The Art of the Javascript Metaobject Protocol
This is a modal window.
Das Video konnte nicht geladen werden, da entweder ein Server- oder Netzwerkfehler auftrat oder das Format nicht unterstützt wird.
Formale Metadaten
Titel |
| |
Untertitel |
| |
Serientitel | ||
Anzahl der Teile | 170 | |
Autor | ||
Lizenz | CC-Namensnennung - keine kommerzielle Nutzung - Weitergabe unter gleichen Bedingungen 3.0 Unported: Sie dürfen das Werk bzw. den Inhalt zu jedem legalen und nicht-kommerziellen Zweck nutzen, verändern und in unveränderter oder veränderter Form vervielfältigen, verbreiten und öffentlich zugänglich machen, sofern Sie den Namen des Autors/Rechteinhabers in der von ihm festgelegten Weise nennen und das Werk bzw. diesen Inhalt auch in veränderter Form nur unter den Bedingungen dieser Lizenz weitergeben | |
Identifikatoren | 10.5446/50630 (DOI) | |
Herausgeber | ||
Erscheinungsjahr | ||
Sprache |
Inhaltliche Metadaten
Fachgebiet | ||
Genre | ||
Abstract |
|
NDC Oslo 201469 / 170
2
3
5
6
8
11
12
16
21
22
23
27
31
35
37
42
43
45
47
48
49
50
52
54
56
57
58
61
65
66
67
71
74
77
80
81
83
84
85
87
88
89
90
91
94
95
96
97
98
100
102
107
108
112
114
115
116
118
120
121
122
123
126
127
128
130
133
135
137
138
139
140
141
142
143
144
145
147
148
149
150
153
155
156
157
158
159
160
161
162
163
166
169
170
00:00
Physikalische TheorieMereologieMeta-TagGrundsätze ordnungsmäßiger DatenverarbeitungWhiteboardZweiSkriptspracheMailing-ListeProtokoll <Datenverarbeitungssystem>Objekt <Kategorie>TopologieMetropolitan area networkUmwandlungsenthalpieQuick-SortAutorisierungComputeranimation
00:52
Objekt <Kategorie>GeheimnisprinzipCodeRepository <Informatik>ComputerspielVerkehrsinformationProzess <Informatik>Ornamentgruppep-BlockCoxeter-GruppePunktZentrische StreckungComputeranimation
01:41
BitZentrische StreckungCodeFunktionalSoftwareentwicklerRechenschieberProgram SlicingSpezifisches VolumenCoxeter-GruppeMultiplikationsoperatorComputeranimation
02:48
Funktion <Mathematik>Service providerSystemaufrufMaßerweiterungObjekt <Kategorie>SichtenkonzeptMixed RealitySinusfunktionSkriptspracheAppletThumbnailMusterspracheFunktionalAutorisierungMultiplikationsoperatorQuick-SortDomain <Netzwerk>Strategisches SpielPrototypingGrenzschichtablösungObjektorientierte ProgrammierspracheInformationCoxeter-GruppeRefactoringKategorie <Mathematik>ProgrammbibliothekEinfache GenauigkeitKartesische KoordinatenInstantiierungRechter WinkelFaktor <Algebra>Schnitt <Mathematik>SpieltheorieReelle ZahlDivergente ReiheWebDAVProgrammierungLaufzeitfehlerForcingFormale SpracheComputeranimation
07:22
Basis <Mathematik>Funktion <Mathematik>AppletProgrammierumgebungKonfiguration <Informatik>DatenmissbrauchSkriptspracheMultiplikationsoperatorKontextbezogenes SystemFunktionalRechter WinkelMaßerweiterungATMIndexberechnungKategorie <Mathematik>Arithmetisches MittelObjekt <Kategorie>Schreib-Lese-KopfZweiMehrrechnersystemProzess <Informatik>PrototypingAttributierte GrammatikDomain <Netzwerk>AggregatzustandKlasse <Mathematik>AbstraktionsebeneWort <Informatik>TorusUltraviolett-PhotoelektronenspektroskopieResultanteRichtungCodeLesen <Datenverarbeitung>Meta-TagQuick-SortSchreiben <Datenverarbeitung>Computeranimation
12:03
E-MailDigitalfilterFunktion <Mathematik>Arithmetisches MittelKontextbezogenes SystemE-MailPhysikalischer EffektPersönliche IdentifikationsnummerVariableFunktionalObjekt <Kategorie>DatenmissbrauchSchreiben <Datenverarbeitung>Computeranimation
13:21
Kontextbezogenes SystemKontextbezogenes SystemPersönliche IdentifikationsnummerObjekt <Kategorie>CodeKategorie <Mathematik>Lesen <Datenverarbeitung>MehrrechnersystemGeradeE-Mail
14:38
Funktion <Mathematik>DifferenteInformatikFundamentalsatz der AlgebraQuellcodeDokumentenserverVierzigCodeFunktionalObjekt <Kategorie>Kontextbezogenes SystemRegulärer Ausdruck <Textverarbeitung>ComputeranimationBesprechung/Interview
15:32
Meta-TagObjekt <Kategorie>NummernsystemFitnessfunktionFunktionalPrototypingBetrag <Mathematik>Äußere Algebra eines ModulsKontextbezogenes SystemKartesische KoordinatenObjekt <Kategorie>ProgrammiergerätVererbungshierarchieComputeranimation
16:17
PrototypingQuarkmodellFormale Sprachep-BlockGebäude <Mathematik>Kontextbezogenes SystemHierarchische StrukturAbgeschlossene MengeMultiplikationsoperatorPrototypingTeilbarkeitObjekt <Kategorie>SchaltnetzProgrammierungQuick-SortObjektorientierte ProgrammierspracheFundamentalsatz der AlgebraBesprechung/Interview
17:04
BetragsflächeWellenlehreMaßstabHierarchische StrukturZentrische StreckungBestimmtheitsmaßMultiplikationsoperatorTechnische ZeichnungComputeranimation
17:59
Objekt <Kategorie>MaßstabMeta-TagZentrische StreckungFunktionalSchreiben <Datenverarbeitung>ProgrammierungRechter WinkelObjekt <Kategorie>SoftwareKette <Mathematik>MathematikDifferenteAnpassung <Mathematik>ProgrammbibliothekKategorie <Mathematik>Quick-SortImplementierungMeta-TagFormale SpracheInterface <Schaltung>VektorraumGemeinsamer SpeicherPrototypingDatenstrukturFokalpunktElement <Gruppentheorie>Komplex <Algebra>FitnessfunktionVererbungshierarchieKontrollstrukturVariableKlasse <Mathematik>TeilbarkeitFlächeninhaltFehlermeldung
20:41
AggregatzustandMusterspracheFunktion <Mathematik>Proxy ServerIndexberechnungKeller <Informatik>OvalGeheimnisprinzipQuick-SortObjekt <Kategorie>DatenmissbrauchKontrollstrukturProgrammierungProxy ServerQuantisierung <Physik>ElektrizitätslehreVersionsverwaltungProzess <Informatik>MereologieKategorie <Mathematik>MusterspracheKeller <Informatik>MultiplikationsoperatorAggregatzustandFormale SpracheOvalCodeFunktionalStellenringAutomatische IndexierungDefaultQuantenelektrodynamikProdukt <Mathematik>SkriptsprachePrototypingAppletKugelkappeVollständiger VerbandMixed RealityImplementierung
24:22
PrototypingFunktion <Mathematik>Objekt <Kategorie>PrototypingSkriptspracheOntologie <Wissensverarbeitung>TopologieReelle ZahlPunktFormale SpracheProgrammiergerätKlasse <Mathematik>Automatische IndexierungMultiplikationsoperatorObjekt <Kategorie>CASE <Informatik>Güte der AnpassungHierarchische StrukturBruchrechnungProdukt <Mathematik>Komplex <Algebra>AppletNebenbedingungTemplateFaktor <Algebra>DifferenteSchnittmengeZeichenketteDickeProgrammierungProtokoll <Datenverarbeitungssystem>StandardabweichungQuick-SortBusiness ObjectMereologieFundamentalsatz der AlgebraVererbungshierarchieGanze ZahlInstantiierungCharakteristisches PolynomFunktionalTermNamensraumEinsMinkowski-MetrikTypentheorieFamilie <Mathematik>Prozess <Informatik>Mixed RealityGewicht <Ausgleichsrechnung>Projektive EbeneZahlenbereichMailing-ListeJSON
30:47
Objekt <Kategorie>MereologieFunktionalAuflösung <Mathematik>SkriptspracheMaschinenschreibenVariableInterface <Schaltung>Ordnung <Mathematik>MomentenproblemWarteschlangeQuick-SortKontrollstrukturPrototypingKeller <Informatik>AggregatzustandMathematikInstantiierungKartesische KoordinatenPartikelsystemHierarchische StrukturGeheimnisprinzipBitComputeranimation
33:14
Offene MengeKlasse <Mathematik>Hierarchische StrukturVariableWort <Informatik>Kartesische KoordinatenMathematikerinFunktionalRekursive FunktionOffene MengePrototypingMultiplikationsoperatorSkriptspracheObjekt <Kategorie>Computeranimation
34:07
Klasse <Mathematik>SystemprogrammierungProgrammierungVererbungshierarchieFundamentalsatz der AlgebraVererbungshierarchiePrototypingZentrische StreckungGewicht <Ausgleichsrechnung>SkriptspracheHierarchische StrukturProzess <Informatik>SoftwareentwicklerObjekt <Kategorie>Reelle ZahlProgrammierungKlasse <Mathematik>VariableMaschinenschreibenRechter WinkelTablet PCKontrollstruktur
34:56
Kartesische KoordinatenProxy ServerZentrische StreckungTypentheorieKeller <Informatik>SystemaufrufPeer-to-Peer-NetzObjekt <Kategorie>ComputeranimationFlussdiagramm
36:01
Kontextbezogenes SystemMaß <Mathematik>Funktion <Mathematik>Objekt <Kategorie>Proxy ServerLie-GruppeKnotenpunktMultitaskingProxy ServerCookie <Internet>Metropolitan area networkCodeGeradeZweiQuick-SortAlgebraisch abgeschlossener KörperMeta-TagDatenmissbrauchObjektorientierte ProgrammierspracheAggregatzustandIdentitätsverwaltungObjekt <Kategorie>Rechter WinkelMusterspracheOrdnung <Mathematik>Mixed RealityKontextbezogenes SystemFormale SpracheAttributierte GrammatikProzess <Informatik>Produkt <Mathematik>Dichte <Physik>AuswahlaxiomSkriptspracheFlussdiagrammComputeranimation
39:32
VerschlingungFunktion <Mathematik>MultitaskingObjekt <Kategorie>Proxy ServerKontextbezogenes SystemObjekt <Kategorie>Proxy ServerKugelkappeFlächeninhaltProtokoll <Datenverarbeitungssystem>Prozess <Informatik>VersionsverwaltungMeta-TagDeklarative ProgrammierspracheAttributierte GrammatikComputeranimation
40:38
Konstruktor <Informatik>Objekt <Kategorie>VHDSLDatenmissbrauchZentrische StreckungAggregatzustandVariableGeheimnisprinzipQuick-SortVererbungshierarchieKlasse <Mathematik>PrototypingSoftwareMultiplikationsoperatorExogene VariableInformatikRekursive FunktionMultiplikationMeta-TagEinfache GenauigkeitComputeranimation
42:25
Netzwerk-gebundene SpeicherungStochastische AbhängigkeitFunktion <Mathematik>KnotenpunktDigitalfilterObjekt <Kategorie>Proxy ServerPartielle DifferentiationKontextbezogenes SystemInnerer PunktGrenzschichtablösungKategorie <Mathematik>SchlüsselverwaltungKategorie <Mathematik>Proxy ServerSoftwareUmwandlungsenthalpieMereologieKontextbezogenes SystemLoginGebäude <Mathematik>CodierungZentrische StreckungObjekt <Kategorie>Exogene VariableVirtuelle MaschineAutomatische HandlungsplanungDeklarative ProgrammierspracheDifferenteQuick-SortPersönliche IdentifikationsnummerGrenzschichtablösungOffene MengeMeta-TagSystemaufrufEinsVariableSchreiben <Datenverarbeitung>AusnahmebehandlungVerkehrsinformationFunktionalInformationsspeicherungMotion CapturingCASE <Informatik>MultiplikationsoperatorSoftwareentwicklerGrundsätze ordnungsmäßiger DatenverarbeitungComputeranimation
46:59
Funktion <Mathematik>Weg <Topologie>Objekt <Kategorie>FunktionalMaßerweiterungMixed RealityMailing-ListePrototypingMultiplikationsoperatorSingularität <Mathematik>SubstitutionKontrollstrukturComputeranimation
48:22
SubstitutionProgrammierungComputerObjekt <Kategorie>Funktion <Mathematik>Auflösung <Mathematik>DigitalfilterSystemaufrufMeta-TagArray <Informatik>HilfesystemFunktionalProtokoll <Datenverarbeitungssystem>SchaltnetzStrategisches SpielOrdnung <Mathematik>CASE <Informatik>Perfekte GruppeSystemaufrufMaßerweiterungComputeranimation
49:27
GruppenoperationFunktion <Mathematik>Objekt <Kategorie>GeheimnisprinzipDatenmodellFunktorMultitaskingMailing-ListeRechter WinkelKartesische KoordinatenAutomatische DifferentiationMailing-ListeLesen <Datenverarbeitung>SichtenkonzeptGüte der AnpassungObjekt <Kategorie>Meta-TagLuenberger-BeobachterExistenzaussageComputeranimation
50:58
ProgrammbibliothekBenutzerbeteiligungZentrische StreckungInteraktives FernsehenCodePunktPrototypingSoftwareProdukt <Mathematik>MaschinenschreibenRekursive FunktionKlasse <Mathematik>ART-NetzSkriptspracheKonfiguration <Informatik>VererbungshierarchieGeheimnisprinzipDifferenteOffene MengeSoftwareentwicklerComputeranimation
52:25
GeheimnisprinzipGeheimnisprinzipProgrammierungMultiplikationsoperatorBitBitrateComputeranimation
53:11
KohäsionWorkstation <Musikinstrument>Hook <Programmierung>KreisflächeKohäsionKontrollstrukturRichtungProtokoll <Datenverarbeitungssystem>MultiplikationsoperatorSelbst organisierendes SystemE-MailHauptidealPhysikalische TheorieBeobachtungsstudieOffice-PaketCodeZentrische StreckungObjekt <Kategorie>SoftwareRechenschieberComputeranimation
55:20
Umkehrung <Mathematik>Exogene VariableHauptidealDatenstrukturStereometrieBenutzerbeteiligungGüte der AnpassungInterface <Schaltung>SoftwareVersionsverwaltungEinfache GenauigkeitArithmetischer AusdruckLuenberger-BeobachterObjekt <Kategorie>Offene MengeKlasse <Mathematik>SubstitutionAbgeschlossene MengeVHDSLUmkehrung <Mathematik>Computeranimation
57:06
Objekt <Kategorie>Protokoll <Datenverarbeitungssystem>ProgrammiergerätMultiplikationsoperatorPunktRückkopplungProgrammierungComputeranimation
Transkript: Englisch(automatisch erzeugt)
00:02
Well, thank you for coming to the second of two talks. They are connected. How many people here were not here for the first talk? You're the winners. You're not going to be nearly as bored as those of you who've sat through an hour already with me. Congratulations. This talk is about the art of the JavaScript mid-object protocol,
00:24
which is, for those of you who are familiar, I don't even know how to pronounce his name. Gregor Kizaks, he wrote the art of the mid-object protocol about Common Lisp, and this is phenomenally pretentious. All I can do is ask you to pretend that I'm a hipster and this is ironic,
00:40
and I'm not actually trying to be in the same city as the author of that incredible work. What we're going to be talking about in this talk, specifically, are proxies, encapsulation, and composition of objects.
01:05
Those are the specific techniques. I'll throw up lots of code, and I'll just tell you now, I'm not expecting anyone to read the code. It's online, of course. It's in GitHub. You can look at it right now in my repo if you're so fascinated. It's more the ideas that we want to talk about.
01:22
The code is kind of a decoration, like wallpaper, a desktop. As much as we're talking about those things, that's not actually what I'm here to communicate. It's not what I was thinking about when putting this presentation together.
01:41
I was thinking about the flexibility of code and decoupling at scale. In the earlier talk, we talked about some very small things, which were little functions and decorators and so on, the opposite of scale, really small scale JavaScript development. Here, I want to talk about things when you're dealing with JavaScript in large scale development, larger teams on what techniques really matter.
02:03
In that respect, it's completely different from the first talk, but in other respects, it's completely the same as the first talk. It's just at a different scale. A lot of slides to go through. Sorry about that, but this is something that really excites me.
02:22
I don't know if it's Voltaire or something. He wants his alleged to have been commissioned to write a novel. Supposedly, with the novel, he included a letter that says, Madame, here's the novel you've commissioned me to write. I have given it to you in two volumes. Had I more time, I would have done it in one.
02:43
I'm sorry. Had I more time, I would have figured out how to have fewer slides in this presentation. I was excited and I couldn't cut as much as possible. We'll start with some basics. How many people here know what a mix-in is? You'll probably all know what it is, but how many people know it by that name?
03:01
The rest of you are probably too polite or busy with other things, making dinner arrangements, and need both thumbs for what you're doing. I understand. Here's an example of an object in JavaScript. One of the pleasures of JavaScript is how sparse this is of syntax. It can be more complicated.
03:21
We can have news and things like that if we want to, but if we don't want to, we don't have to. That, to my mind, is one of the things I like about JavaScript. Our object has some... I'm going to just arbitrarily call them, and you all know that there's not always this sharply delineated, but first name and last name I'm going to say are domain properties.
03:40
And full name and rename I'm going to say are behaviors. Again, one of the beauties is sometimes a domain property is still a function, if you get into things like strategy patterns and so on, and sometimes something that looks like a static thing
04:01
is not necessarily a domain property. It may be some private variable that's used by one of the other functions. So it's not always this clear-cut, but this is a presentation. The presentation is only an hour, so we have a simple example. And this is the first major refactoring everyone does in object-oriented programming 101. You say, hey, the behavior is one thing,
04:21
and the domain properties are another. All people, all instances of person or whatever, have a full name and a rename, and Sam happens to have Sam and Lowry. How many people know this name, Sam Lowry? Okay, leave the presentation right now. Go and download Brazil by Terry Gilliam and watch the movie.
04:41
That's a must. It's much more important than listening to me. Okay, and here's an extend. Underscore has a copy of this. It seems like every library has to reinvent this function. It just takes all the properties from one object and stuffs them by force, whether you like it or not, into another. Or series, in this particular case, it will do more than one.
05:02
But underscore dot extend does this, and I'm pretty sure every single JavaScript library has this function in it. You just can't write JavaScript without doing this, or you're constantly baking your own throughout your application. And if we put those together, you can extend the Sam object with the person object
05:21
and stuff the behaviors in. At runtime, you end up with the same thing that I showed a couple slides ago. Look at this, backwards in time. You end up with this at runtime, but you write this at compile time, at authoring time or whatever, and so you easily see the separation between Sam and person.
05:41
And, because you're mixing it in, there is a many to one or more, or something, we're not quite sure, our relationship, in that you can also extend your Peck object with person, and thus you have shared behavior between Peck and Sam. Of course, we'll all say but prototypes and so on,
06:02
and that's all true, but they're sort of more advanced. This is the thing that they're accomplishing. This is the most basic thing you could do. If there weren't prototypes or whatever, this is the way we would program in JavaScript, and it would work. We would build startups, we would raise money, we would change the world. We'd do just fine if we didn't have anything else.
06:22
This is the most basic thing you can do in JavaScript, just copy values around. It's kind of magic. Other languages, it's very difficult. In Ruby, you have to go through all these backflips to add methods dynamically to other objects. Some languages, it's very difficult to do. The flip side of that, so I said that you can have one behavior
06:41
and apply to more than one object. You can also apply more than one behavior to a single object using this sort of naive or basic mixin. So we can take our existing Peck object and we can add hasCareer behavior to it. We already added person. We can add career information as well.
07:02
This is not true of prototypes. Fundamentally, mixins are a many-to-many relationship. You can have many objects share the same behavior when you're mixing things in, and you can have one object mix several kinds of behavior in.
07:23
However, one flaw, if you want to call it that, is something fundamental to JavaScript. Everything is open all the time. No privacy. JavaScript is not even a clothing optional community. It's a no-clothing community. Everything.
07:43
However, we are clever creatures, we humans, and if we do not like the environment we're in, we modify it to suit. The same is true of JavaScript. So here is a version of extend called extend privately, and what it does is it does the copying
08:01
that the original extend did, but it does a little stuff in between, where what it does is it binds every function that it's copying so that that function will operate in a specific context rather than, sorry, operate, be evaluated, I should say, in a specific context rather than being evaluated in the receiver's context.
08:22
How many people know what I just said, are familiar with those buzz words? Right, so I'll just briefly, those of you, you know, talk amongst yourselves. When we evaluate a method in JavaScript, there's a context. There's something that this refers to, and if we don't do anything else, don't go out of our way to make it any different,
08:42
it's traditionally going to be either in strict mode, I think null, or the global environment if we don't use a method to send a dot invocation, or if we do use a dot, or actually braces as well, it's evaluated in the receiver's context, the receiver's set to this.
09:02
But using things like bind, or apply, or call, I think there's five different ways, but I can only think of three off the top of my head, but there's a quiz, I think there's some other ways, you can actually override and say, no, I want this to mean something else. And what we've done in this particular function, and again, you can come back to this if you want later,
09:21
and there's some flaws with using method name and mixin and so on that you might want to adjust if you were ever writing your own, but you don't need to. What we're saying is, when we copy these functions over, we don't want them to operate in the context of the receiver. We want them to operate in the context of this private property object that we've created.
09:44
And the reason why that is interesting, is that if we extend privately, PEC with hasCareer, we can still do things like set its career and so on. Well look, there's a missing parenthesis and a missing quote. How about that?
10:02
However, when we check the domain property, the attribute that would normally have been set by setCareer, it's not set in PEC. And the reason is, it's been set in that little private property that was created when we called our extend privately.
10:24
So this is a private mixin. It has private data. We still mix it into an object, we're not talking about prototypes yet, but we can in fact create some private data. Now, there are many flaws, I mentioned prototypes.
10:40
Another one has to do with if this isn't the normal thing, sometimes you want to return this from a function, sometimes you want to pass this to another function and that's going to be wrong because it's going to be the private state and not the object. I'm not saying that this is the be all and end all and rush out and rewrite all your code using this technique. Not at all. However, it is kind of like a finger pointing in a direction. The beauty of JavaScript is that you can write anything.
11:07
Aspect-oriented programming, combinators, large, you can write meta object twos, in other words, objects like Ruby classes that have methods like methods and add method and so on. You can write all those things in JavaScript.
11:20
The flaw of JavaScript is that everyone does. But you know what? I don't lose a lot of sleep over that. There are some people who are kind of fascist and say that this is a bad thing, but in every other aspect of human endeavor, we've gotten great results with this. We get great results in business by having lots of people create crappy startups,
11:41
but some people create great things and the wheat gets separated from the chaff. I think it's a good thing when people try to do all sorts of weird things. Yeah, of course most of them are going to fail, but some of them are going to succeed and they're going to add something. It's great that we don't have to ask permission before trying to create private mix-ins or something. Yeah, maybe this particular thing I wrote is crap, but that's okay. Let a thousand flowers bloom.
12:04
Another basic technique is forwarding. I've chosen this picture for a very specific meaning. Semantically, imagine you get an email asking you for a donation for a worthy cause.
12:21
Reg Brathwaite, for example. If you forward that email to someone else, you say, okay, you might be interested in this. That other person reads it in their own context. If they decide to donate, they don't donate your money. The tax receipt isn't made out to you. You forwarded it to them and you're done with it. It's like, here, you deal with this and that happens over there.
12:42
And that's a very important technique. Here's a forward function I've written. I'm not asking you to understand all of this, but the idea is that if you say, hey, I want to forward the following methods to some other object. The receiver looks like they have these methods, but when they get called, they just pass it along.
13:02
So here, you deal with this and it's evaluated in that some other object's context. Why is that interesting? The fact that it's evaluated in their context creates some privacy. Since I forwarded it to something else to handle, if it sets some private variables or whatever, I don't have them.
13:22
It's creating some private context. And in fact, this idea is very important and I'm going to return to it later in this talk. So, let's stick a pin in it and we'll come back to it, this idea of forwarding. Now, that's awful to read. And there's too much text.
13:40
You're not supposed to read stuff on there. I've talked about three things. I've talked about mixins, I've talked about private mixins, and I've talked about forwarding. Now, I really should have drawn a little table, but mixins have two interesting properties.
14:01
The code that actually does the work is in the object, the receiver, and it evaluates in the receiver's context. A private mixin, the code that does the work is in the receiver, but it's evaluated in another object's context.
14:20
Forwarding, the code that does the work is actually in another object and it's evaluated in another object's context. Now, if we drew that on a line, we would see that there's a missing spot. What is it when the code does the work in another object, but it's evaluated in your context? That's delegation.
14:41
Instead of forwarding my email, I delegate it to my accountant. This is different. If the accountant thinks the donation is a good idea, the accountant does not donate the accountant's money. The accountant donates my money on my behalf and I get the tax receipt. Delegating something to be done to somebody else is not the same thing as forwarding. You're asking them to do it on your behalf.
15:01
I think that's true in English. It's certainly true in computer science. There's a fundamental difference between forwarding and delegation, and we can represent that in JavaScript. I won't bore you by walking through all of it. You can come back to this later. The source code is all in my GitHub repository, of course.
15:20
Delegation. So the code is in another object, but it evaluates in my context. Now, there was a function that Reg just wrote, but could there be another way to do this, to delegate to something else? Pardon? Absolutely.
15:42
Prototype is delegation. And it's valuable to go through the code or write your own delegate function because, not as an alternative to prototypes, but when writing with prototypes, if instead of saying, oh, this is inheritance, or this is object-oriented programming, or this is whatever,
16:00
if you say to yourself, oh, this is one of these four different quadrants that we have for evaluating things, I understand how it fits in this larger scheme of evaluating behavior, then it's better to work with when you see it in context of where it fits. And in fact, inheritance, as we say,
16:21
is delegation through prototypes. It's sort of the baked-in thing that's given to you. But it's not the only thing. And those four fundamental concepts mix-ins, private mix-ins, forwarding and delegation, which have these four different combinations of the two factors. Do I do the work, or does somebody else do the work?
16:41
And do they do it in their own context? Or is it somebody else's context or my own context? Those four things are in fact the building blocks of all object-oriented programming in JavaScript and in most other languages. They're kind of like the, they're the quarks. You don't necessarily see them all the time, but those are the things that make the basic objects, the basic entities and techniques
17:01
that we work with every day. So, I've done this little thing. I guess you could say I have an ontological personality. I like to break things down and see where the things fit in their little hierarchy and whatever. I found this picture fascinating. It's from a Russian encyclopedia that was written between 1890 and 1907
17:21
or something like that. So, now that we've got this kind of out of the way, it's time to start thinking at scale. Other than this gentleman who just asked the question, who knows what this picture is? Hmm? Yes.
17:40
It's the last, it's the farthest picture we've ever done from Earth. There's a long little white dot in the middle of that red thing and that is Earth, one pixel large. It's the smallest possible scale. So, let's scale up from these basic techniques.
18:01
So, our problems at scale are very different than problems in the small. In the small, we say things like how do we write a function with a decorator so that the main thing of the function is obvious and the secondary thing like logging or fluent return or whatever is very, it's an important thing to think about.
18:20
I devoted a whole hour to talking about it, but it's not the same as the problem of scale. How do I write stuff that other people are going to come along and maintain and refactor and rewrite? How do we work with much larger programs? So, what are these problems at scale? One, object coupling.
18:41
So, one of the things about other languages that have things like private property is that they want to reduce the amount of coupling between objects. You want to have a very small interface that's very easy to control, so that it's very easy to change later and you don't say, oh, I changed this particular data structure from being an array to being a vector and something else broke
19:00
because it assumed it was an array and not a vector. This was the whole principle behind Smalltalk was that by hiding all this, all the sort of internal implementation, other things that only went through methods would not be broken if you changed internal implementations. That's object coupling. Another problem at scale, inflexibility.
19:21
When you have different sort of interfaces and things set up, it's hard to combine and recombine the various elements. That was the main focus of the 9 o'clock talk. It's a very big issue at large scale because you find that different people have written different things in different ways and they don't fit together and you end up writing a lot of facades and adapters and using libraries that don't necessarily work
19:41
and they upgrade and they make little changes. Suddenly everything's returning a promise instead of returning a value and this is a problem with software at scale. It is not quite the same problem in the small. And then meta object coupling. So by meta object, I mean things like what we call classes, prototypes and so on. These things get coupled as well.
20:01
For example, when you have a prototype chain and you find that something that inherits from another from a super prototype is depending upon the super prototype. And a change there breaks the change in the subclass as more traditional classicists would say. Coupling between meta objects
20:21
in some ways is similar to coupling between objects but we tend to see it in different ways because they're not necessarily directly calling each other's functions. They may, for example, share access to some private variable and if one of them changes what it's writing into that private variable, it breaks the other even though neither one called a function in the other.
20:43
So I talked about three things. Let's start with object coupling. The main culprit is when one object breaks through the encapsulation and just sort of directly handles some private data of another object. Forget that wall. It's two in the morning. We've got a ship. Let me just fix this.
21:01
I've never said that. Not once. So this was Dr. Alan Kay. And many people say that he doesn't know anything about object oriented programming because you know we've moved on since he sort of helped invent Smalltalk
21:22
and the Dynabook and a bunch of other stuff. And that he's far too restrictive. Mostly what I hear is it's inconvenient to pay attention to him. So he said that object oriented programming was only messaging, local retention protection and hiding of state process. He also said an extreme late binding in all things
21:40
and that is difficult to achieve in JavaScript. And we don't have enough time to talk about late versus early binding today. That is something that we don't get a lot of in JavaScript. We don't encapsulate. The language by default is unencapsulated. Our eggs are shell-less.
22:03
There's just yolks being thrown around. But we have a pattern for that. Remember we stuck a pin in it. Forwarding was a pattern where you can have a completely we had private mixins as well. But forwarding is really great. Something else does the work. It's all encapsulated over there and all you expose are the methods. And people can inspect you and I don't have any of this.
22:21
I just forward the tax stuff to somebody else. So ES6 is going to change all of this. But today, if you're not running Node with Harmony or whatever, you can write your own proxy function. And this says, okay, leaving out the optional prototype, I have a base object
22:41
and what I want is a new object that implements all the same methods. It doesn't copy over any of its private data and all it does is forward everything to the base object. Again, the code is not so important and frankly, most of the people in this room can probably write a better version of this function than I can if they know the requirement.
23:02
So here's how we use it. Here's a stack data object. It has an array, an index. I can already see some stuff. If I were applying for a job with myself, I'd have many questions about this alleged stack implementation.
23:21
So don't start feeling smart because you can find flaws. It really is brain damaged. But you'll get the job done. It has three behaviors. Push, pop, and isEmpty. And we can make a proxy by calling proxy on our stack.
23:40
And our stack proxy behaves like a stack. And when we take a look at it, we can see it has the behavior of a stack, but it doesn't actually have any of the properties of a stack. Why? It's just a proxy. It's just an object that hands over, that forwards every single request to the actual stack. This is a classic pattern
24:02
for creating encapsulated private data in JavaScript. There are other things you can do. You can create non-enumerable properties with defined property and so on. But this is like one of the sort of, it's part of the quantum electrodynamics of JavaScript to use proxies.
24:24
Now I mentioned inflexibility earlier. And one of the problems with doing things flexibly in JavaScript is the prototype.
24:42
Prototype inheritance being one to many unfortunately does not match the real world requirements that we usually have in a couple of ways. First, most things are more many to many than they are one to many. And we try to sort of shoehorn them into this artificial tree-shaped ontology. The second problem with the one to many thing,
25:04
which is related to, sort of coupled to the first problem with it, is that it tends to create fat-based classes rather than skinny ones. It's really hard to create an elegant, simple, one to many based class hierarchy.
25:21
Going back to the 80s, one of the things Dr. Alan Kay said about Smalltalk was that when they first created inheritance, they thought that inheritance trees were going to be baked in and that there would be specialists, sort of what you might call meta-programmers, who might make other ones. So they thought that say in banking, an industry consortium of banks
25:41
who all use Smalltalk might agree on a fundamental sort of set of classes that everyone would use. And then you might subclass just off the edge. So there might be bank account, which is an ISO standard or something in Smalltalk, and then you might subclass that in your individual bank. But they did not think that people should be programmers. It was not part of the design of the language that programmers would be creating entire hierarchies
26:01
starting with object and working down to bank account. They thought that these things, people would sit and they'd deliberate in a long time because it took them a long time. Things like the numerical things, the integer, number, and so on, fraction in Smalltalk is considered one of the most beautiful and elegant class hierarchies, and it actually took them an incredibly long time of arguing and debating and oh, what about this
26:20
and thinking about all the cases. And they realized that it's not an everyday thing to make a good class hierarchy that really works in production. And then people went and created stuff like Java and whatever and copied, and they said, oh, class hierarchies, everybody should be doing this. And usually they're terrible, honestly. You know, we work under time constraints and so on,
26:40
and we don't often have entire teams who have no job other than to design the class hierarchy and think about all the consequences. You know, and then we assume that, well, it must be the inherent complexity of the problem. Well, it is the inherent complexity of the problem. It's hard to create class hierarchies. Mixins are many to many. Mixins solve many of these problems for us. Mixins allow us to have thinner objects
27:02
that are single purpose. However, mixins aren't prototypes. So, if you want some of the characteristics of A and some of the characteristics of B, what do you do? In other languages, you write these complicated meta-object protocols.
27:21
JavaScript has something very beautiful and elegant about it. JavaScript is a meta-object one language. Anybody here familiar with that term? Aha, you're all very honest. I made that term up, so I didn't expect any hands. It actually comes from a Lisp term. Lispers talk about Lisp one languages
27:42
and Lisp two languages, which refer to namespaces, whether functions and other values are in the same namespace or in different ones. If JavaScript were a Lisp, it would be a Lisp one because functions are in the same namespace as all of our other values. Something like Pascal is not a Lisp one if it were a Lisp because functions live in a completely different sort of space of things than values like integers and so on.
28:04
So, when it comes to meta-objects, my made-up term, I admit, you don't have to use this anywhere else. A meta-object one language is a language where meta-objects are the same thing as objects. And a made-up object two language is a language where meta-objects are a different kind of thing, fundamentally.
28:21
Small talk, meta-objects are objects. Same thing with Ruby. Meta-objects are objects. However, if I look at the integer class in Ruby, or for that matter the integer class, maybe not integer class, string is a good example. If I look at the string class,
28:41
what are the string class's methods? Does anyone name a string class method? Ah, no. A string instance has a length method, but the string class in Ruby has methods like methods, plural, or class methods, or define const.
29:02
Sorry, it's not supposed to be a trick question, but really the string class has a completely different set of methods than ordinary objects. They have methods that are concerned with doing class-type things. It's a meta-object two language. JavaScript is very different from that. If we made a string prototype, it would have a length method, and it would have a concatenate method,
29:23
or, I don't know, an index of method, because the methods of a meta-class are the same as the methods of the things that it informs, the behaviors that it creates. And that's why I call JavaScript a meta-object one language in that our meta-objects are just the prototypes or templates for the things that we actually use,
29:40
as opposed to being factories with factory-like concerns. A motor car factory does not actually drive. In JavaScript, a motor car factory would drive. You know, it would be a prototype of a car. So, the fact that it's a meta-object one language gives us something really beautiful. It gives us the ability to use the same techniques
30:02
we use for objects with meta-objects, like mixins. So, if we have a person and has career, we can use a prototype like careerist, which just mixes two other behaviors together.
30:25
Earlier, we said mixin is a basic fundamental thing. We can mix behavior into objects, but we don't actually write our program where we mix behavior directly into domain objects. We can use mixin techniques with meta-objects, with prototypes. And, of course, if you prefer, you know, new and so on,
30:43
you can create new careerists rather than object careers. That's okay. I don't mind. So, just before we move into the next part about meta-object coupling, the flexibility in JavaScript comes from recognizing that meta-objects,
31:01
because it's a meta-object one language, are just like objects, and saying they're not some special thing where we only create a function and assign things to a prototype and leave it. We can use all the same techniques we use with objects with meta-objects. Now, that still leaves us with a problem to solve, coupling between meta-objects.
31:25
So, meta-objects need to be encapsulated just like objects do, albeit in a slightly different way. If you're using them as prototypes, you can't just create private state for them and so on, because then it would be shared amongst all the things which inherit from,
31:42
not inherit, which delegate to it, I should say. So, you do need some extra techniques in order to create encapsulation. Now, I'm going to get to those, but I want to explain why this is so important.
32:00
Consider for a moment our stack object. If we wanted to create a queue from a stack, this would be a was-a relationship for those who are really into sort of traditional OO design and so on, that was able to append and remove stuff from the other end of the stack. We had push and pop, I think, on our previous stack.
32:22
We wanted to inherit from it. So, we could create a prototype that delegates to our original stack, if we had a stack prototype, and our new prototype would add two new methods that both touch the, what was it called, array or whatever, you know, we had an attribute for that. And what happens?
32:40
We have a prototype that is touching private variables of an object. Mind you, only the objects that are instances of it. And then we have another prototype which is touching the same private variables. Those two things are coupled through private variables, not through an interface that we carefully designed the way we do with objects, only through methods.
33:00
They're just coupled by directly managing with private state. So, if either one of those changes the way it interacts with private state, it could break the others. Now, this is not a theoretical concern. This is a very large practical concern. This is what most large applications with class hierarchies really look like if you actually trace out all the touching of private variables.
33:25
And in fact, there's a word for this. It's called open recursion. Recursion meaning to refer to yourself. Most people think it only refers to functions referring to themselves. But to a mathematician, recursion is touching yourself. This is beginning to sound very inappropriate. I'm sorry.
33:42
But, basically, this pseudo variable in JavaScript is open recursion. The ability to refer to yourself. And as much as it's very powerful and flexible, it is also this double-edged sword when dealing with the coupling of meta-objects to each other any time you have two or more prototypes involved.
34:02
And not just prototypes, but any time you mix in two things that both refer to this. And in fact, there's a phrase for this that's called the fragile base class problem, which people have discovered going back 30 years to small talk that as you build this hierarchy, the higher you up in the hierarchy,
34:21
the more things you can break by touching anything. Imagine, for example, if JavaScript had a very Ruby-like heavyweight class hierarchy going back up to object at the very top and then I think now there's like a blank object, blank slate or something above it. But if you just think about object, this big fat thing, and you change the way ID works, you'd break every Ruby program in the universe.
34:41
Right? Because everything inherits from it and they all touch into internal private variables. It would be very bad. And that fragile base class problem is a real thing with large-scale software development that relies upon hierarchies of prototypes. So, one of the goals
35:00
when writing large-scale applications is to either get rid of, or at the very least, manage this type of fragility. And we have techniques for that, techniques we've talked about. This is what our proxy looked like before.
35:20
We have some other objects, call them peers, and it doesn't talk directly to the stack, it talks to a proxy for the stack. This is what we can do to isolate a method from this.
35:44
If we have methods that refer to a proxy for this, rather than themselves, you can actually control what they touch and what they don't touch. You can say, this is not available to you, this is.
36:02
Essentially, encapsulating this. Our previous proxy was like, okay, I'm going to build a fence between me and the outside world. But now, this is kind of like, okay, I'm going to put all the cookies out of reach of my children. It's inside my house, but it still does not mean that everyone in my house has access to everything.
36:24
And here's some complicated code that you will look at later and say, oh man, he was a good speaker, but I can do better. And you're right, trust yourself, you can. One of the things that's in here of interest, I'm just going to point out the, I guess, one, two, three, fourth line on there, the second line of code in the method, safekeeping name.
36:44
What this particular, and this is just one of many ways to do it. What this does is hide private state for an object. Remember the private mix and pattern like create a private thing? It hides it in the object in an attribute that is non-enumerated
37:01
so that it doesn't come up if you try to print it or look at it or reference it, you can't find it. There are some trade-offs involved with this, and there are other techniques if you research for doing this kind of thing. This is not the only way. It's just an idea for it. One of the trade-offs, for example, is you can no longer copy objects because if you try to copy it, you're not going to copy this private state
37:21
that's hidden away. So, but this gets the job done for the purpose of this demonstration and if you want to try this code at home. There are other trade-offs I mentioned, you know, copying it is a problem. You have another problem. JavaScript, I said it was a meta object one language.
37:40
JavaScript is kind of a context one language. So, there's two things about contexts. Using a metaphor, I am in this room and I am me. In JavaScript, both of those are the same thing. The context that the method evaluates in and the self, the receiver, the identity of the receiver of the method
38:01
are the same thing, this. That's not true in all object-oriented languages. Some of them separate these concepts. You know, what sort of things, like, well JavaScript sort of does in that you can have a method that lives inside of a closure. But the sort of context that I evaluate in and my identity can be two separate things.
38:23
The technique where you stash private data somewhere munches these together. If you encapsulate this, if this now points to something else, you no longer know who you are. So, you have to find some way to stick that back in. In this particular technique,
38:41
when making a proxy for the method receiver, I know that doesn't make a lot of sense right now, but that's okay. We add a new variable called self. It's not the only way to do it, but it does allow you for those methods that need to refer to themselves. Other techniques, there are some things
39:00
that have a special magic method called yourself. I think small talk, you can always call yourself on any objects in order to get the actual identity of yourself. So, this is not the only way to do it. And that's true of everything I'm showing you here. It's not necessary that this is the canonical way to do something or the suggested way. It's just that it's an example that allows us to talk about a larger subject.
39:23
We can use this technique to invent some private methods. We could say, hey, what is a private method? If you remember the drawing that I did before, and let's go back to it quickly. Ah, there we go. We have this proxy inside. Well, a private method is defined on the proxy, but not on the outside object.
39:40
So any method that's in the outside object, these public methods, can call the private method, but nothing else can call them. And once you have this idea of having a proxy for this, you can write private methods. Now, of course, you'd have to know what they are.
40:00
And, you know, one way to do that is to just go and look at the methods and see, here's a version of this, does the method start with an underscore? If so, I'll make it private. It's a convention that many JavaScript people like. It's not the only way to do it. If you were writing your own meta object protocol, you might say, well, actually, I want to have some declarative thing.
40:21
If the meta object has an attribute called private, which is an array of names, those methods are private. I mean, this is not the only way to do things. But the fundamental idea is that these things are possible. And if I can show you one way, then you know that there is at least one way to do it.
40:42
Now, encapsulation's beard, as I say, is half constructed. This is a Lego thing constructed by a fellow named Chris McVeigh. I've glossed past at very high speed, with much hand-waving, a way of creating encapsulated objects,
41:01
objects that don't willy-nilly mess with the internal private variables. This is useful in that if we have multiple meta objects, either through prototypical inheritance, or by mixing them in together into a single object,
41:20
they all have their own private state that they refer to. They all have their own private data. And so, it does prevent them from interfering with each other through private variables. We've removed that private variable coupling, which is called open recursion in the computer science community.
41:40
But what we haven't removed is the ability for them to just call each other's public methods. That is not a big deal if you're really, really, really super sharp about having single responsibility meta objects that are all small and only do one thing. But if over time, this is a talk where we talk about things on scale, meta objects in classes tend to grow.
42:01
Not everyone is as much of a purist as you are. Other people come and maintain it and they grow. More and more of these things call each other's public methods. And some people just say, well, that's just the nature of software. But you do have a situation where they become coupled not as quickly as if they just touch each other's private variables, but they do become coupled through public methods.
42:21
And one of the things you might want to do is control that. So, we looked at a sort of has name, which we encapsulate. So by calling encapsulate, I'm building something which has that ability to call proxies and use proxies over itself.
42:41
And then we can do the same thing with has career. And both of these are independent. They just expose methods and store some private stuff. And then I create a is self-describing, which actually depends upon there being a name and a career. So it's another meta object. Now, I don't know if this is exactly the right thing to do with names and careers,
43:03
but I know that this is the right way to design software in general. Things have very specific responsibility and if there's something that relies on both of those, you make another thing. It has these dependencies, but it doesn't declare them. The only way you can find out is by examining it. So, you build enough of these and they get large enough, and the next thing you know, you're fooling around with Eclipse
43:21
and trying to have a machine look through all the dependencies for you. So, we can do this. Now before you all thunder to your feet with applause for my invention, this is stuff that Odersky and the Scala people have been doing for years.
43:40
It's not some new thing. It's not necessary to invent stuff as much as it is necessary just to keep your eyes and ears open and graze broadly upon the planes of knowledge that are in this world. What this is, Scala people call this a trait. It has behavior that depends upon other behavior and it can be mixed in to almost any different object to decorate that behavior.
44:06
And you must define those things that it requires as its dependencies. In this case, we've said name and career. I chose with this particular thing not to have a dependencies variable or some other declaration. I chose to use something which feels easy to me to read. Hey, it needs a name and a career and they're both undefined.
44:22
So we've got to go find a definition. We've got to mix it in with some other stuff that have a name and a career. And then if you write a bunch of codes and debug it, hopefully not at three in the morning before giving your talk at ten, you'll identify the dependencies and you'll resolve them by making a proxy
44:42
that instead of just magically copying all of the functions, only copies those that you ask for. And which ones do you ask for? Those that either the meta object defines itself or those dependencies that it declares. So, if we think back to, hopefully I don't need to scroll back,
45:03
this idea that hasName would have its own little proxy inside of the object with whatever variables it needs. And what would be defined on that? Only its own methods. HasName never declared any dependencies so it doesn't actually have access to any of the other stuff that is defined by HasCareer or by IsSelfDescribing.
45:24
HasCareer does the same thing. IsSelfDescribing is a little different. It defines its own thing which was described, I guess, is what it was called. But it also, its proxy, has a name and a career method that it in turn can sort of tunnel down into this to get at itself.
45:42
So you're defining, you're saying, hey, I need these. And while that doesn't magically prevent things from growing over time and coupling, it allows you to manage it because it's explicit where you can see it. At small scale, this just gets in the way. At large scale, sort of the needle pins over and it becomes useful.
46:06
So, here's some nice things to think about. If we can encapsulate our meta objects, that is, if we can, instead of just having them magically just touch this, if we control its access to properties and we keep its own properties private,
46:22
you separate context and self and you make the context something private. You can allow private methods, which is an important part of being able to build things that are more complicated without having the object become very fat, because it's got all these private methods stuck inside there. And you can have your named dependencies,
46:41
which allow you to, in large scale development, see, okay, this thing needs these other things. You can even write pieces of software that do stuff, like you can write a check, and if you have dependencies that haven't been satisfied, it can actually throw an exception or report or log or whatever you want.
47:01
Now, I've just been hand-waving. The stuff that I've showed you so far, you can mix together using the extend function that I showed earlier. However, there are some problems with that. So, here we have our singSongs and it has an initialize method. Here we have a hasAwards. It has an initialize method.
47:25
What happens if we use extends to mix them together? One clobbers the other. This is not a sustainable practice. Fundamentally, semantically, what do we want?
47:42
We want to be able to look at something like singSongs and say, okay, anything that uses the singSongs and however we do it, with prototypes, with mixins, whatever, has this behavior. And anything which does hasAwards has this behavior. This is actually related to the Liskov substitution principle, which is that anything which is a singer of songs has this behavior.
48:04
You can always count on it. No matter what else you mix in or do to it, there's something you can count on when you look at it and say, this thing sings songs. And what we just did with extends does not do that. It breaks that. Now, that particular one is kind of obvious because the initialize method is broken. You're going to discover that right away. But you can have much more subtle breaking of this principle.
48:24
And here's some stuff you can read, but it's actually just a copy of Wikipedia. So let's move on. If we write a bunch of helper functions and ordering strategy and some more helper functions and some resolving of undefined stuff, and we can have a protocol
48:43
and we can check whether things are merged into. Where is he going with this? Call left, which is actually a combinator-type behavior from the first talk. And we can create a seed. What do we get? I think this is the most I've ever hand-waved in the talk. Thank you very much for not rioting.
49:00
I appreciate it. This function, using all of these others, does something very simple. It merges the things together, resolving undefined as it goes, just like extend. But when there's two of the same, it kind of sticks them together in order and says run them both.
49:20
So in the case of our initialize thing, it would run both initializes. That doesn't always work perfectly. But as an example of how it might work, our songwriter, something called Subscribable, which allows you to listen. Somebody asked me earlier about Observe.
49:41
This is kind of like if you don't have ES6 yet. In a Subscribable songwriter, we compose Subscribable with songwriter, and we can wire them together with a third thing, that whenever you add the song, it notifies it.
50:00
And what do you do with that? You have a view, a very complicated view. If you look in the middle of it, it writes to console.log. Some of you are writing front-end applications which do something else entirely. And it works. It stuck the two things together,
50:20
and it allows you to wire multiple things together. And why this matters is that if we go back to here, you'll see that the third thing in the list, which doesn't even have a name, encapsulate, notify, it needs to have a notification, and it has some behavior for addSong.
50:41
If we go back and look at songwriter, songwriter also defines addSong. So our composed meta objects just said, oh, look, there's two different things that define addSong, so I'll just glue them together, one after another. There's some more stuff in there if you look. If something's undefined, it doesn't use it as a return value, and yada, yada, yada, Reds can bore people for days.
51:02
And there is a lot more to it. It's on the web, the entire library. But some principle ideas that come from this. The first one, and this was in the earlier talk as well, is that flexibility comes from having small pieces
51:22
that you can put together. And there are some things in JavaScript that work against this, both structurally, prototype typical inheritance only having single inheritance tends to encourage fat-based classes, and conceptually, open recursion,
51:41
and the fact that all of the prototypes touch this also make it hard to have lots of little small things that interact because they bump into each other. It kind of encourages you to make these really big things that you've designed very carefully to work together, and they're all kind of big and monolithic. So if you can find a way to combine them in a different way,
52:01
I've glossed over one such thing. The exact code is not the point. You're going to get a lot more flexibility. And this is important when dealing with large-scale software development. Honestly, at a small thing, who cares? You can do almost anything and it works. But developing software at scale is hard, and it's important because many of the most important things we need to do as we as a species advance
52:22
involve writing software at scale. Another option, another thing, is that encapsulation is very important, sticking a fence around things. It reduces convenience, but although it's less convenient to have to work around and maybe to divine getters
52:41
and setter methods or something, it actually, in the long run, increases flexibility. It doesn't increase flexibility when you first write a program, not at all. But it does increase flexibility over time because the program does not accrete at the same rate. All programs accrete until they become very static. But some programs accrete more slowly. And programs which are well encapsulated
53:01
accrete more slowly than programs which are not. So in the long run, and it's a bit of a bet, that you'll create less technical debt if you go to the trouble to properly encapsulate things. Another thing is that composition is a good thing. Two things, each of which have a specific purpose,
53:20
a trailer and a little mini car, I think that's a BMW Iata or something like that, a pretty little car. Stick them together, compose them, and you get something else. Now, of course, you can make a station wagon, but this is a very flexible design. You can hook up the trailer to something else and you can drive the Iata without a trailer. This creates what people in OO circles called
53:42
cohesion without coupling, things that work together, but that aren't tied in such a way that making changes breaks. Is everyone just about ready for this? Tell the truth. Yes, right? You need a coffee after listening to all this. The final lesson. Now, I put a lot of slides in here,
54:01
I told you about that, and I hand waved over a lot of stuff. One of the reasons why I didn't lose too much sleep over that was this exact lesson. The actual code is not important. The actual technique is not important. It's more the principle. This is an example of something. In the first talk, I talked about,
54:21
I think it's a Buddhist proverb, finger pointing at the moon, where the story goes that one monk gave a bunch of books and treatises to another monk as a way of saying, here, you come along and study these things and so on. The other monk took them and threw them in the fire to warm himself. He said, how could you do this?
54:41
He said, oh, well, these books, they're not the thing. They're like a finger pointing at the moon. If you pay too much attention to the finger, you'll miss the moon. And I think that's true of the code, as much as I would love it, and I'm proud of it, and I'd love to talk to you some more about it, over IRC or email or whatever,
55:01
the fact of the matter is, it exists to point in a direction. Whether you specifically write a meta-object protocol of your own and the next time you're writing something at scale in your organization or your startup or whatever, or whether you simply take some of these ideas and apply them to the way in which you design software, that's the thing, not this code.
55:22
And finally, if you're not familiar with this expression, solid, I'm hoping that you will actually say, aha, okay, this is something I should check out. Because in fact, everything I've talked about in this talk, in this hour, has focused on one or the other or several of these basic five principles of good software design.
55:42
The single responsibility principle, something should have one clearly defined responsibility which does well. You can't do that if you have all these structures that force you to make fat classes and so on. You're breaking that. You can if you find a way to combine small things together. The open-closed principle, the principle that things should be open to be extended,
56:00
but closed for modification. If you have easy ways to glue small meta-objects together and to extend them as I did very quickly with a lot of hand-waving, by saying, okay, we can glue a songwriter with, what was it called, subscribable and then put them together, that's extending it rather than going in and saying, like actually Smalltalk and both Ruby do, where you have all these observation methods
56:21
and notification methods glued into objects so every object has it. Listgov substitutability, which I did again at high speed, hand-waving over the fact that you can define two methods for addSong and when you use composed meta-objects as opposed to extend, instead of wiping them out, you perform both.
56:40
This speaks to list of substitutability. And we're getting a little long in the tooth here, so you can look through, if you look at this talk again at the material on the web, you can look through that and say, okay, I see where interface segregation comes out of this. I see where dependency inversion comes out of this. The important thing here is the underlying principle of good design, involving small pieces that have clearly defined ways
57:01
of gluing together that you can combine in many different ways. And that, in 57 minutes, is what I have to share with you today. Thank you so much for being patient. I'm afraid we don't have time for Q&A, but I will be around all day if you want to harangue me,
57:22
point fingers, laugh, and so on. And they do have feedback things here. I'd really appreciate your honest and candid feedback that would help me improve both as a presenter and as a programmer.