Speaker 1: Hey everybody, and welcome to another episode of Alixer Mix.
Speaker 2: This week on our panel we have Sasha Wolf.
Speaker 3: Hello everybody, I'm.
Speaker 1: Charles Maxwood from devchat dot TV. And this week we
Speaker 1: have a special guest, and that's Ivan Rubelog. Did I
Speaker 1: get anywhere close to saying your name right?
Speaker 4: Yes, that's right. Hello, every bunny.
Speaker 1: Do you want to introduce yourself real quick? Let people
Speaker 1: know who you are and why you're famous?
Speaker 4: Yeah? Sure, thanks to work for kind words. So, Hi,
Speaker 4: I'm Ivan. I'm originally I'm from Russia, but for three
Speaker 4: years we with my family live in Humburg, Germany. So
Speaker 4: I'm software back at Elixir, engineer, working in business domains
Speaker 4: real estate and currently in B two B business. Yeah,
Speaker 4: so that's cool.
Speaker 1: And yeah, I was looking at this Domo library that
Speaker 1: you wrote. I have to admit I'm I'm still green
Speaker 1: when it comes to some of this stuff. So and
Speaker 1: follow all of it. But do you want to give
Speaker 1: us kind of the ten thousand view on what domo
Speaker 1: is and what it does?
Speaker 3: Yeah?
Speaker 4: Sure, that started like about a year ago, and I
Speaker 4: usually had the impressions that I miss something within Elixir
Speaker 4: and when I look at the structure and especially type
Speaker 4: definitions of the structure. Of course, there is a dialyzer
Speaker 4: tool that helps us to check validity of the source
Speaker 4: code program same time, it doesn't work at run time,
Speaker 4: and vilizer is quite heavy too, to be honest. So
Speaker 4: and I was missing these things. That's okay. Elixir is
Speaker 4: dynamically type language, and on the other hand, the type definition,
Speaker 4: maybe I can do something about that. And then pandemic
Speaker 4: started and I've got some free time, and I just
Speaker 4: kick it off. Made these libraries that basically validates the
Speaker 4: structure against the type definition and return meaningful errors about
Speaker 4: the fields. Okay, here you define that this field should
Speaker 4: be a string, and you have some number in this
Speaker 4: field in the structure. So these aims to keep the
Speaker 4: state valid because many software errors comes from invalid state
Speaker 4: in the memory, and structures looks like a good place
Speaker 4: for keeping the state. So that was my thought, Okay,
Speaker 4: let's make a tool that validates a state within the structure.
Speaker 3: Was prompted by like a concrete, like if use case
Speaker 3: you had, like for example, at work, you had some
Speaker 3: issues or what was just like an just an academic
Speaker 3: idea at the beginning, and you were curious to try
Speaker 3: somethings out.
Speaker 4: Well, yeah, it was mostly inspired by book The Main
Speaker 4: Dream Design by Eric Evans and more. It was more
Speaker 4: like in academic inspiration, let's say. And yeah, so I've
Speaker 4: got this feelings that there are lots of trials and
Speaker 4: terrors around. So we know that there are other libraries
Speaker 4: like norm that aiming the validation and other attempts to
Speaker 4: make to introduce types in Elixir to get these benefits
Speaker 4: of checking and some time nothing what I meant before
Speaker 4: suit mean well, and because of that I decided, okay,
Speaker 4: maybe I should give it a try and do some
Speaker 4: not full fledged type system or something, because Elixir is
Speaker 4: not such kind of thing but a very little, tiny
Speaker 4: specific library that does on the validation of the structures
Speaker 4: and basically keeping invariants.
Speaker 3: Yeah.
Speaker 4: So, answering your question directly, no, it wasn't inspired by
Speaker 4: any and create task at the office. So it was
Speaker 4: more like general ideas that I would like to have
Speaker 4: such a thing.
Speaker 3: And are you not using it in like any production scenarios?
Speaker 3: I mean you said it comes from an academic background, sure,
Speaker 3: but do you know that like anybody is using it
Speaker 3: in production? Yeah?
Speaker 4: Well sure, so I checked it's with current real projects
Speaker 4: that we have and it works well. So and it's
Speaker 4: kind of at early stage, so of course it's in
Speaker 4: development for about a year, but only a couple of
Speaker 4: days ago I can say okay that final things were
Speaker 4: fixed and now it can be widely adopted.
Speaker 3: Okay, Well, would you see like DOMO being used most
Speaker 3: likely any specific use cases where you say, hey, that's
Speaker 3: like a pretty good fit for DOMO where I saw
Speaker 3: personal success and using it, Like when more people reach
Speaker 3: for DOMO compared to something like for example, norm as
Speaker 3: you mentioned earlier, because just to give them context for
Speaker 3: listeners like NORMS, this data validation library where you specify
Speaker 3: schemas like in code, like it doesn't use the type specs,
Speaker 3: but like you can basically use functions and stuff from
Speaker 3: norm to say okay, the data should conform to this
Speaker 3: schema and mean demo that uses the typespecs. So when
Speaker 3: would you say, is like it's a scenario where somebody
Speaker 3: would like to use DOMO any specific.
Speaker 4: Yeah, sure, that's an amazing question. Thanks a lot. So
Speaker 4: there is another component in DOMO. It's that I haven't
Speaker 4: mentioned before. So it it's not only validating the data
Speaker 4: against the type definition TYPESPEC, but it also has these
Speaker 4: pre condition functions attached to the type, so meaning that
Speaker 4: for example, if you have the type definition for a
Speaker 4: field of your structure, you can also add a pre
Speaker 4: condition function to this type that the normal library would
Speaker 4: call and if this function returns okay, then it would
Speaker 4: consider that the value is not only of that type,
Speaker 4: but it's also of a for example, right format that
Speaker 4: you expect. So and saying that I can point out
Speaker 4: to the concrete scenario. So for example, if you know
Speaker 4: that you have an identifier in your system for your order.
Speaker 4: For example, let's say you build e commerce system right
Speaker 4: some websites the e commerce website, and you know that
Speaker 4: in your system this identifiers have specific format for example
Speaker 4: AA letter in the beginning and some numbers afterwards. You
Speaker 4: can just define the type okay my ideas of string
Speaker 4: type and add a precondition function to this, so saying
Speaker 4: that the value should begins with A and then using
Speaker 4: this type across any structures in your application. You would
Speaker 4: have these automatically validated whenever the structure is created with
Speaker 4: a construction function added by dormal library, and the DOMO
Speaker 4: will guarantee you that you will have valid values for
Speaker 4: this id type across your application and that in this
Speaker 4: regards the state would be valid. So yeah, this is
Speaker 4: one of scenarios, and it can go even more. Like
Speaker 4: we can go further. We can define with normal library,
Speaker 4: it's possible to define the precondition for the struct type.
Speaker 4: You know, when you write this type T for your structure,
Speaker 4: and you can say, okay, for this type T, the
Speaker 4: miprecondition function will be this one you name it. And
Speaker 4: let's say you would like to have some relations check
Speaker 4: between fields of this structure, saying that if this is
Speaker 4: the order structure for e commerce website, that you have
Speaker 4: some allowed amount or of the order in terms of money,
Speaker 4: and you would like to have the sum of all
Speaker 4: line items in this order to be not higher than
Speaker 4: this given amount. So this precondition function attached to the
Speaker 4: type of the structure can validate that and give some
Speaker 4: meaningful error bag that okay, you should have the summary
Speaker 4: amount less than a lot. And that's as a scenario.
Speaker 4: When DOMO gives you a consistency of your structure or
Speaker 4: more higher level let's say so so it allows to
Speaker 4: follow business rules of the system implementing. So this is
Speaker 4: the second scenario.
Speaker 3: So that's I guess that could make sense to use Thermo.
Speaker 3: For example, at the edges of my system. When I
Speaker 3: say I have a Phoenix API, for example, getting some
Speaker 3: jacon in and I want to verify that the user
Speaker 3: actually like the information the user gave me, conforms to
Speaker 3: a certain data schema to like to the to the
Speaker 3: requests objects I expect, and that I then can use
Speaker 3: that to forward it to the rest of my application,
Speaker 3: being sure that, Yeah, as you said, preconditions are met.
Speaker 3: Is that right? Is that like a scenario where you
Speaker 3: would say DOMO is applicable.
Speaker 4: Yes, is one of scenarios where DOMO can can play
Speaker 4: and it's like equivalent to what can be implemented with norm. Right,
Speaker 4: So you can define the schema and validate the adjacent
Speaker 4: on the let's say boundary of your application, and then
Speaker 4: be sure that the data that you operate on is valid.
Speaker 4: And yeah, there's definitely one of the possible scenarios. On
Speaker 4: the other hand, there are other scenarios. It's when you
Speaker 4: work with a pure core having only pure functions and
Speaker 4: structures in it, and you would like to follow to
Speaker 4: make it follow some business rules that should be executed
Speaker 4: in your system. So, for example, it's from the domain
Speaker 4: domain driven design framework. Right, So when you have a
Speaker 4: set of business rules, you can define them with normal
Speaker 4: precondition functions page to the type and have this business
Speaker 4: rule fulfilled everywhere you use these values of these type
Speaker 4: in structures. So, for example, as I mentioned this before
Speaker 4: with order, right, so you can have the order structure
Speaker 4: in your core and have these values dependency between items
Speaker 4: of this order and allowed amount the same invariants, same
Speaker 4: kind of invariants may be for other structures that participate
Speaker 4: in the business logic of your application.
Speaker 2: Right.
Speaker 4: And instead of the okay, this can be compared that
Speaker 4: you can say, hey, I can write this in any module,
Speaker 4: write this verification that my structure have a valid number
Speaker 4: of items and that there's some is not exceeding the
Speaker 4: allowed amount for this order. And the interesting part here
Speaker 4: is that if you do this with DOMO, by using
Speaker 4: this precondition function attached to the type, you can have
Speaker 4: this validation not only in this structure but in any
Speaker 4: other kind of structures using this type. So it goes
Speaker 4: like automatically in these places and you don't need to
Speaker 4: think twice about if I forgot any validations or you know,
Speaker 4: any parts of checking my structures in regards to business
Speaker 4: logic of the application, and it even can go further
Speaker 4: across the application boundaries. For example, if you have several
Speaker 4: micro services that is very common nowadays, you may have
Speaker 4: hundreds of them, and if, for example, you share these
Speaker 4: type definition and pre condition functions in some model files
Speaker 4: across these several applications, due to the normal library, you
Speaker 4: can be sure that this would be checked and full filled.
Speaker 4: These either these validations for boundary situation or for business
Speaker 4: logic in the core.
Speaker 3: When you say sharing the model fied, I assume like
Speaker 3: in the sense of like a private tax package or
Speaker 3: what exactly are you thinking of?
Speaker 4: Oh, yeah, sure, it can be a hex package. On
Speaker 4: the other hand, it's usually starts like a little you
Speaker 4: just have several modules like share models that you can
Speaker 4: check out in various repels. So the techniques are various
Speaker 4: for that. So for example, you can have shared Git
Speaker 4: repository with this model and you can edit as submodules
Speaker 4: to other Git repositors or you know, just check it.
Speaker 3: But basically you lose like some kind of mechanism to
Speaker 3: like get the code into your micro services, be through
Speaker 3: x package or like through okay, yeah, that's right, okay,
Speaker 3: And I was just thinking because there are also solutions
Speaker 3: such as protobaf or others I can think of right now,
Speaker 3: which like also follow this idea of having like a
Speaker 3: model definition which then can be used to generate some code.
Speaker 3: But that's like more agnostic, not really specific to to
Speaker 3: to elix here.
Speaker 4: Yeah, it's very interesting. Yes, the true protobuffs are very
Speaker 4: good to have the intercommunication be validated time. It is
Speaker 4: impossible to put function protobize definition.
Speaker 3: Which with some might argue is a good thing.
Speaker 4: At some scenario.
Speaker 3: Yes.
Speaker 4: On the other hand, with dormo, you can do that
Speaker 4: and do more precise validation like Okay, if that if
Speaker 4: these conditions that mad, then these values should be as expected.
Speaker 4: On the other hand, if I have another value in
Speaker 4: my structure set to this value, then this should be
Speaker 4: should be another duly expected. So you can imagine that
Speaker 4: it can be quite complex interdependencies between fields of even
Speaker 4: one structure, not saying about some nested structures that usually
Speaker 4: now can be seen in modern applications.
Speaker 3: Okay, to get back to something you said earlier, So
Speaker 3: you said that you can reuse like type definitions and
Speaker 3: preconditions that attached with that type. So if for example,
Speaker 3: I like to get back into an example, you said, like, yeah,
Speaker 3: I've a certain identifier, like an order identifier. I could
Speaker 3: just specify this type in some module, attach some preconditions
Speaker 3: to it, and then use it across my application and
Speaker 3: wherever I use DOMO. Basically, I assume then that would
Speaker 3: basically reuse these preconditions attached to my order identifier type.
Speaker 3: Is that right? Did I get that right? Yeah? That's right?
Speaker 3: To Okay, it looks like that. Okay, that's nice. I
Speaker 3: guess DOMO boils a bit down to like saying to
Speaker 3: avoid a bit of a petition, right, because for example,
Speaker 3: if you look at EMO, you acto schemas like like
Speaker 3: for at least from my experience, you tend to have
Speaker 3: this scenario where you say, okay, this is like my
Speaker 3: schema and these my fields. But then it's also helpful
Speaker 3: to to have type definition on tops so that you
Speaker 3: then just for documentation purposes, right ba, I say okay,
Speaker 3: this is like the type of this, and these are
Speaker 3: like the sphere as an integer and this field as
Speaker 3: a string. And then you also have on the bottom,
Speaker 3: like maybe some some ECTO change set validations where they say, okay,
Speaker 3: I use the idea needs to start with an AID
Speaker 3: or my other ID needs to start with an ASOL.
Speaker 3: So I guess DOMO goes a bit in that direction
Speaker 3: where they say, okay, I don't want to maintain like
Speaker 3: multiple definitions of the same information basically.
Speaker 4: Right true true, that's it. And moreover, Domo has support
Speaker 4: of ACTO. So if you have these schema defined, and
Speaker 4: you have these type defined into the schema, you can
Speaker 4: call the change set in the Dormo library and the
Speaker 4: function that's named validate type, and DOMO will automatically validate
Speaker 4: changes in the Acto change set for you according to
Speaker 4: the type you defined. So this is already supported and
Speaker 4: quite convenient.
Speaker 3: That's nice. I assume that, like to actually reuse a
Speaker 3: type for example, such as the order ID, I have
Speaker 3: to like use Domo in that place, right, I can't
Speaker 3: just use any remote type. I mean that, like, how
Speaker 3: does that work? When you say okay, it's like a
Speaker 3: string T, then like we probably have some code written
Speaker 3: which says, okay, if it's a string, then doing this
Speaker 3: and that check. But if I just say I have
Speaker 3: like this module over there, which like doesn't use domo
Speaker 3: at all, but it specifies my type, I don't know which,
Speaker 3: just say like it's a map with like certain certain keys,
Speaker 3: and the keys need to be of a certain value.
Speaker 3: Is that like something DOMO can can handle them? Or
Speaker 3: how exactly can I can I imagine this to work?
Speaker 4: Yeah?
Speaker 3: Like where are the boundaries? Basically like why does it break?
Speaker 4: Okay, so three key questions, so where it's break? Well,
Speaker 4: I can say that that's a very good example. And
Speaker 4: it was a quite long year. But then here so
Speaker 4: I had the time to resolve this and it was
Speaker 4: successfully completed. So how DOMA works. If you have remote
Speaker 4: type is within some structure or other module that's not
Speaker 4: using DOMA at all, library automatically take this type into
Speaker 4: validation because more has is shipped with compiler. So when
Speaker 4: you add library to the project, it has two pass compilation.
Speaker 4: First pass is by alixer and second past of the
Speaker 4: compilation is by DOMA compiler that just do the job
Speaker 4: by getting all the type definitions from remote modules and
Speaker 4: putting them in place where the validation should be performed.
Speaker 4: So and moreover, if you change remote type, for example,
Speaker 4: you compile your project and you change one of the
Speaker 4: keys in this map you mentioned in the remote module,
Speaker 4: I mean type definition of the key and you can
Speaker 4: again the DOMO will notice that and recompile the module
Speaker 4: where you use is remote map definition.
Speaker 3: So automatically as signs that compiled time dependency to the remote.
Speaker 4: Model, it tracks dependence in between types in your application
Speaker 4: and recompiles appropriately.
Speaker 3: I assume that this can have a hit on compilation
Speaker 3: times because I mean, if you look at what the
Speaker 3: Alexi core team and the Phoenix core team has been
Speaker 3: doing in the past few months, they very much try
Speaker 3: to reduce this kind of like compile time compilation compilation
Speaker 3: links between modules which can SUI times. So I assume
Speaker 3: that at least like a trade off of using domo
Speaker 3: in that fashion is probably that it might impact your
Speaker 3: compiled times.
Speaker 4: Right, yeah, sure when you comes at price, so definitely
Speaker 4: it would increase compilation times. In synthetic tests it was
Speaker 4: about maybe twenty percent of increase compilation time. And of
Speaker 4: course during the run time it's additional sipute cycles that
Speaker 4: are spent on the validation of the data you've got.
Speaker 3: I mean, that's your idea, right.
Speaker 4: That's true. Yeah. At the same time, I can say
Speaker 4: that there is a heavy optimization implemented yet for the
Speaker 4: dependency checks it just works. I can say that during
Speaker 4: the compilation time, Dormo relies to the pattern matching a lot,
Speaker 4: and at least for the part when you have this
Speaker 4: validation at run time of your values. It's working on
Speaker 4: already optimized code optimized by Elixir and a lung compilers.
Speaker 4: Because of pattern matches that automatically generated by Domo, you
Speaker 4: can have quite a good performance. Yeah. If you you know,
Speaker 4: when we talk about code generation, that definitely happens here
Speaker 4: with the dormal library. It's always a question mark, Okay,
Speaker 4: what this library generates and how it works in my application,
Speaker 4: So you can ask this question at some point in time.
Speaker 4: And interesting enough that Domo rights the source code of
Speaker 4: this validation into the build folder. So if you add
Speaker 4: the type definition to your structure and say use dormo there,
Speaker 4: then in underscore build folder you would have a Domo
Speaker 4: generated called subfolder where you can see the old source
Speaker 4: code that is used to do these run time validations.
Speaker 4: So it's yeah, then used as a compilation source or
Speaker 4: is it just like for the user's benefit, Well, it's
Speaker 4: used as compilation source. The same time, if you change it,
Speaker 4: it wouldn't affect anything because it would be overwritten during
Speaker 4: the next company, so you can read it, but you
Speaker 4: can't affect it much. This add this additional confidence about
Speaker 4: what's going on when you call this function validate type
Speaker 4: on your structure or constructor function or if you do
Speaker 4: a reidate type in ECTO schema.
Speaker 3: Okay, I guess the question which for some people might
Speaker 3: have like how readable is this code because that code
Speaker 3: generation tends to sometimes produce code which is like a
Speaker 3: bit not so nice on the ice to say to
Speaker 3: phrase it like that.
Speaker 4: Yeah, true, there is a four matter run during the
Speaker 4: generation of this code, and it's quite readable and quite simple.
Speaker 4: So worse, the more fields in your structure you have,
Speaker 4: the longer would be the output and the source code file.
Speaker 3: Same time.
Speaker 4: It's quite straightforward there too, same in functions there that
Speaker 4: you just can read and say, okay, here is the validation,
Speaker 4: here is the pattern matching. So it's quite simple.
Speaker 3: So that means that like domo generates like an additional
Speaker 3: module or what which is then used FORUL for type checking.
Speaker 4: Yeah, okay, okay, what happens when you use domo at
Speaker 4: minimum level? You can just add use domo into your
Speaker 4: struct module, right, and then dormo generates a submodule that
Speaker 4: is called type ensure. So let's say your module named
Speaker 4: car and after DOMA works, you have also in addition
Speaker 4: car dot type insure and inside of this type ensure
Speaker 4: all validation happened and how it works in regards to
Speaker 4: your original car structure. DOMO adds functions to the car
Speaker 4: structure as well. It's a new function that is constructor
Speaker 4: function for the structure and validate type function that is
Speaker 4: for validation of existing instance. So there are also a
Speaker 4: couple of other functions like typed fields and required fields
Speaker 4: that returns the list of the fields of your structure
Speaker 4: that has not new types. Let's say, so that's useful
Speaker 4: in actual change that. So the first two new and
Speaker 4: validate type functions they just facate for type insure module.
Speaker 4: So when you call car dot new and keywould leads
Speaker 4: to these fields and values for these fields, the new
Speaker 4: function bypasses that after some checks to type insure module
Speaker 4: type insure module, do pattern matches validate the all types
Speaker 4: of the values is as expected, then run pre condition
Speaker 4: functions associated with these types, checking okay the format of
Speaker 4: these values is good, all invariants have full field, and
Speaker 4: then returns back to the call site so and it
Speaker 4: returns the constructor the structure basically, So that's how you
Speaker 4: can be sure that at the time of the call,
Speaker 4: when you get this structure back, it's valid structure according
Speaker 4: to the type and pre conditions defined. Then if you
Speaker 4: modify the structure, for example, alter field of the car,
Speaker 4: then you can call again the validate type function with
Speaker 4: this modified instance, and the validate type function would do
Speaker 4: the same trip to the type insurance back, giving you
Speaker 4: the answer is it still okay structure matching the type
Speaker 4: and preconditions or no, you have this field incorrect because
Speaker 4: of this and that. So that's how it works basically.
Speaker 3: Okay, And what happened if I, like, have my car
Speaker 3: struck and I have said use domo and then instead
Speaker 3: of that, I just define a module which it's called
Speaker 3: type insure. What would happened then, like, because then I
Speaker 3: have a name class.
Speaker 4: Right, yeah, sure, the behavior would be the same if
Speaker 4: if you define type insure twice. So you can do
Speaker 4: this by hand and there are no any you know,
Speaker 4: hidden things behind that. It's just simply a generation of
Speaker 4: the Elixir source code and compiling it with the LEIKXIR
Speaker 4: two times.
Speaker 3: So okay, I guess, like on one thing DOMO could
Speaker 3: do there is like generating like it in a different
Speaker 3: name space, right, like could for example generated in domo
Speaker 3: dot type insure dot name of a module, because then,
Speaker 3: I mean people could then still define a module which
Speaker 3: is called that way. But if they basically messed with
Speaker 3: like another uplic another libraries name space, it's like they
Speaker 3: all fault.
Speaker 4: Right, Yeah, well this nice idea. Let's see what can
Speaker 4: be done in this regard. And there is another scenario
Speaker 4: how to start using domo. You may not even use
Speaker 4: all the functions that DOMA adds to your structure. For example,
Speaker 4: let's say we have the car, and if you even
Speaker 4: write use domo inside the car, you already get some benefits.
Speaker 4: What I mean, during the compilation time, it would check
Speaker 4: the default values of your car structure, these values that
Speaker 4: you usually define with death struck, and during the compilation time,
Speaker 4: DOMO already would validate if the default value specified conforms
Speaker 4: to the type and pre conditions, and if it's not,
Speaker 4: it would say compile error. So you have these values
Speaker 4: not matching, and yeah, that's that's interesting. Even more, if
Speaker 4: for example, you have some connected structure like one structure
Speaker 4: nested in another and you let's say car, and what
Speaker 4: can be inside of the car. Let's say some some seat,
Speaker 4: yeah seat, and you know these seats with leather or
Speaker 4: other materials some, So we can imagine that for the
Speaker 4: seat it can be a separate structure defining all the
Speaker 4: parameters of the sea.
Speaker 3: I want to cut a blue seed and orange seed
Speaker 3: and two yellow seeds. Yeah.
Speaker 4: For example, So if you give the default value of
Speaker 4: seats to the car saying okay, I would like orange
Speaker 4: seat and blue and put it into the depths truct
Speaker 4: of the car. And if you use a dorma function
Speaker 4: like seat dot new right, so it would check during
Speaker 4: the compilation time the validity of this default value. And if,
Speaker 4: for example, you put into the sea dot new some
Speaker 4: invalid value by mistake instead of orange stream orange atom,
Speaker 4: and it wouldn't manage the seed type. DOMO will also
Speaker 4: give you back the compilation error saying okay. So you're
Speaker 4: constructing the thing that is not mentioned the type as
Speaker 4: a default value. And this works even in function calls.
Speaker 4: So if you pass this default value with domo dot
Speaker 4: new to the function heater definition, it will also be
Speaker 4: checked during the compile time. So how DOMO does that.
Speaker 4: It basically tracks the calls to dot new that is
Speaker 4: generated by the DOMA obviously, and then during the compilation
Speaker 4: pass it just make validation of these fields.
Speaker 3: Okay, that some timeful. I mean I've not a had
Speaker 3: a scenario. Well default values were as complex where I said, okay,
Speaker 3: I want to verify about it. Don't make the mistake here.
Speaker 3: But if you get for free, that's what's nice, I guess.
Speaker 4: Yeah, And you know the software is constantly evolving, so
Speaker 4: and it may happen then for example, at some point
Speaker 4: in time you change the type of your structure and
Speaker 4: all humans, so you can forget to change the default value, right,
Speaker 4: and that potentially could lead to mistakes, and DORMO play
Speaker 4: safe here, so it gives you appropriate feedback very early
Speaker 4: at compile time.
Speaker 3: Charles, do you have any questions I've been talking.
Speaker 1: About it's about to chime in. I'm more curious about
Speaker 1: like testing and performance. Yeah, how does this affect any
Speaker 1: of that?
Speaker 4: Well, did some synthetic tests, so you can find the
Speaker 4: detailed results in the read me to the library. What
Speaker 4: I've observed it's one point twenty six times slower than
Speaker 4: without library at run time. So it looks like around
Speaker 4: thirty PAF and slower work. Same time you get valid
Speaker 4: state of your application price.
Speaker 3: I guess it makes sense when you're like, I wouldn't
Speaker 3: probably use it in a scenario where I will already
Speaker 3: know that certain data is valid, because then I mean,
Speaker 3: way check in the first place. Right, But if you
Speaker 3: are in a scenario they say, okay, I I'm not
Speaker 3: uncertain that the data which I'm getting here is conforming
Speaker 3: to what I expected to be, then sure why not?
Speaker 3: I mean you can even write now validation at all,
Speaker 3: but which works if the users friendly enough to give
Speaker 3: you a right data. If they don't, then it's going
Speaker 3: to go boom. Right, yeah, yes, and.
Speaker 4: It's not only user sometimes the business logic can be
Speaker 4: quite sophisticated. And if of course we have you test
Speaker 4: and cover all not happy but unhappy path as well.
Speaker 4: And same time, it can be that you can forget
Speaker 4: are one or another combination of all parameters and adding
Speaker 4: these validated against the type can add additional let's say,
Speaker 4: it can give you additional insurance that you will have
Speaker 4: valid state of your application.
Speaker 3: One thing. As Charles asked about testing, for example, I say, like,
Speaker 3: I let's go back to that example from earlier with
Speaker 3: the idea it's a swing, it's supposed to start with
Speaker 3: a letter A, Like I mean, how would I then
Speaker 3: go roup fighting a test for that? Like? Because I mean,
Speaker 3: as you mentioned earlier, this is like a reusable type, right,
Speaker 3: like a type I can use the multiple places I
Speaker 3: can see, like how I would use reuse like the
Speaker 3: destruct how we test the struct definitions of dormal because
Speaker 3: then I can just call dot new right if it
Speaker 3: raises an error, it turns an error toroogle, then then
Speaker 3: it can failed successful. Is that like an option to say, Okay,
Speaker 3: I have this type over here, and now I would
Speaker 3: write to write some tests because I also have some
Speaker 3: preconditions attached to that, and I want to make sure
Speaker 3: that I didn't make a mistake while writing these preconditions, right, yeah,
Speaker 3: so like some option to do that? Yeah?
Speaker 4: So I remember one talk in regards to that from
Speaker 4: camp back about what is right size of unit that
Speaker 4: is under the test. And I can say that, for example,
Speaker 4: in the test, you can define as trugged for test
Speaker 4: purposes that uses the type definition and be sure that
Speaker 4: these preconditions associated with this type working properly by calling
Speaker 4: these you know, test struck Nott new Okay, so this
Speaker 4: would be what what does it? It means that you
Speaker 4: would ast the interface and not internal implementation. Right, So
Speaker 4: the publicly available interface provided by domo is this new
Speaker 4: function and validate type function.
Speaker 3: Okay, but there's no API where I can say, hey, Domo,
Speaker 3: I'd like to use this type over there, and please
Speaker 3: check it, like check piece values I give you, and
Speaker 3: now tell me if that conforms, like basically probably similar
Speaker 3: to what norm does. Right, there's like no altitude that
Speaker 3: I guess they always have to go through, like the
Speaker 3: motions of like specifying a struct and then I mean
Speaker 3: either using a struct I already find or specifying one
Speaker 3: if I want to, for example, test the remote type.
Speaker 4: Yeah, well technically you can, so you can call type
Speaker 4: ensure modules that Domo generates for these kind of things.
Speaker 4: So there is a public function that is called. And
Speaker 4: on the other hand, it's a question where your interface is.
Speaker 3: So if yeah, I guess we're now entering some a
Speaker 3: certain level of philosophical conversation like what is a unit test?
Speaker 3: What is the purpose of life? Yeah?
Speaker 4: Well, it's possible to do the unit testing with either
Speaker 4: new function or with calling typing. Sure, model directly.
Speaker 3: Yeah, I can see why I call it. Type into
Speaker 3: a model directly is something which probably should not be encouraged.
Speaker 3: From what you told me, it feels like it's more
Speaker 3: of a private API think, so yeah, yeah, better not
Speaker 3: go there, I guess.
Speaker 4: So it's a quite simple thing. On the other hand,
Speaker 4: if you would like to express business rooms, it's another
Speaker 4: possible way to do that. So for me, it's also
Speaker 4: always a question to keep every scene in place, especially
Speaker 4: when some parts of the business rules are shared across
Speaker 4: various parts of the application or even across several micro services.
Speaker 3: So abe bit of a hard question now when it's
Speaker 3: like a scenario where you would not use DOMO, So
Speaker 3: it fe like, say, okay, this is just not the
Speaker 3: right tool for job when people may be reach for
Speaker 3: something else or write custom code.
Speaker 4: Yeah, so I think every tool should be used for
Speaker 4: appropriate problem. And if it's high performances application like maybe cryptocurrency,
Speaker 4: where you have heavy calculations and every microsecond is on count,
Speaker 4: then maybe it's not right a problem to use DOMO for.
Speaker 4: On the other hand, if you have a business application
Speaker 4: like e commerce, website or lots of business logic that
Speaker 4: should work correctly and you can spend some time to
Speaker 4: get the answer to provide the user, then dom could
Speaker 4: be a good choice.
Speaker 3: Okay, So what is any anything you see on the
Speaker 3: horizon for for like DOMO, any next steps you'd like
Speaker 3: to take, anything which is missing and you'd like to
Speaker 3: tackle what comes next.
Speaker 4: Yeah, So I'm looking forward for some large system to
Speaker 4: give this library a try, because all applications I work
Speaker 4: with of the average size, so it's kind of web
Speaker 4: shops or such kind of websites, and I'm really interested
Speaker 4: to see how it would work on one hundred micro
Speaker 4: services setups, so where you have lots of components that
Speaker 4: should be play that should play nice together too, and
Speaker 4: very welcome for any such kind of collaborations to run
Speaker 4: a test on such larger than average systems. Other plans
Speaker 4: are to add additional type checks to dormo, Like it
Speaker 4: checks all the standard types, but that are defined in
Speaker 4: the Elixir documentation. At the same time, it doesn't check
Speaker 4: types that referencing itself yet, so I mean crimary trees,
Speaker 4: recursive types, right, So I'd like to add support for that.
Speaker 4: It's not such usual scenario in business applications, but I
Speaker 4: intend to support this.
Speaker 3: I've done this when I wanted to have a representation
Speaker 3: of like adjacent of like an arbitrary adjacent because then
Speaker 3: you can say, okay, like adjacent value can be like
Speaker 3: a list, that can be an integer, that can be
Speaker 3: a stream, but it can also gain be an object
Speaker 3: with in turn users values which then by definition, so yeah,
Speaker 3: and I can see why why that we useful? Yeah,
Speaker 3: and for many for many such kinds of definitions. DOMO
Speaker 3: is working. Now if you say, okay, this is part
Speaker 3: of Jason, and inside of this part of Jason, it
Speaker 3: would be the same part of Jason, so you know,
Speaker 3: recursively and DOMO wouldn't work.
Speaker 4: So yeah, what happens when you do that? It doesn't
Speaker 4: raise an error? Yeah, yeah, it rises an error that
Speaker 4: is not supported yet. Okay, so no binary trees for now, sorry,
Speaker 4: so with leaves and branches, but it's it's a question
Speaker 4: of some further work on that.
Speaker 3: It's also mean it might just then explode the runtime complexity, right,
Speaker 3: because if you have a very large binarit tree, yes,
Speaker 3: but sure, that's that's always an issue.
Speaker 4: Sure, And for example, if you have very long list
Speaker 4: that can be in your structure, it's also can be
Speaker 4: an issue. So This is natural limitation for DOMO because
Speaker 4: it validates each list tallemands for conformance to the type,
Speaker 4: so it should be considered as well.
Speaker 3: It's like some some smart instead of DOMO, for example,
Speaker 3: when you say I've got a list of any, because
Speaker 3: then there has no reason to check each element of
Speaker 3: a list if you say it can be anything. Is
Speaker 3: something like that DOMO or yeah.
Speaker 4: Well in regards to Liz, no, Well, it's so there
Speaker 4: are such kind of optimizations. If you say that some
Speaker 4: field is any, for example, it wouldn't be checked, so
Speaker 4: it would be a shortcut like okay, SVLID and lists
Speaker 4: should be supported as well with any type inside. Yeah,
Speaker 4: so I intend to look up for other such kind
Speaker 4: of optimitysations too.
Speaker 3: But I guess that goes into what you said earlier,
Speaker 3: like to see it use the larger scale, and then
Speaker 3: these kinds of issues and optimization things are going to
Speaker 3: crop up naturally because you push the library to its limits. Yeah,
Speaker 3: that's true. Okay, child to you if anything left because
Speaker 3: I'm trying out.
Speaker 1: I think you pretty much covered it. Yeah, a couple
Speaker 1: of the questions I was going to ask and when
Speaker 1: you cover them.
Speaker 4: So so it may seems a bit weird from the
Speaker 4: first point of view, right, So attaching pre conditions to
Speaker 4: types and sharing here in there, but all the other
Speaker 4: And it's another view on the same problem of having
Speaker 4: valid state and fulfiling invariants in your models.
Speaker 2: So all right, well, I'm gonna push your Swart picks.
Speaker 1: You have a conversation about stuff that we like before
Speaker 1: we do that, though, yvon if people want to follow
Speaker 1: you on social media connect how do they do that?
Speaker 4: You can follow me on githab My username is Ivan
Speaker 4: rublev and you can follow me on Twitter. User name
Speaker 4: is Levy Brown. Maybe I should write it somewhere folks,
Speaker 4: and you can add it to the description of the podcast.
Speaker 3: Yeah, yeah, we'll do that.
Speaker 1: Yeah, absolutely, yeah, I just put it in the chat.
Speaker 1: Well all right, well let's go ahead and do the picks, Sasha,
Speaker 1: Do you have some picks for us?
Speaker 3: Yes, And it's actually related to what we talked about,
Speaker 3: because I mean even mentioned that he A lot of
Speaker 3: these ideas are based on the main driven design by
Speaker 3: Evan True. I forgot his last name, Evan Evans, Eric Evans, Yeah, Eric,
Speaker 3: that was And there's also another book not from Eric Evans,
Speaker 3: but from from Scott Blushing and that's called the main
Speaker 3: Modeling Made Functional. Yeah, that's an amazing book. Yeah, it's
Speaker 3: very nice. Arguably it's probably the best book I've read
Speaker 3: it on the winderin design. It's also relatively short, especially
Speaker 3: compared to Eric Evans book, which is not short.
Speaker 2: And we should see if we get Eric on we
Speaker 2: had him on Ruby Road for a long time ago.
Speaker 3: Nice. Wow, yeah, that would be pretty cool, to be honest,
Speaker 3: maybe you could also get Scott Blushing. Of all, he's
Speaker 3: not an elixir of death. But yeah, just to get
Speaker 3: back to the pic. So the book is called domin
Speaker 3: Modeling Made Functional, and it's it's actually a nice introduction
Speaker 3: into both like in the domainder design and also functional programming.
Speaker 3: He's using f sharp there, and he's like talking a
Speaker 3: lot about how to use the type system to basically
Speaker 3: help you restricting and like restricting things to what they
Speaker 3: should be to like basically avoid in that state already
Speaker 3: on the type system level, which plays a bit in
Speaker 3: what we talked about today, because I mean demo helps
Speaker 3: with like using the type definitions and forcing those. And yeah,
Speaker 3: it's like a really really nice book. It's well written,
Speaker 3: it's it didn't really bore me to death text books
Speaker 3: which I just stopped reading at a certain point. And
Speaker 3: if anybody is interested in my demander of design is
Speaker 3: into some function programming and types, then I can really
Speaker 3: wold hotly recommend.
Speaker 2: This book awesome. I'm going to throw out a couple
Speaker 2: of picks.
Speaker 1: The book I'm reading right now is I'm still in
Speaker 1: the middle of a Rhythm of War by Brandon Sanderson.
Speaker 1: Really enjoying that picture book fantasy book. I have another pick,
Speaker 1: but I'm kind of saving it for last. There was
Speaker 1: something else we're going to pick, and I can't remember.
Speaker 1: I guess I'll just go to this last one because
Speaker 1: I'm excited about it. So I've been doing a whole
Speaker 1: bunch of work lately around the idea of top end devs.
Speaker 1: You all, if you listen to dev chat dot tv
Speaker 1: and are you subscribe to the mailing list and stuff
Speaker 1: like that, you're going to start seeing a whole lot
Speaker 1: more stuff branded with top end devs instead of dev
Speaker 1: chat dot tv, because we're kind of moving everything over
Speaker 1: to that, mainly because I want to communicate to people that, hey, look,
Speaker 1: if you put in some effort. We talked a lot
Speaker 1: about this last week with Audi. Audi and I talked
Speaker 1: about this, but you can take your career wherever you
Speaker 1: want it, and I am committed to that idea, and
Speaker 1: so I want to because devchat dot tv doesn't dev
Speaker 1: chat doesn't, it doesn't really mean anything.
Speaker 3: You know.
Speaker 1: The idea was is, Hey, we talked about dev right,
Speaker 1: but this is kind of more of a higher idea
Speaker 1: and aspirational idea.
Speaker 2: One of the things that I'm doing.
Speaker 1: And I can't remember if I brought this up last time,
Speaker 1: and so I'm going to just throw it out here
Speaker 1: so you all can show up if you need it.
Speaker 1: But one of the things that I've really picked up
Speaker 1: lately is is the coaching.
Speaker 2: Right.
Speaker 1: I've just loved helping people figure out, Hey, what do
Speaker 1: I do next, What do we need to learn, what
Speaker 1: do I need to work on to grow into what
Speaker 1: I want what I want to be. And as I've
Speaker 1: been doing that, it just it just fires me up.
Speaker 1: I mean, I had a conversation with somebody on Friday,
Speaker 1: and you know, he's trying to figure out where to
Speaker 1: go next, right, and we talked about all kinds of stuff,
Speaker 1: and at the end of the call, you know it's like, hey,
Speaker 1: you know, go do this stuff. Let's talk in a
Speaker 1: couple of weeks, right, and holy cow is just seeing
Speaker 1: the potential of what he can do and the power
Speaker 1: behind what he can accomplish.
Speaker 2: It just gets me going, right.
Speaker 1: And there are some things that everybody can do, and
Speaker 1: then there are some things that, as we get into
Speaker 1: the particulars of your situation, you can do, right. And
Speaker 1: that's kind of the difference I guess between like the
Speaker 1: course and coaching, or training and coaching. And so what
Speaker 1: I'm doing is I'm kind of splitting the difference between both.
Speaker 1: And so I'm using Zoom's webinar system. But it's not
Speaker 1: a webinar, right. Webinar is I give you half the
Speaker 1: information that's useful, leave you hanging, and then give you
Speaker 1: a sales pitch. I'm not doing any of that crap. Okay,
Speaker 1: that's I'm not doing a webinar. But I am going
Speaker 1: to do training. So I'm gonna do like ten or
Speaker 1: fifteen minutes of training and then for then the rest
Speaker 1: of the hour hour and a half that I have,
Speaker 1: I'm planning on doing this Wednesdays around noon mountain time.
Speaker 1: I'm just gonna take questions, okay, and not take questions
Speaker 1: in the sense of you know, what what what? How
Speaker 1: do how do strings work in elixir?
Speaker 3: You?
Speaker 1: No, it's not that kind of stuff, right if I
Speaker 1: if you have that question and I can answer it,
Speaker 1: you can ask it, right, and I'll try and answer it.
Speaker 2: But what I'm really looking to dive into is, hey,
Speaker 2: I've got this far.
Speaker 1: In my career, or hey, I'm trying to figure this
Speaker 1: stuff out, or hey, i've got this situation at work,
Speaker 1: or I'm trying to find a job and I'm not
Speaker 1: getting interviews, or things are going really well, but I
Speaker 1: feel like I could do more.
Speaker 2: What should I be doing next? And then we'll actually
Speaker 2: talk through your situation, right, talk through where you're at,
Speaker 2: and figure out where things should go.
Speaker 3: Right.
Speaker 2: So it's going to be almost more coaching than Q
Speaker 2: and A. But we'll just do it until we run
Speaker 2: out of time, run out of questions, whatever, right, And
Speaker 2: I really just want to help people out, So it's
Speaker 2: totally free, right, no commitment, no whatever. I'm not going
Speaker 2: to do a sales pitch right and try and sell
Speaker 2: you on coaching, nothing like that.
Speaker 3: Right.
Speaker 1: I am offering paid coaching, but I'm not gonna try
Speaker 1: and sell anybody on that on these calls. Right, it's
Speaker 1: completely free, completely you know whatever. So all you have
Speaker 1: to do is just go to dev chat dot TV
Speaker 1: slash level up. I think you have to put your
Speaker 1: email address in so that the Zoom system can send
Speaker 1: you the link to the webinar software and then from
Speaker 1: there you're in, right, And yeah, just show up, jump
Speaker 1: on the call, and we'll answer as many questions as
Speaker 1: you want. And if we don't get to you, then
Speaker 1: show up the next week, right, because we're going to
Speaker 1: do it every week. And yeah, I'm really looking forward
Speaker 1: to helping some folks out. Like I said, this is
Speaker 1: the stuff that really just makes me feel like I'm
Speaker 1: making a difference myself, right, and then yeah, you know,
Speaker 1: if it turns into a kind of a deeper relationship
Speaker 1: and we wind up doing coaching, than great. And if
Speaker 1: I kind of get you there in twenty minutes, then great.
Speaker 1: Then you got there in twenty minutes, and you can
Speaker 1: come back when you get stuck again or you need
Speaker 1: more guidance. All right, So that's kind of what I'm
Speaker 1: looking at, and I'm really hoping that I can help
Speaker 1: some fokes out.
Speaker 2: So dev chat, not TV slash level up, that's my
Speaker 2: evon what are your picks?
Speaker 4: Okay, my peak for today and his book called micro
Speaker 4: Services in Auction by Morgan Bruce and Paul Opereira. It's
Speaker 4: very nice and laconic book about building micro services the
Speaker 4: right way to Yeah, you can recommend it.
Speaker 2: Awesome. All right, Well we're gonna go ahead and wrap up.
Speaker 2: Thanks for coming. This was fun.
Speaker 4: Thanks a lot, folks. It was very nice discussion about
Speaker 4: types and the library. Thanks for having me today.
Speaker 3: If you fear interested in types like, check out our
Speaker 3: episode with the Gleam of Lewis. Oh yeah, that's fun too, Yes, yes,
Speaker 3: Gleam is very nice. Usually very nice too. We had
Speaker 3: two weeks ago on the show. That was pretty cool.
Speaker 2: Yeah, louis cool.
Speaker 3: Good stuff.
Speaker 2: All right, Well till next time, folks. Next up,