Transcript from the "Introduction" Lesson
>> Okay, welcome to functional architecture. I'm Brian Lonsdorf, I'll be your teacher. And we're gonna learn about architecture and functional programming today. So, there's this issue with teaching architecture. Its always happens where you try to teach architecture and it's gonna have all these benefits. But you can't actually show them in the class when you're teaching it because you want the examples to be simple enough to consume and understand in a day.
[00:00:26] And architecture really only pays off once you hit this kind of breaking point. There's enough complexity and your app gets big enough. So we're gonna try to balance that line and look at how we can apply this architecture to get benefits once the app gets kind of big enough.
[00:00:42] So, what is our goal? Why, why are we doing this? Do we want our apps to be more modular or the, do we need them to be more extensible or performance or maintainable? Each app has a different kind of set of values that you wanna go after. And so for our compass today and in general I think, we can establish a good goal for functional architecture that you start with.
[00:01:07] And as you have different requirements, you can focus on different goals. So what is that goal? What can we do here? Let's just take a step back and look at this code. It's a long procedure, you don't have to read it. But what we're really doing when we do architecture is we just kind of group things.
[00:01:24] And then we give them a name. So we have these named procedures that we've grouped. And then we group those procedures with names into more groups, and we call this modulars, modules or classes. And then those get names. And then we have datatypes. And we group data into these little bundles.
[00:01:42] And then we give those names. We have names on tops of names on tops of names, this giant cloud of names. Thank you to Joe Nelson for the slide. Just wanna call that out. So, Domain Driven Design is a great book. It really, really tells you how coding by metaphor and using these names and really getting into the zone of of using ubiquitous, ubiquitous language to model the real world.
[00:02:07] And really, really hammering on that until you distill it into the perfect metaphors. And we kind of have a problem with metaphors here. One you have to know about the domain and context. You can't just jump into an app. You have to know everything about what's not in the code itself to understand the code.
[00:02:24] And then we end up with like these things like processor and converter. That's not real world, like raise your hand if you've ever written a processor class. So you're, you end up with these mixed metaphors of computer stuff and real world stuff and things evolve over time and blur and you end up with this hodgepodge of functionality.
[00:02:43] There's all kind of grouped by name, but the functionality may be grouped in different ways. So, right off the bat, if we're gonna be capturing procedures for reuse and we're just depending on a name, we don't know what we can do with that, really, there's no actual rules of composition.
[00:03:03] If we're planning on recomposing this after grouping it and naming it, we don't know if we can run it more than once. Can we run it in different orders? is it changing other parts of our program? How does it interact? So these things that we are actually defining don't really become knowledge in our program.
[00:03:24] So we want to focus on these properties here, right? Whenever we develop a stored procedure, we want to have properties around composition. After all, we're reusing these things. We're gonna be composing them in different situations. And these laws are what protect us from just the confusion of the name alone.
[00:03:44] So our first goal is to find functions with defined contracts,mainly those mathematical properties. So we are gonna look at this class ,that's user and we have a full name here.,and yhis is perfect, right? We have a full name function, works just fine. We have Bobby Fischer, comes right out.
[00:04:05] So, another thing we're gonna do here is try to break this down and generalize it. Let's see how that process works. So we have a user type and a full name function. And here we're joining the same thing as the class effectively. And it ends up with the same result.
[00:04:23] But what if we generalize it further, I mean, we're just passing first name and last name. Why don't we create a join with spaces function? We don't have to call it first or last name, and ends up being the same exact function, but it's much more generic and reusable.
[00:04:39] And look, we have properties, it's associative. Turns out, we can call jonWithSpace in any nested order. As long as it's all called, it doesn't matter how we associate the parentheses, that's what associated means. And that's a composable contract for this generic function. I'm gonna hammer on generic functions for a little while longer.
[00:05:01] Here with joinWithSpaces, we could take it a step further and call it joinable. We'll take any joinable and called join on it and then we'll pass in the array. And literally, there's nothing joinWithSpaces can do other than call join, because it knows nothing about its data type. So by generalizing, we're making less possibility, simpler implementations, more reuse, and it becomes a more generic generalized function.
[00:05:29] And we actually gather what we recover encapsulation. Objects give us encapsulation through information hiding, but this effectively is information hiding. If we only know we can call join on our objects, we know nothing else about it, we're hiding information. And we can take that to its logical end and just define this identity function.
[00:05:49] And this identity function, it knows nothing of this a, it's just gonna take an a and return an a. And if it called anything on it or did anything to it, I mean, it would break that contract of taking anything at all and returning it back. So by not knowing anything about this and generalizing it to its logical end, as much as we can make it general, we're actually doing information hiding and protecting ourselves from rippling changes across our application.