diff --git a/.gitignore b/.gitignore index a3b42dd..a3c9ad4 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ adminmailer/config.go adminmailer/adminmailer local/backups /tmp +*.exe diff --git a/public/fishbowl.css b/public/fishbowl.css new file mode 100644 index 0000000..2a28c90 --- /dev/null +++ b/public/fishbowl.css @@ -0,0 +1,624 @@ +.fishbowl { + background-color: #36393e; + color: #dcddde; + font-family: Whitney, "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 17px; + font-weight: 400; + border-radius: 3px; +} + +.fishbowl a { + color: #00aff4; + text-decoration: none; +} + +.fishbowl a:hover { + text-decoration: underline; +} + +.fishbowl img { + object-fit: contain; + image-rendering: high-quality; + image-rendering: -webkit-optimize-contrast; +} + +.fishbowl .preamble { + display: grid; + grid-template-columns: auto 1fr; + max-width: 100%; + padding: 1rem; +} + +.fishbowl .preamble__guild-icon-container { + grid-column: 1; +} + +.fishbowl .preamble__guild-icon { + max-width: 88px; + max-height: 88px; +} + +.fishbowl .preamble__entries-container { + grid-column: 2; + margin-left: 1rem; +} + +.fishbowl .preamble__entry { + margin-bottom: 0.15rem; + color: #ffffff; + font-size: 1.4rem; +} + +.fishbowl .preamble__entry--small { + font-size: 1rem; +} + +.fishbowl .chatlog { + padding: 1rem 0; + width: 100%; +} + +.fishbowl .chatlog__message-group { + margin-bottom: 1rem; +} + +.fishbowl .chatlog__message-container { + background-color: transparent; + transition: background-color 1s ease; +} + +.fishbowl .chatlog__message-container--highlighted { + background-color: rgba(114, 137, 218, 0.2); +} + +.fishbowl .chatlog__message-container--pinned { + background-color: rgba(249, 168, 37, 0.05); +} + +.fishbowl .chatlog__message { + display: grid; + grid-template-columns: auto 1fr; + padding: 0.15rem 0; + direction: ltr; + unicode-bidi: bidi-override; +} + +.fishbowl .chatlog__message:hover { + background-color: #32353b; +} + +.fishbowl .chatlog__message:hover .chatlog__short-timestamp { + display: block; +} + +.fishbowl .chatlog__message-aside { + grid-column: 1; + width: 72px; + padding: 0.15rem 0.15rem 0 0.15rem; + text-align: center; +} + +.fishbowl .chatlog__reference-symbol { + height: 10px; + margin: 6px 4px 4px 36px; + border-left: 2px solid #4f545c; + border-top: 2px solid #4f545c; + border-radius: 8px 0 0 0; +} + +.fishbowl .chatlog__avatar { + width: 40px; + height: 40px; + border-radius: 50%; +} + +.fishbowl .chatlog__short-timestamp { + display: none; + color: #a3a6aa; + font-size: 0.75rem; + font-weight: 500; + direction: ltr; + unicode-bidi: bidi-override; +} + +.fishbowl .chatlog__message-primary { + grid-column: 2; + min-width: 0; +} + +.fishbowl .chatlog__reference { + display: flex; + margin-bottom: 0.15rem; + align-items: center; + color: #b5b6b8; + font-size: 0.875rem; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.fishbowl .chatlog__reference-avatar { + width: 16px; + height: 16px; + margin-right: 0.25rem; + border-radius: 50%; +} + +.fishbowl .chatlog__reference-author { + margin-right: 0.3rem; + font-weight: 600; +} + +.fishbowl .chatlog__reference-content { + overflow: hidden; + text-overflow: ellipsis; +} + +.fishbowl .chatlog__reference-link { + cursor: pointer; +} + +.fishbowl .chatlog__reference-link * { + display: inline; + pointer-events: none; +} + +.fishbowl .chatlog__reference-link .hljs { + display: inline; +} + +.fishbowl .chatlog__reference-link:hover { + color: #ffffff; +} + +.fishbowl .chatlog__reference-link:hover *:not(.chatlog__markdown-spoiler) { + color: inherit; +} + +.fishbowl .chatlog__reference-edited-timestamp { + margin-left: 0.25rem; + color: #a3a6aa; + font-size: 0.75rem; + font-weight: 500; + direction: ltr; + unicode-bidi: bidi-override; +} + +.fishbowl .chatlog__header { + margin-bottom: 0.1rem; +} + +.fishbowl .chatlog__author { + font-weight: 500; + color: #ffffff; +} + +.fishbowl .chatlog__bot-label { + position: relative; + top: -0.1rem; + margin-left: 0.3rem; + padding: 0.05rem 0.3rem; + border-radius: 3px; + background-color: #5865F2; + color: #ffffff; + font-size: 0.625rem; + font-weight: 500; + line-height: 1.3; +} + +.fishbowl .chatlog__timestamp { + margin-left: 0.3rem; + color: #a3a6aa; + font-size: 0.75rem; + font-weight: 500; + direction: ltr; + unicode-bidi: bidi-override; +} + +.fishbowl .chatlog__content { + padding-right: 1rem; + font-size: 0.95rem; + word-wrap: break-word; +} + +.fishbowl .chatlog__edited-timestamp { + margin-left: 0.15rem; + color: #a3a6aa; + font-size: 0.75rem; + font-weight: 500; +} + +.fishbowl .chatlog__attachment { + position: relative; + width: fit-content; + margin-top: 0.3rem; + border-radius: 3px; + overflow: hidden; +} + +.fishbowl .chatlog__attachment--hidden { + cursor: pointer; + box-shadow: 0 0 1px 1px rgba(0, 0, 0, 0.1); +} + +.fishbowl .chatlog__attachment--hidden * { + pointer-events: none; +} + +.fishbowl .chatlog__attachment-spoiler-caption { + display: none; + position: absolute; + left: 50%; + top: 50%; + z-index: 999; + padding: 0.4rem 0.8rem; + border-radius: 20px; + transform: translate(-50%, -50%); + background-color: rgba(0, 0, 0, 0.9); + color: #dcddde; + font-size: 0.9rem; + font-weight: 600; + letter-spacing: 0.05rem; +} + +.fishbowl .chatlog__attachment--hidden .chatlog__attachment-spoiler-caption { + display: block; +} + +.fishbowl .chatlog__attachment--hidden:hover .chatlog__attachment-spoiler-caption { + color: #fff; +} + +.fishbowl .chatlog__attachment-media { + max-width: 45vw; + max-height: 500px; + vertical-align: top; + border-radius: 3px; +} + +.fishbowl .chatlog__attachment--hidden .chatlog__attachment-media { + filter: blur(44px); +} + +.fishbowl .chatlog__attachment-generic { + max-width: 520px; + width: 100%; + height: 40px; + padding: 10px; + border: 1px solid #292b2f; + border-radius: 3px; + background-color: #2f3136; + overflow: hidden; +} + +.fishbowl .chatlog__attachment--hidden .chatlog__attachment-generic { + filter: blur(44px); +} + +.fishbowl .chatlog__attachment-generic-icon { + float: left; + width: 30px; + height: 100%; + margin-right: 10px; +} + +.fishbowl .chatlog__attachment-generic-size { + color: #72767d; + font-size: 12px; +} + +.fishbowl .chatlog__attachment-generic-name { + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} + +.fishbowl .chatlog__embed { + display: flex; + margin-top: 0.3rem; + max-width: 520px; +} + +.fishbowl .chatlog__embed-color-pill { + flex-shrink: 0; + width: 0.25rem; + border-top-left-radius: 3px; + border-bottom-left-radius: 3px; +} + +.fishbowl .chatlog__embed-color-pill--default { + background-color: #202225; +} + +.fishbowl .chatlog__embed-content-container { + display: flex; + flex-direction: column; + padding: 0.5rem 0.6rem; + border: 1px solid rgba(46, 48, 54, 0.6); + border-top-right-radius: 3px; + border-bottom-right-radius: 3px; + background-color: rgba(46, 48, 54, 0.3); +} + +.fishbowl .chatlog__embed-content { + display: flex; + width: 100%; +} + +.fishbowl .chatlog__embed-text { + flex: 1; +} + +.fishbowl .chatlog__embed-author-container { + display: flex; + margin-bottom: 0.5rem; + align-items: center; +} + +.fishbowl .chatlog__embed-author-icon { + width: 20px; + height: 20px; + margin-right: 0.5rem; + border-radius: 50%; +} + +.fishbowl .chatlog__embed-author { + color: #ffffff; + font-size: 0.875rem; + font-weight: 600; + direction: ltr; + unicode-bidi: bidi-override; +} + +.fishbowl .chatlog__embed-author-link { + color: #ffffff; +} + +.fishbowl .chatlog__embed-title { + margin-bottom: 0.5rem; + color: #ffffff; + font-size: 0.875rem; + font-weight: 600; +} + +.fishbowl .chatlog__embed-description { + color: #dcddde; + font-weight: 500; + font-size: 0.85rem; +} + +.fishbowl .chatlog__embed-fields { + display: flex; + flex-wrap: wrap; + gap: 0 0.5rem; +} + +.fishbowl .chatlog__embed-field { + flex: 0; + min-width: 100%; + max-width: 506px; + padding-top: 0.6rem; + font-size: 0.875rem; +} + +.fishbowl .chatlog__embed-field--inline { + flex: 1; + flex-basis: auto; + min-width: 50px; +} + +.fishbowl .chatlog__embed-field-name { + margin-bottom: 0.2rem; + color: #ffffff; + font-weight: 600; +} + +.fishbowl .chatlog__embed-field-value { + color: #dcddde; + font-weight: 500; +} + +.fishbowl .chatlog__embed-thumbnail { + flex: 0; + max-width: 80px; + max-height: 80px; + margin-left: 1.2rem; + border-radius: 3px; +} + +.fishbowl .chatlog__embed-image-container { + margin-top: 0.6rem; +} + +.fishbowl .chatlog__embed-image { + max-width: 500px; + max-height: 400px; + border-radius: 3px; +} + +.fishbowl .chatlog__embed-footer { + margin-top: 0.6rem; + color: #dcddde; +} + +.fishbowl .chatlog__embed-footer-icon { + width: 20px; + height: 20px; + margin-right: 0.2rem; + border-radius: 50%; + vertical-align: middle; +} + +.fishbowl .chatlog__embed-footer-text { + vertical-align: middle; + font-size: 0.75rem; + font-weight: 500; +} + +.fishbowl .chatlog__embed-plainimage { + max-width: 45vw; + max-height: 500px; + vertical-align: top; + border-radius: 3px; +} + +.fishbowl .chatlog__embed-spotify { + border: 0; +} + +.fishbowl .chatlog__embed-youtube-container { + margin-top: 0.6rem; +} + +.fishbowl .chatlog__embed-youtube { + border: 0; + border-radius: 3px; +} + +.fishbowl .chatlog__sticker { + width: 180px; + height: 180px; +} + +.fishbowl .chatlog__sticker--media { + max-width: 100%; + max-height: 100%; +} + +.fishbowl .chatlog__reactions { + display: flex; +} + +.fishbowl .chatlog__reaction { + display: flex; + margin: 0.35rem 0.1rem 0.1rem 0; + padding: 0.125rem 0.375rem; + border: 1px solid transparent; + border-radius: 8px; + background-color: #2f3136; + align-items: center; +} + +.fishbowl .chatlog__reaction:hover { + border: 1px solid hsla(0,0%,100%,.2); + background-color: transparent; +} + +.fishbowl .chatlog__reaction-count { + min-width: 9px; + margin-left: 0.35rem; + color: #b9bbbe; + font-size: 0.875rem; +} + +.fishbowl .chatlog__reaction:hover .chatlog__reaction-count { + color: #dcddde; +} + +.fishbowl .chatlog__markdown { + max-width: 100%; + line-height: 1.3; + overflow-wrap: break-word; +} + +.fishbowl .chatlog__markdown-preserve { + white-space: pre-wrap; +} + +.fishbowl .chatlog__markdown-spoiler { + background-color: rgba(255, 255, 255, 0.1); + border-radius: 3px; +} + +.fishbowl .chatlog__markdown-spoiler--hidden { + cursor: pointer; + background-color: #202225; + color: rgba(0, 0, 0, 0); +} + +.fishbowl .chatlog__markdown-spoiler--hidden:hover { + background-color: rgba(32, 34, 37, 0.8); +} + +.fishbowl .chatlog__markdown-spoiler--hidden::selection { + color: rgba(0, 0, 0, 0); +} + +.fishbowl .chatlog__markdown-quote { + display: flex; + margin: 0.05rem 0; +} + +.fishbowl .chatlog__markdown-quote-border { + margin-right: 0.5rem; + border: 2px solid #4f545c; + border-radius: 3px; +} + +.fishbowl .chatlog__markdown-pre { + background-color: #2f3136; + font-family: "Consolas", "Courier New", Courier, monospace; +} + +.fishbowl .chatlog__markdown-pre--multiline { + margin-top: 0.25rem; + padding: 0.5rem; + border: 2px solid #282b30; + border-radius: 5px; + color: #b9bbbe; +} + +.fishbowl .chatlog__markdown-pre--multiline.hljs { + background-color: inherit; + color: inherit; +} + +.fishbowl .chatlog__markdown-pre--inline { + padding: 2px; + border-radius: 3px; + font-size: 0.85rem; +} + +.fishbowl .chatlog__markdown-mention { + border-radius: 3px; + padding: 0 2px; + background-color: rgba(88, 101, 242, .3); + color: #dee0fc; + font-weight: 500; +} + +.fishbowl .chatlog__markdown-mention:hover { + background-color: #5865f2; + color: #ffffff +} + +.fishbowl .chatlog__markdown-timestamp { + border-radius: 3px; + padding: 0 2px; + color: #a3a6aa; +} + +.fishbowl .chatlog__emoji { + width: 1.325rem; + height: 1.325rem; + margin: 0 0.06rem; + vertical-align: -0.4rem; +} + +.fishbowl .chatlog__emoji--small { + width: 1rem; + height: 1rem; +} + +.fishbowl .chatlog__emoji--large { + width: 2.8rem; + height: 2.8rem; +} + +.fishbowl .postamble { + padding: 1.25rem; +} + +.fishbowl .postamble__entry { + color: #ffffff; +} diff --git a/public/fonts/whitney/whitney-300-1FE35.woff b/public/fonts/whitney/whitney-300-1FE35.woff new file mode 100644 index 0000000..dc91427 Binary files /dev/null and b/public/fonts/whitney/whitney-300-1FE35.woff differ diff --git a/public/fonts/whitney/whitney-400-83E7B.woff b/public/fonts/whitney/whitney-400-83E7B.woff new file mode 100644 index 0000000..2b33081 Binary files /dev/null and b/public/fonts/whitney/whitney-400-83E7B.woff differ diff --git a/public/fonts/whitney/whitney-500-47E37.woff b/public/fonts/whitney/whitney-500-47E37.woff new file mode 100644 index 0000000..fc82138 Binary files /dev/null and b/public/fonts/whitney/whitney-500-47E37.woff differ diff --git a/public/fonts/whitney/whitney-600-9EC09.woff b/public/fonts/whitney/whitney-600-9EC09.woff new file mode 100644 index 0000000..598a6f8 Binary files /dev/null and b/public/fonts/whitney/whitney-600-9EC09.woff differ diff --git a/public/fonts/whitney/whitney-700-A7A71.woff b/public/fonts/whitney/whitney-700-A7A71.woff new file mode 100644 index 0000000..50565a3 Binary files /dev/null and b/public/fonts/whitney/whitney-700-A7A71.woff differ diff --git a/public/fonts/whitney/whitney.css b/public/fonts/whitney/whitney.css new file mode 100644 index 0000000..3735a91 --- /dev/null +++ b/public/fonts/whitney/whitney.css @@ -0,0 +1,29 @@ +@font-face { + src: url(whitney-300-1FE35.woff); + font-family: Whitney; + font-weight: 300; +} + +@font-face { + src: url(whitney-400-83E7B.woff); + font-family: Whitney; + font-weight: 400; +} + +@font-face { + src: url(whitney-500-47E37.woff); + font-family: Whitney; + font-weight: 500; +} + +@font-face { + src: url(whitney-600-9EC09.woff); + font-family: Whitney; + font-weight: 600; +} + +@font-face { + src: url(whitney-700-A7A71.woff); + font-family: Whitney; + font-weight: 700; +} diff --git a/src/ansicolor/ansicolor.go b/src/ansicolor/ansicolor.go index b0e218d..e4609c7 100644 --- a/src/ansicolor/ansicolor.go +++ b/src/ansicolor/ansicolor.go @@ -5,7 +5,7 @@ import "runtime" // See this file for a good color reference: // https://github.com/fatih/color/blob/master/color.go -var Reset = "\033[0m" +var Reset = "\033[0m" // BgBlack is here because Windows just does not care about you at all. var Bold = "\033[1m" var Faint = "\033[2m" var Italic = "\033[3m" @@ -36,14 +36,6 @@ var BgWhite = "\033[47m" func init() { if runtime.GOOS == "windows" { - Reset = "" - Red = "" - Green = "" - Yellow = "" - Blue = "" - Purple = "" - Cyan = "" - Gray = "" - White = "" + Reset = BgBlack + Reset } } diff --git a/src/hmnurl/hmnurl_test.go b/src/hmnurl/hmnurl_test.go index ee861d6..43f634b 100644 --- a/src/hmnurl/hmnurl_test.go +++ b/src/hmnurl/hmnurl_test.go @@ -172,6 +172,15 @@ func TestPodcastRSS(t *testing.T) { AssertRegexMatch(t, BuildPodcastRSS(), RegexPodcastRSS, nil) } +func TestFishbowlIndex(t *testing.T) { + AssertRegexMatch(t, BuildFishbowlIndex(), RegexFishbowlIndex, nil) +} + +func TestFishbowl(t *testing.T) { + AssertRegexMatch(t, BuildFishbowl("oop"), RegexFishbowl, nil) + AssertRegexNoMatch(t, BuildFishbowl("oop")+"/otherfiles/whatever", RegexFishbowl) +} + func TestForum(t *testing.T) { AssertRegexMatch(t, hmn.BuildForum(nil, 1), RegexForum, nil) AssertRegexMatch(t, hmn.BuildForum([]string{"wip"}, 2), RegexForum, map[string]string{"subforums": "wip", "page": "2"}) diff --git a/src/hmnurl/urls.go b/src/hmnurl/urls.go index 337c0c0..01b27ae 100644 --- a/src/hmnurl/urls.go +++ b/src/hmnurl/urls.go @@ -365,6 +365,26 @@ func BuildPodcastEpisodeFile(filename string) string { return BuildUserFile(fmt.Sprintf("podcast/%s/%s", models.HMNProjectSlug, filename)) } +/* + * Fishbowls + */ + +var RegexFishbowlIndex = regexp.MustCompile(`^/fishbowl$`) + +func BuildFishbowlIndex() string { + defer CatchPanic() + return Url("/fishbowl", nil) +} + +var RegexFishbowl = regexp.MustCompile(`^/fishbowl/(?P[^/]+)$`) + +func BuildFishbowl(name string) string { + defer CatchPanic() + return Url(fmt.Sprintf("/fishbowl/%s", name), nil) +} + +var RegexFishbowlFiles = regexp.MustCompile(`^/fishbowl/(?P[^/]+)(?P/.+)$`) + /* * Forums */ diff --git a/src/templates/src/fishbowl.html b/src/templates/src/fishbowl.html new file mode 100644 index 0000000..b10d510 --- /dev/null +++ b/src/templates/src/fishbowl.html @@ -0,0 +1,47 @@ +{{ template "base.html" . }} + +{{ define "extrahead" }} + + + + +{{ end }} + +{{ define "content" }} +
+ {{- .Contents -}} +
+{{ end }} diff --git a/src/templates/src/fishbowl_index.html b/src/templates/src/fishbowl_index.html new file mode 100644 index 0000000..943a38e --- /dev/null +++ b/src/templates/src/fishbowl_index.html @@ -0,0 +1,7 @@ +{{ template "base.html" . }} + +{{ define "content" }} + +{{ end }} diff --git a/src/templates/src/fishbowls/README.md b/src/templates/src/fishbowls/README.md new file mode 100644 index 0000000..bb1fd07 --- /dev/null +++ b/src/templates/src/fishbowls/README.md @@ -0,0 +1,5 @@ +# Folder structure + +One folder per fishbowl. It will look for an index.html file to be dumped directly into the page. All other files / directories are to be served as static files. + +The fishbowl folder name will be used as the URL slug. This is important because the folder name is used for routing to static files. diff --git a/src/templates/src/fishbowls/oop/OOP.html b/src/templates/src/fishbowls/oop/OOP.html new file mode 100644 index 0000000..6f709a2 --- /dev/null +++ b/src/templates/src/fishbowls/oop/OOP.html @@ -0,0 +1,13049 @@ + + + Handmade Network - What, if anything, is OOP? + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ Guild icon +
+
+
Handmade Network
+
fishbowl / What, if anything, is OOP?
+ + +
+
+ +
+ + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
bvisness
+
+ +Topic: What, if anything, is OOP? + +
+
+
+ bvisness + + + 28-May-22 09:58 AM +
+ + + + + +
+
+
+
+
+
+
09:58
+
+ +
+ +
+ Welcome to yet another fishbowl, everyone! Just setting things up here. The main conversation is here in this thread, and the #fishbowl-audience conversation starts here: https://discord.com/channels/239737791225790464/708458209131757598/980155512412864552 + +The pinned messages are some "checkpoints" in the discussion; chapter markers of sorts. Check them out if there's a specific aspect of the discussion you'd like to see. + + (edited) +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ gingerBill + + + 28-May-22 09:59 AM +
+ +
+ Welcome, everyone! + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 10:00 AM +
+ +
+ Hi! + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 10:01 AM +
+ +
+ So, this fishbowl is a long time coming. Since the dawn of the network, many people have asked the question: Is object-oriented programming bad, or what? + +
+ + + + +
+
+ 💥 + 4 +
+
+
+
+
+
+
+
+
10:02
+
+ +
+ +
+ That is, unfortunately, not a very nuanced question. 🙂 + +
+ + + + +
+
+
+
+
+
+
10:02
+
+ +
+ +
+ Our conversations about OOP often veer in a lot of different directions, and the subject is hard to discuss productively because it means so many different things to different people. + +
+ + + + +
+
+
+
+
+
+
10:04
+
+ +
+ +
+ There are many different ideas that are bundled into the modern concept of "object-oriented programming". There are also many languages that have taken on these ideas with different decisions and tradeoffs. Our goal in this fishbowl is to break this subject down and discuss these different concepts with more nuance. + +
+ + + + +
+
+
+
+
+
+
10:04
+
+ +
+ +
+ To that end, we're doing things just a little bit differently for this one. Each of our esteemed participants have picked a particular aspect of "OOP" to present, and we'll be working through those over the course of the conversation here. + +
+ + + + +
+
+
+
+
+
+
10:04
+
+ +
+ +
+ On that note, let me introduce our participants: + +
+ + + + +
+
+
+
+
+
+
10:05
+
+ +
+ +
+ - me (hi) + +
+ + + + +
+
+
+
+
+
+
10:05
+
+ +
+ +
+ - @demetrispanos, general wise elder of the community with particular expertise in machine learning and artificial intelligence + +
+ + + + +
+
+
+
+
+
+
10:06
+
+ +
+ +
+ - @gingerBill, creator of the Odin programming language + +
+ + + + +
+
+
+
+
+
+
10:07
+
+ +
+ +
+ - @Kartik Agaram, creator of creative and very low-level programming systems / operating systems such as Mu and Teliva (look them up!) + +
+ + + + +
+
+
+
+
+
+
10:08
+
+ +
+ +
+ - @SirWhinesalot, a community member whose comments were instrumental to the planning process for this fishbowl (if there are projects you've worked on that I'm not aware of, let me know and I'll update this introduction 😅) + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 10:08 AM +
+ +
+ none public 🙂 + +
+ + + + +
+
+
+
+
+
+
10:08
+
+ +
+ +
+ but my expertise is in Domain-Specific Languages and Constraint Solving + +
+ + + + +
+
+ ❗ + 1 +
+
+
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 10:08 AM +
+ +
+ 👍 + +
+ + + + +
+
+
+
+
+
+
10:09
+
+ +
+ +
+ Before we get into the various modern conceptions of OOP, I think it would be good to take a look back at the history of object-oriented programming, and the path that we took to get to where we are today. @Kartik Agaram has graciously volunteered to walk us through that history, so - take it away, Kartik! + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 10:10 AM +
+ +
+ Is this thing on? Ok, let me paste in some prepared remarks. A quick, opinionated timeline of the major ideas that make up OO. + +
+ + + + +
+
+
+
+
+
+
10:10
+
+ +
+ +
+ 1958-1966: A few different people gradually come up with the notion of structured data. Conventions for managing compound data made of multiple words in memory. If you have two points, you want their x and y coordinates close together and in the same relative order. Seems obvious, but wasn't! See http://akkartik.name/sketchpad-oo.png from the Sketchpad thesis [1]. + +1960-1962: Ivan Sutherland works on Sketchpad. It presages many OO ideas, but they're all in the programmer's mind and prose (thesis) because the code is all machine code. + +1961-1962: Simula provides language support for many OO ideas: objects, classes, inheritance, dispatch based on the precise class of an object (virtual methods).[2] + +1960-1975: Data first. This was mostly a mindset thing, but led eventually to notation like obj.method. Had spread fairly wide by around 1975, when Fred Brooks said, "show me your code and I'll be mystified. Show me your data structures and the code will be obvious." [3] + +1973-1975: Abstract data types by Barbara Liskov. Ignore internal details of how objects are laid out in memory. Focus instead on a small vocabulary of operations that can be performed using them. Interfaces, basically.[4] + +1966-1975: Alan Kay coins OO after working on Smalltalk. (The first chapter of http://gagne.homedns.org/~tgagne/contrib/EarlyHistoryST.html is better than my history above.) "Did not have C++ in mind." However, we're only halfway done. + + (edited) +
+ + +
+ + Embedded image + +
+ + +
+
+
+
+
+
+
10:11
+
+ +
+ +
+ 1970-1975: Lexical scope comes into its own, and leads naturally to closures.[5] + +1980-1994: Lisp has been evolving largely in parallel, but now starts to cross-pollinate with OO. MIT Flavors (1982), CommonLOOPS (1986), CLOS (1994). OO is big on late binding. Lisp takes late binding to 11, with before/after advice and dispatch based on the types of multiple arguments. In 1994, Common Lisp decides to adopt lexical scope by default. + +1992: It becomes clear that there's a yin-yang duality between objects and closures.[6] Though objects have the benefit of putting data first. + +1994: The "gang of four" writes the Design Patterns book, based on ideas by the architect Christopher Alexander. Kicks off the field of OO design. + +2001: Joel Spolsky coins "architecture astronauts,"[7] peak of hype cycle for design patterns. (OO design remains in vogue to this day, though.) + +2007: Clojure arrives. Built on an OO foundation (the JVM) but determinedly anti-OO. Peak of the hype cycle for OO? Functional programming is now ascendant, impelled by the value of immutability. + +2008-2014: Growing anti-OO sentiment[8], anti-design-patterns sentiment[9], awareness that composition is superior to inheritance[10]. + +2020: Richard Feldman crystallizes the case against OO[11]: OO wants to make every object a little computer. But why do we want to make all programs distributed? + +
+ + + + +
+
+
+ +
+
+
+
10:12
+
+ +
+ +
+ Ok I'm done 🙂 Summary: there's a lot of ideas baked into "OO". Most of them are great. Some of them are showing their age. And unbundling them all feels more useful than treating them monolithically. End prepared remarks 🙂 + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 10:14 AM +
+ +
+ Excellent, this is a wonderful place to start. I appreciate that you included a lot of the recent takes on OO; I think we'll especially be revisiting a lot of the 2001-present takes as we go along. + +
+ + + + +
+
+
+
+
+
+
10:16
+
+ +
+ +
+ For some more context, what languages were in use around the 60s-70s when Brooks said that quote about data structures, and when Liskov was pioneering abstract data types? + +
+ + + + +
+
+
+
+
+
+
10:16
+
+ +
+ +
+ In general I'm curious how some of these early ideas manifested in the tools that we now use today. (I know Java was a big one along the way, and we'll have a nice long section dedicated just to that...) + + (edited) +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 10:18 AM +
+ +
+ I know CLU (Barbara Liskov's language) came out in 1973 + +
+ + + + +
+
+
+
+
+
+
10:18
+
+ +
+ +
+ Interestingly it was the first language with built-in Tagged Unions as far as I know + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 10:19 AM +
+ +
+ Oh gosh. I wasn't around then 🙂 but my weak sense is that while there were a few different programming languages being researched, the vast majority of people were programming in machine code and Assembly back then. Big ones: Fortran, COBOL, Algol (still getting refined), Lisp 1.5. + +
+ + + + +
+
+
+
+
+
+
10:20
+
+ +
+ +
+ @SirWhinesalot Yes, I think so! Too bad it took so long for them to go "mainstream". + +
+ + + + +
+
+
+
+
+
+
10:21
+
+ +
+ +
+ Going back to that Brooks quote. I think he was mostly talking about how programmers communicate. Languages and compilers weren't really the dominant gatekeepers of notation back then. + +
+ + + + +
+
+
+
+
+
+
10:21
+
+ +
+ +
+ It was paper, in some form. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 10:21 AM +
+ +
+ That makes sense, I suppose that would be the case + +
+ + + + +
+
+
+
+
+
+
10:22
+
+ +
+ +
+ The sense that I get (which may not be very accurate) is that in the 60s and 70s, there was a lot of pioneering work in the field happening mostly in parallel, but that the ideas hadn't really taken hold in "industry" yet. At what point would you say that began to occur? + + (edited) +
+ + + + +
+
+
+
+
+
+
10:22
+
+ +
+ +
+ Certainly from what I've seen of e.g. FORTRAN, the "practical tools" of the day didn't have any such concepts. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 10:25 AM +
+ +
+ That's a good question. I have a hard time thinking of descriptions of production systems and languages used by industry. Even though Bell Labs and PARC came from industry, I think a lot of their work was fed by govt. grants and so tightly coupled with govt. rather than commercial considerations. + +The software industry took off around late 70s? And then it took a while to rediscover the value of programming languages as the PC revolution took off and computers got fast enough to manage HLLs. + +
+ + + + +
+
+
+
+
+
+
10:25
+
+ +
+ +
+ Turbo Pascal was 1983. That was really my introduction to high-level languages. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 10:26 AM +
+ +
+ I know @gingerBill is quite a Pascal fan; I don't know if he would know any more about the history there + +
+ + + + +
+
+
+
+
+
+
10:26
+
+ +
+ +
+ or at least a Wirth fan 🙂 + +
+ + + + +
+
+ ❤️ + 3 +
+
+
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ gingerBill + + + 28-May-22 10:27 AM +
+ +
+ The first Pascal was created by Niklaus Wirth in 1970 as a teaching tool. + +
+ + + + +
+
+
+
+
+
+
10:27
+
+ +
+ +
+ It mostly became popular because of its simplicity and that it was easy to learn, especially amongst many of the minicomputer buyers in the 1970s. + +
+ + + + +
+
+
+
+
+
+
10:28
+
+ +
+ +
+ Pascal (along with C) are part of a language family called ALGOL, specifically ALGOL 60. + +
+ + + + +
+
+
+
+
+
+
10:28
+
+ +
+ +
+ ALGOL is the basis of pretty much every imperative (procedural) programming language to date. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 10:30 AM +
+ +
+ It's honestly pretty crazy to me to look at the timeline here and see that nearly all these fundamental OOP-y designs were all developed independently at around the same time. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ gingerBill + + + 28-May-22 10:31 AM +
+ +
+ ALGOL 60 was created by many designers with many famous names too: +John Backus, Peter Naur (yes, those two of Backus-Naur Form), Friedrich Bauer (discovered the stack data structure), Charles Katz (you'll see his name in many papers), John McCarthy (AI, Lisp, etc), Alan Perlis (APL), and many many more. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 10:31 AM +
+ +
+ And then the whole academic side runs out of steam in the 2000s, in my mind.. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ gingerBill + + + 28-May-22 10:32 AM +
+ +
+ There's the basic history lesson for the roots of all imperative programming languages, as well as some others like Lisp and APL. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 10:33 AM +
+ +
+ The 1980s to early 1990s is when OOP really starts picking up steam, Object Pascal, Objective-C, C++, COM, all culminating in Java in 1995 + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 10:33 AM +
+ +
+ I think I can see traces of all these historical ideas in the languages we use today, and perhaps we can refer back to this list as we go + +
+ + + + +
+
+
+
+
+
+
10:33
+
+ +
+ +
+ What Bill is saying about imperative programming languages may accidentally be a good segue into the first major concept of OOP that I have on my list... + +
+ + + + +
+
+
+
+
+
+
10:34
+
+ +
+ +
+ Which is that OOP is when you associate behavior with data, in a sense just the idea of a "method". (I am not saying this is a completely correct concept, but it is one that I see frequently discussed.) + + (edited) +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ gingerBill + + + 28-May-22 10:34 AM +
+ +
+ One really important thing that I would love to bring up before we dive deep into the philosophy questions is the distinction between Object-Oriented Programming (OOP) and Methods, and why I think this is at the heart of the discussion. + + (edited) +
+ + + + +
+
+
+
+
+
+
10:35
+
+ +
+ +
+ I'd argue that 99% of the reasons people want methods (and what many mean by "OOP" in a weird sense) are for the following reasons: + + (1) Organizing procedures under a data type + + (2) Allowing methods as a form syntactic sugar for writing calls in a subject verb object manner, e.g. do_thing(x, y) vs x.do_thing(y) + + (3) Searching for procedures/methods by a data type, especially with the aid of tools such as an IDE + +Regarding (1), I personally believe this is much better solved with a well designed package/module/library system as part of the language. Most OOP languages do not have such a system and usually use classes as a means to organize code. For my programming language Odin, packages have really aided us in terms of organization a lot better than + +Regarding (2), this is a weird linguistic typology thing which I doubt most people will even know unless they speak multiple languages. If you want to learn more about word orders in different languages, I recommend reading the following: + + * https://en.wikipedia.org/wiki/Subject%E2%80%93verb%E2%80%93object_word_order + * https://en.wikipedia.org/wiki/Verb%E2%80%93subject%E2%80%93object_word_order + + +Regarding (3), this is purely a tooling issue. It comes down to two main aspects: + + * Many people just want to use the tools that they have and how they currently work (there is nothing wrong with that, per se) + * Many people cannot think outside of the current paradigm and think what is being asked for is not possible + + +Doing foo. and waiting for the IDE to autocomplete what is available for that value of a specific data type is extremely useful to many people, but there is not reason it could not work for something that was purely procedural, it is that many languages nowadays do support some form of methods and thus the general need has not arisen. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 10:36 AM +
+ +
+ Like Common Lisp's generic methods. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 10:36 AM +
+ +
+ So in your opinion, is it not correct to say that "associating behavior with data" is essential to OOP, because all functions are associated with some form of data? (Regardless of syntax?) + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 10:37 AM +
+ +
+ "mere methods" (Lua is a good example of this, where they're just sugar for passing in the "subject" pointer) are IMO roughly analogous to for-loops or if-blocks, i.e. a syntactic standardization of a widespread common practice + +
+ + + + +
+
+
+
+
+
+
10:37
+
+ +
+ +
+ "procedural programming" could be seen as just standardizing a handful of assembly language idioms into language constructs + +
+ + + + +
+
+
+
+
+
+
10:37
+
+ +
+ +
+ "mere methods" are, for me, just more of this + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 10:38 AM +
+ +
+ they standardize the pattern
struct mything { + // whatever +} + +void mything_do_cool_stuff (struct mything *m, int x) { + // whatever +}
+ +
+ + + + +
+
+
+
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 10:38 AM +
+ +
+ I would agree with @demetrispanos and @gingerBill , methods as in the little . notation and OOP are independent concerns + +
+ + + + +
+
+
+
+ + + + + + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
demetrispanos
+
+ +they standardize the pattern
struct mything { + // whatever +} + +void mything_do_cool_stuff (struct mything *m, int x) { + // whatever +}
+ +
+
+
+ SirWhinesalot + + + 28-May-22 10:39 AM +
+ +
+ importantly, note how in the pattern above the function is not tied to struct, you can keep adding as many functions as you want + +
+ + + + +
+
+
+
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 10:39 AM +
+ +
+ in OOP, classes have a fixed set of methods, usually + +
+ + + + +
+
+
+
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
SirWhinesalot
+
+ +importantly, note how in the pattern above the function is not tied to struct, you can keep adding as many functions as you want + +
+
+
+ demetrispanos + + + 28-May-22 10:40 AM +
+ +
+ yes exactly, that's part of what I mean by "mere" (i.e. they're not wound up in some other concept like a class) + +
+ + + + +
+
+
+
+
+
+
+ Avatar +
+ +
+
+ gingerBill + + + 28-May-22 10:39 AM +
+ +
+ Lua is an example of something I'd like to call an Emergent OO Programming Language , but I'll leave that for a little later to reduce confusion. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ gingerBill + + + 28-May-22 10:40 AM +
+ +
+ Lua after all is a table oriented language. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 10:39 AM +
+ +
+ There's a few of those 😄 + +
+ + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
SirWhinesalot
+
+ +in OOP, classes have a fixed set of methods, usually + +
+
+
+ Kartik Agaram + + + 28-May-22 10:40 AM +
+ +
+ "open to extension" is another wonderful idea we should discuss at some point. ❤️ Ruby + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 10:40 AM +
+ +
+ Smalltalk as well + +
+ + + + +
+
+ 💡 + 1 +
+
+
+
+
+
+ + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
demetrispanos
+
+ +yes exactly, that's part of what I mean by "mere" (i.e. they're not wound up in some other concept like a class) + +
+
+
+ bvisness + + + 28-May-22 10:40 AM +
+ +
+ Would you elaborate on what extra ideas a "class" adds to the picture? + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 10:42 AM +
+ +
+ I'd say a "mere class" is a struct with a fixed set of "mere methods" (echoing some comments from above) + +
+ + + + +
+
+
+
+
+
+
10:42
+
+ +
+ +
+ but classes as practiced add more ideas like visibility, inheritance, etc. + +
+ + + + +
+
+
+
+
+
+
10:43
+
+ +
+ +
+ I'd note that while "mere methods" are IMO definitely useful, it's not clear to me what you get from a "mere class" + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 10:43 AM +
+ +
+ I think a mere class only becomes useful when subtype polymorphism is involved (i.e., a vtable of some sort) + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 10:43 AM +
+ +
+ ah yes, good point + +
+ + + + +
+
+
+
+
+
+
10:43
+
+ +
+ +
+ I agree + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 10:44 AM +
+ +
+ The evolution I tend to see is: +* Putting the primary data type first is a nice way to organize vocabularies in people's minds. (I think this is what y'all mean by "mere methods") +* Once you do that, you can also generalize and allow different types to do different things. That pulls in inheritance and static dispatch. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 10:45 AM +
+ +
+
* Putting the primary data type first is a nice way to organize vocabularies in people's minds. (I think this is what y'all mean by "mere methods") +
yes
+ +
+ + + + +
+
+
+
+
+
+
10:46
+
+ +
+ +
+ but importantly, the generalization of mere methods has consequences + +
+ + + + +
+
+
+
+
+
+
10:47
+
+ +
+ +
+ because the set of methods is usually fixed + +
+ + + + +
+
+
+
+
+
+
10:47
+
+ +
+ +
+ the moment you do so + +
+ + + + +
+
+
+
+
+
+
10:47
+
+ +
+ +
+ for implementation reasons + +
+ + + + +
+
+
+
+
+
+
10:47
+
+ +
+ +
+ there are alternative formulations but they tend to have severe performance penalties + +
+ + + + +
+
+
+
+
+
+
10:48
+
+ +
+ +
+ this is why I think mere methods and OOP are separate concerns. Having a nice . notation is one thing, introducing the extra machinery is another (and OOP only starts manifesting when the extra machinery comes into play) + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 10:50 AM +
+ +
+ I guess re: methods and subtypes, we should also mention prototype-style ideas because that gives a related view on what "mere classes" would do + +
+ + + + +
+
+
+
+
+
+
10:50
+
+ +
+ +
+ in self (https://en.wikipedia.org/wiki/Self_(programming_language)) you have the idea of a prototype as the unit of implementation delegation + +
+ + + + +
+
+
+
+
+
+
10:51
+
+ +
+ +
+ (and of course this carried over into the original version of Javascript OO) + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 10:52 AM +
+ +
+ Yeah. There's definitely class- and prototype-based OO out there. Also extensible vs closed to extension. + +Trying to demarcate precisely the boundaries of "OOP" might be a time sink. I'd much rather chop OOP up into its component pieces, and then we can discuss each separately. And then the question of, "is there anything we missed?" becomes fruitful. + +
+ + + + +
+
+
+
+
+
+
10:52
+
+ +
+ +
+ In a game you can have a performance-focused substrate that is closed to extension, and a command language like Lua that is open to extension. Both use OO ideas. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 10:52 AM +
+ +
+ I think it's important to address how people think about OO though + +
+ + + + +
+
+
+
+
+
+
10:53
+
+ +
+ +
+ because just chopping up the pieces leads to talking about various pieces in isolation and that's not what gets people confused (or irate) + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 10:53 AM +
+ +
+ Let's talk about some of those pieces though, because getting a more nuanced idea of them will allow us to come back to what does get people confused and irate + +
+ + + + +
+
+
+
+ + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
SirWhinesalot
+
+ +this is why I think mere methods and OOP are separate concerns. Having a nice . notation is one thing, introducing the extra machinery is another (and OOP only starts manifesting when the extra machinery comes into play) + +
+
+
+ bvisness + + + 28-May-22 10:54 AM +
+ +
+ I think we should start discussing this "extra machinery". I'm not sure what angle to discuss first; there's the more nuts-and-bolts ideas such as inheritance and polymorphism, but there's also the very hairy subject of object-oriented design. @SirWhinesalot is our point person for that, but I'd like to make sure we feel we've covered our bases first. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 10:55 AM +
+ +
+ Right, might be worth posting that meme making fun of GeeksForGeeks here 😄 + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 10:56 AM +
+ +
+ heh + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 10:56 AM +
+ +
+ So what we're talking about here is the idea that "OOP models the real world". + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 10:56 AM +
+ +
+ that's indeed the most important meme to address IMO + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 10:56 AM +
+ +
+ Should we tackle that now? or after we split OOP up first? + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 10:57 AM +
+ +
+ and it links up to almost everything else + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 10:57 AM +
+ +
+ Let's just get into it. + +
+ + + + +
+
+
+
+
+
+
10:57
+
+ +
+ +
+ We can branch from there into everything else, like Demetri says + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 10:57 AM +
+ +
+ What does it mean for OOP to model the real world? Here's what Wikipedia has to say (technically from the Domain-Driven Design page, but the two are intimately related): + +
In terms of object-oriented programming it means that the structure and language of software code (class names, class methods, class variables) should match the business domain. For example, if a software processes loan applications, it might have classes like LoanApplication and Customer, and methods such as AcceptOffer and Withdraw.
+ +
+ + + + +
+
+
+
+
+
+
10:57
+
+ +
+ +
+ I would like to focus on that Customer class. Think of a website like Amazon, what does a Customer do? They can login/logout, purchase items, review items, contact customer support, etc. They also have a lot of data about them like their user-info, preferences, purchases, support tickets, etc. + +
+ + + + +
+
+
+
+
+
+
10:58
+
+ +
+ +
+ What data and methods should the Customer class have? + +
+ + + + +
+
+
+
+
+
+
10:58
+
+ +
+ +
+ Really think about this and the consequences it has on the structure of the codebase. All of the above? Classes should have a "single-responsibility" (supposedly). What should the single responsibility of the Customer class be? + +
+ + + + +
+
+
+
+
+
+
10:58
+
+ +
+ +
+ You see how we immediatelly start getting into trouble? + +
+ + + + +
+
+ 😄 + 1 +
+
+
+
+
+
+
+
+
10:58
+
+ +
+ +
+ Then there's the issue of structuring your code into class hierarchies based on real-world concepts, e.g. Customer : Person, Seller : Person, Employee : Person. + +
+ + + + +
+
+
+
+
+
+
10:58
+
+ +
+ +
+ The problem of course is that the same person can not only be all three, they can be different subsets at different times! Even real-world taxonomies need to be updated from time to time, and this modeling style is imposing that kind of rigid structure, with far less certainty, on your data and behavior. + +
+ + + + +
+
+
+
+
+
+
10:59
+
+ +
+ +
+ This style is considered bad practice these days, but even without the taxonomy nonsense the core issue remains, which is trying to model real-world concepts as bundles of encapsulated data + behavior. It just doesn't work well in practice, that idea is the fundamental mistake. + +
+ + + + +
+
+
+
+
+
+
10:59
+
+ +
+ +
+ IMO of course + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 11:00 AM +
+ +
+ One wonderful book that made the rounds last year: https://buttondown.email/hillelwayne/archive/why-you-should-read-data-and-reality + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ gingerBill + + + 28-May-22 11:01 AM +
+ +
+ My personal view that thinking "OOP models the real world" is wrong because it is a category error. You cannot treat [programming objects] as "real objects" since "real objects" and "programming objects" have little connection to each other ontologically. This is why I've previously called OOP a form of misinterpreted and misapplied Aristotelian Metaphysics applied to a domain it was never meant to model[2]. + +By this statement, I mean that artificially conforming to any/all relations between data and types to an artificial hierarchy of agency is a form of naïve-Aristotelian metaphysics. Since there is no actual agency in the programming objects, it is a partial fallacy (and as previously stated, category error). When trying to conform a program to have a particular structure when it does not naturally, the absence of a structure in a program in more useful than a bad structure. + +[1] https://en.wikipedia.org/wiki/Category_mistake +[2] https://www.gingerbill.org/article/2020/05/31/progamming-pragmatist-proverbs/ + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 11:02 AM +
+ +
+ Map vs territory confusion, right? + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ gingerBill + + + 28-May-22 11:02 AM +
+ +
+ There is also the other aspect that in an actual Aristotelian metaphysics, an object can belong to an infinite amount of "classes" in any moment and even change depending on the situation. + +
+ + + + +
+
+
+
+
+
+
11:02
+
+ +
+ +
+ In a way, yes. + +
+ + + + +
+
+
+
+
+
+
11:03
+
+ +
+ +
+ When we discuss of an object, we are speaking of it about what is relevant to us in that situation. + +
+ + + + +
+
+
+
+
+
+
11:03
+
+ +
+ +
+ Let's take a random object off my table right now: a lens cap. + +
+ + + + +
+
+
+
+
+
+
11:03
+
+ +
+ +
+ A lens cap could be in the class of objects that cover a lens. + +
+ + + + +
+
+
+
+
+
+
11:03
+
+ +
+ +
+ But it could also be used a coaster for my drink. + +
+ + + + +
+
+
+
+
+
+
11:04
+
+ +
+ +
+ It could also be used as an eye patch. + +
+ + + + +
+
+ 🏴‍☠️ + 1 +
+
+
+
+
+
+
+
+
11:04
+
+ +
+ +
+ Or a weird weapon. + +
+ + + + +
+
+ 🗡️ + 1 +
+
+ ⚫ + 1 +
+
+ 📷 + 1 +
+
+
+
+
+
+
+
+
11:04
+
+ +
+ +
+ Or a one of an infinite number of things with infinite uses. + +
+ + + + +
+
+
+
+
+
+
11:04
+
+ +
+ +
+ The question is realizing what is relevant for the situation. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 11:05 AM +
+ +
+ Now you've got me thinking about what a computer that can fluidly move between ontologies would look like.. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ gingerBill + + + 28-May-22 11:06 AM +
+ +
+ This is why, in my personal opinion, a huge issue with force something to an "object"/"class"/etc has issues with. Things belong to more than just one class and trying to force it into one category can be very bad, especially when there is no "object" to speak of in the first place, only algorithms and data structures. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 11:06 AM +
+ +
+ The relational/logical model tends to be much better at this, since you can add/retract facts about an object + +
+ + + + +
+
+
+
+
+
+
11:06
+
+ +
+ +
+ Entity-Component Systems are a form of relational model btw + +
+ + + + +
+
+
+
+
+
+
11:06
+
+ +
+ +
+ Some people think they are a form of OO, that's incorrect + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 11:08 AM +
+ +
+ I think whether or not it is wrong, "OO solves problem by modeling the real world" is both believed and practiced, and indeed it is widely used to advertise and teach OO + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 11:08 AM +
+ +
+ Indeed, that's how I was taught in university + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 11:08 AM +
+ +
+ this is what I mean about talking about how people think about it + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 11:08 AM +
+ +
+ The best defense I've heard for OO design is to limit your ambitions to modeling solutions, not problems. That avoids the issues@gingerBill raises, but it's also a much more modest goal. OO design books seem to pay this idea lip service, but quickly go back to thinking symbols are the thing they represent. It's a very easy mental trap to fall into. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 11:09 AM +
+ +
+ modeling solutions is antithetical to OO-best practices (as taught), because the right solution often involves some sort of "Manager" class that handles the data, and these are "frowned upon" because they don't bundle the data and behavior + +
+ + + + +
+
+ 👍 + 2 +
+
+
+
+
+
+ + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
Kartik Agaram
+
+ +The best defense I've heard for OO design is to limit your ambitions to modeling solutions, not problems. That avoids the issues@gingerBill raises, but it's also a much more modest goal. OO design books seem to pay this idea lip service, but quickly go back to thinking symbols are the thing they represent. It's a very easy mental trap to fall into. + +
+
+
+ gingerBill + + + 28-May-22 11:10 AM +
+ +
+ The irony of that statement is that is kind of the opposite of the point. Programming is a form of problem solving. If you have already solved the problem, then redesigning it to be OOP is really weird, and borderline masturbation. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 11:10 AM +
+ +
+
limit your ambitions to modeling solutions, not problems. +
I would phrase this as "[90s style C++/Java] OO offers the ability to form hierarchies of data structures and functions but that this is usually misinterpreted to mean that it will be useful to model hierarchies of concepts in the world outside the program"
+ +
+ + + + +
+
+ 👍 + 1 +
+
+
+
+
+
+ + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
gingerBill
+
+ +The irony of that statement is that is kind of the opposite of the point. Programming is a form of problem solving. If you have already solved the problem, then redesigning it to be OOP is really weird, and borderline masturbation. + +
+
+
+ Kartik Agaram + + + 28-May-22 11:11 AM +
+ +
+ The idea is that once you've solved a problem, OO Design is a good way to continue to maintain the solution without forgetting why you did what you did. Software systems can last a long time! + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 11:12 AM +
+ +
+ I've found no advantage to an OO design vs any other form of design with a clear structure, unless the features provided by OO (like subtype polymorphism) were necessary + +
+ + + + +
+
+
+
+
+
+
11:12
+
+ +
+ +
+ In fact quite the opposite, since OO design can impose a lot of rigidity that is hard to get rid off + +
+ + + + +
+
+
+
+
+
+
11:13
+
+ +
+ +
+ See weird workaround like C# extension methods for an example + +
+ + + + +
+
+
+
+ + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
Kartik Agaram
+
+ +The idea is that once you've solved a problem, OO Design is a good way to continue to maintain the solution without forgetting why you did what you did. Software systems can last a long time! + +
+
+
+ gingerBill + + + 28-May-22 11:13 AM +
+ +
+ See the trick? If it needs to be continuously improved, it's not a solution, yet. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 11:13 AM +
+ +
+ I would say I almost never use inheritance, but I almost always use methods + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 11:13 AM +
+ +
+ and if someone told me I could never use inheritance again I would not consider it a big loss + +
+ + + + +
+
+
+
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 11:13 AM +
+ +
+ I'm actually not familiar with any non-OO design methodology 😄 They kinda sucked the oxygen out of the room, didn't they? + +
+ + + + +
+
+
+
+ + + + + + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
Kartik Agaram
+
+ +I'm actually not familiar with any non-OO design methodology 😄 They kinda sucked the oxygen out of the room, didn't they? + +
+
+
+ SirWhinesalot + + + 28-May-22 11:14 AM +
+ +
+ there are many architectures you can use. Things like publish/subscribe, model-view-update, etc. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 11:14 AM +
+ +
+ Certainly though the term "design patterns" has come to exclusively mean "object-oriented design patterns", and really the gang of four stuff + +
+ + + + +
+
+
+
+ + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
Kartik Agaram
+
+ +I'm actually not familiar with any non-OO design methodology 😄 They kinda sucked the oxygen out of the room, didn't they? + +
+
+
+ gingerBill + + + 28-May-22 11:14 AM +
+ +
+ "JUST SOLVE THE PROBLEM YOU HAVE" is my preferred one. + +
+ + + + +
+
+ 💯 + 7 +
+
+
+
+
+
+ + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
bvisness
+
+ +Certainly though the term "design patterns" has come to exclusively mean "object-oriented design patterns", and really the gang of four stuff + +
+
+
+ bvisness + + + 28-May-22 11:15 AM +
+ +
+ and that persists to this day, thanks probably to universities? + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 11:15 AM +
+ +
+ yes I think the fact that OO has the superficial appearance of a "theory of programming" is important here + +
+ + + + +
+
+
+
+
+
+
11:15
+
+ +
+ +
+ (re: universities) + +
+ + + + +
+
+
+
+ + + + + + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 11:15 AM +
+ +
+ universities had rapidly increasing needs to "produce programmers" but universities loathe doing anything that might look like vocational school + +
+ + + + +
+
+
+
+
+
+
11:16
+
+ +
+ +
+ OOP looked like it had some ideas from type theory, had some kind of taxonomy scheme, had some claims to provable properties + +
+ + + + +
+
+
+
+
+
+
11:16
+
+ +
+ +
+ and so it was compatible with what a university might be persuaded to adopt + +
+ + + + +
+
+
+
+
+
+
11:17
+
+ +
+ +
+ and it also had the claim of "intuitively models the real world, so businesses like it" + +
+ + + + +
+
+ 💡 + 1 +
+
+
+
+
+
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 11:15 AM +
+ +
+ https://en.wikipedia.org/wiki/Software_design does have a list. I guess I'm not aware of it because I don't do design 😅 + +
+ + +
+
+ +
+
+
+ + + +
+
Software design is the process by which an agent creates a specification of a software artifact intended to accomplish goals, using a set of primitive components and subject to constraints. Software design may refer to either "all the activity involved in conceptualizing, framing, implementing, commissioning, and ultimately modifying complex sys...
+
+ +
+ +
+ + +
+
+ + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 11:18 AM +
+ +
+ My university thankfully presented all paradigms (procedural, oo, functional, logical) + +
+ + + + +
+
+
+
+
+
+
11:19
+
+ +
+ +
+ a good question there is if OO is an actual paradigm + + (edited) +
+ + + + +
+
+
+
+
+
+
11:19
+
+ +
+ +
+ Alan Kay certainly thought so, but Smalltalk OO is a very different beast from C++ or Java or whatever + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 11:20 AM +
+ +
+ I think Kay has sufficiently lost that battle that there's not much point talking about it as a peer + +
+ + + + +
+
+
+
+
+
+
11:20
+
+ +
+ +
+ when I want to talk about his stuff I say "Kay style OO" or "message passing OO" + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 11:22 AM +
+ +
+ I personally think Kay-style OO could be seen as a unique programming paradigm (when you include the full reflexivity and the IDE as the OS sort of programming style Smalltalk has), but regular OO is not, it's just procedural programming with a pointless structure on top + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 11:22 AM +
+ +
+ the folk understanding of OO, which IMO is like 90+% of people, is something like +- your program is a collection of classes +- one class per file +- each class represents some concept from the real world +- each class has a single responsibility (this is at odds with above but whatever :P) +- there are "good patterns" of assembling classes into programs to solve problems + + (edited) +
+ + + + +
+
+ 💯 + 1 +
+
+
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ gingerBill + + + 28-May-22 11:23 AM +
+ +
+ I (luckily?) don't have any programming education, let alone academic, so I cannot comment on what is or what is not taught commonly in Universities beyond what I have heard. From what I can tell, they seem to vary extremely widely compared to say harder science such as Physics or Chemistry. If you go to one University for Physics, it'll be similar enough to another. But for Computer Science (Infomatics), it will be very very different + +
+ + + + +
+
+ 👍 + 1 +
+
+
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 11:23 AM +
+ +
+ Among other critiques, this approach causes some blind spots because you get trained to think in terms of nouns and deemphasize verbs: http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 11:24 AM +
+ +
+ yes, a very important essay in this history + + (edited) +
+ + + + +
+
+
+
+ + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
Kartik Agaram
+
+ +Among other critiques, this approach causes some blind spots because you get trained to think in terms of nouns and deemphasize verbs: http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html + +
+
+
+ bvisness + + + 28-May-22 11:24 AM +
+ +
+ I love that post. When Demetri showed it to me for the first time years ago, I was shocked by how much it resonated with me + +
+ + + + +
+
+
+
+
+
+
11:25
+
+ +
+ +
+ This seems like as good a time as any for Demetri to talk about Java and what it did to the world of software + +
+ + + + +
+
+
+
+
+
+
11:25
+
+ +
+ +
+ which he volunteered to do as someone who lived through the Great Javafication + +
+ + + + +
+
+
+
+
+
+
11:31
+
+ +
+ +
+ To give some context for that, though, my understanding is that Java really took over the software industry in the mid-90s for a variety of reasons I'm not entirely familiar with + +
+ + + + +
+
+
+
+
+
+
11:31
+
+ +
+ +
+ He talked about it some on our podcast episode about programming education, as I recall (https://handmade.network/podcast/ep/eeac46c9-5e90-4b1c-9104-cff49734764d) + +
+ + + + +
+
+
+
+
+
+
11:32
+
+ +
+ +
+ And much of what he laid out in his "folk understanding of OO" above is, as far as I know, a direct line from Java + +
+ + + + +
+
+
+
+
+
+
11:32
+
+ +
+ +
+ for example, one class per file + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 11:34 AM +
+ +
+ Java uses classes for everything. Namespacing, modeling the solution, modeling the world, file system organization... + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 11:34 AM +
+ +
+ Yes I believe other languages aren't as restrictive, but the pattern is visible in a lot of C# codebases for example + + (edited) +
+ + + + +
+
+
+
+
+
+
11:34
+
+ +
+ +
+ one file per class + +
+ + + + +
+
+
+
+
+
+
11:34
+
+ +
+ +
+ because they sort of act like modules as well, specially when it's a "static" class with "static" methods + +
+ + + + +
+
+
+
+
+
+
11:35
+
+ +
+ +
+ (read: a bog standard procedural thing with extra keywords) + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 11:36 AM +
+ +
+ Java was the first "real" programming language I learned, and it took me a long time to broaden my understanding enough to unlearn a lot of the decisions it made. static is certainly an example of that; a great way to obscure a very obvious concept. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 11:37 AM +
+ +
+ It was the first question I asked my teacher: "What does static mean?" + +
+ + + + +
+
+
+
+
+
+
11:37
+
+ +
+ +
+ I had been exposed to Pascal before, but not in an educational setting + +
+ + + + +
+
+
+
+
+
+
11:37
+
+ +
+ +
+ So public static void main() inside a class was very confusing + +
+ + + + +
+
+
+
+
+
+
11:38
+
+ +
+ +
+ Btw his answer was "I'll explain that by the end" + +
+ + + + +
+
+
+
+
+
+
11:38
+
+ +
+ +
+ "Ignore it for now, just know it needs to be there" + +
+ + + + +
+
+
+
+
+
+
11:38
+
+ +
+ +
+ never a good start + +
+ + + + +
+
+
+
+
+
+
11:40
+
+ +
+ +
+ it was much worse for my partner, her teacher decided explaining the difference between static and non-static was a great discussion topic for class 2 of newbie bioinformatics learning to program + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 11:40 AM +
+ +
+ static is a great scapegoat example for the problems with Java's design decisions, but I suspect there is a lot more to it than that + +
+ + + + +
+
+
+
+
+
+
11:41
+
+ +
+ +
+ For example, I'm curious if from @demetrispanos's perspective, the design of Java's standard library had an impact here (or if that was just an outflow of the language design) + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 11:42 AM +
+ +
+ the standard library specifically, I'm not sure ... though Java definitely pioneered the idea that the standard library would have a canned solution for almost everything + +
+ + + + +
+
+
+
+
+
+
11:42
+
+ +
+ +
+ I remember buying "Java in a Nutshell" in the late 90s and being genuinely shocked at its size + +
+ + + + +
+
+
+
+
+
+
11:42
+
+ +
+ +
+ I think the large standard library overlapped with the idea of programs as "connecting objects to each other" + + (edited) +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 11:43 AM +
+ +
+ Well perhaps it would be best to just step back then and talk about the shift you saw in the industry when Java hit the scene + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 11:44 AM +
+ +
+ Java was the front runner but C++ in the 90s was also a major participant (indeed Design Patterns came from the C++ community) + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 11:45 AM +
+ +
+ Also Smalltalk! + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 11:45 AM +
+ +
+ I think the biggest change was just how much marketing effort was behind "90s OOP", led primarily by Java (in terms of marketing) + +
+ + + + +
+
+
+
+
+
+
11:46
+
+ +
+ +
+ Java promised everybody a pony + +
+ + + + +
+
+
+
+
+
+
11:46
+
+ +
+ +
+ universities got to teach a thing that looked like a theory of programming + +
+ + + + +
+
+
+
+
+
+
11:46
+
+ +
+ +
+ businesses got programmers that could program in "intuitive real world concepts" + +
+ + + + +
+
+
+
+
+
+
11:46
+
+ +
+ +
+ new programmers were told they didn't have to worry about details their predecessors used to sweat over, and could just draw object/class hierarchy diagrams + +
+ + + + +
+
+
+
+
+
+
11:47
+
+ +
+ +
+ (there were also other Java promises re: security and portability that aren't relevant here) + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 11:48 AM +
+ +
+ I wonder how much of Java being OO was because of the marketing efforts predating it.. 🤔 + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 11:48 AM +
+ +
+ well, to ask a question I think I know the answer to...how did Java live up to the hype :) + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 11:48 AM +
+ +
+ I think Gosling definitely saw himself as successor to Bjarne who was successor to Ritchie etc. + +
+ + + + +
+
+
+
+
+
+
11:49
+
+ +
+ +
+ and indeed Java was conceptualized as a kind of "C++, the good parts" + +
+ + + + +
+
+
+
+
+
+
11:49
+
+ +
+ +
+ and it's telling what they thought were "the good parts" + +
+ + + + +
+
+
+
+
+
+
11:49
+
+ +
+ +
+ class hierarchies + +
+ + + + +
+
+
+
+
+
+
11:49
+
+ +
+ +
+ you don't just have the option of classes, everything is a class (even your program itself) + +
+ + + + +
+
+
+
+
+
+
11:50
+
+ +
+ +
+ I would say that by the end of the 90s the thing we now know as "Java/C++ OOP" was cemented as the responsible way to write software + +
+ + + + +
+
+
+
+
+
+
11:51
+
+ +
+ +
+ or rather, cemented the reputation as such + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 11:51 AM +
+ +
+ One reason it took so long to notice that OO didn't always work well, was that it worked best in the lower levels where people designed and implemented languages like Java. After they put in all the effort to build the language over a decade, it took a decade of using OO methodologies in anger to crystallize its limitations. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 11:51 AM +
+ +
+ well also it genuinely did work reasonably well with widget hierarchies in GUIs + +
+ + + + +
+
+ 👍 + 1 +
+
+
+
+
+
+
+
+
11:52
+
+ +
+ +
+ but that was IMO an accident of overlap between problem and solution domain + +
+ + + + +
+
+
+
+
+
+
11:52
+
+ +
+ +
+ the widgets are code objects, and having hierarchies of code objects is something that OOP delivers as it says on the tin + +
+ + + + +
+
+
+
+
+
+
11:52
+
+ +
+ +
+ and indeed "textbox with a slider" is a reasonable conceptual descendant of "plain textbox" + +
+ + + + +
+
+
+
+
+
+
11:53
+
+ +
+ +
+ so I think many people saw that there was a good solution for an ascendant problem (the 90s saw the rise of GUIs to dominance) + +
+ + + + +
+
+
+
+
+
+
11:53
+
+ +
+ +
+ and they figured this would just be the first major success of many + +
+ + + + +
+
+
+
+
+
+
11:54
+
+ +
+ +
+ but widget hierarchies are much more usefully modeled by OOP than, say, customer/person hierarchies + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 11:55 AM +
+ +
+ That might be an interesting example to break down further + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 11:55 AM +
+ +
+ (Except when widgets used inner classes. That was a whole other can of worms..) + +
+ + + + +
+
+
+
+ + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
demetrispanos
+
+ +but widget hierarchies are much more usefully modeled by OOP than, say, customer/person hierarchies + +
+
+
+ SirWhinesalot + + + 28-May-22 11:56 AM +
+ +
+ Important to note here that UI frameworks moved away from "Split button inherits from Button" to "Split button is a button with a nested dropdown and a vertical line", you see that shift with the introduction of WPF at least + +
+ + + + +
+
+
+
+
+
+
11:57
+
+ +
+ +
+ so the move away from inheritance to composition was definitely ongoing in the 2000s + +
+ + + + +
+
+ 👍 + 1 +
+
+
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 11:57 AM +
+ +
+ yeah this is what I meant by "reasonably well", i.e. it was better than no organization at all but didn't end up being the one abstraction to rule all of GUI + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 11:58 AM +
+ +
+ I do think it's interesting though that it was still a more effective model than what you tend to see elsewhere. @Kartik Agaram and @SirWhinesalot talked in the planning doc about objects needing to belong to the "solution domain", not the "problem domain", and this feels like a similar situation to me + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 11:59 AM +
+ +
+ One thing I still grapple with is that it's easier to use computers to talk about computers than it is to do something useful. That leads to all our yak shaving and abstraction-tower-building tendencies. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 12:01 PM +
+ +
+ Yeah, OO is a rather natural way to model GUIs (not necessarily the only way, nor the best), but it works. A button has some internal state, it responds to some events, those events are shared between all kinds of GUI entities. A "Widget" interface that gets implemented by many different Widget classes is a rather obvious way to model this + +
+ + + + +
+
+
+
+
+
+
12:02
+
+ +
+ +
+ even in languages without native OO support + +
+ + + + +
+
+
+
+
+
+
12:02
+
+ +
+ +
+ See COM or GTK in C for examples + +
+ + + + +
+
+
+
+ + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
bvisness
+
+ +I do think it's interesting though that it was still a more effective model than what you tend to see elsewhere. @Kartik Agaram and @SirWhinesalot talked in the planning doc about objects needing to belong to the "solution domain", not the "problem domain", and this feels like a similar situation to me + +
+
+
+ Kartik Agaram + + + 28-May-22 12:02 PM +
+ +
+ That HN comment (https://news.ycombinator.com/item?id=785601#785833) actually hit me like a pile of bricks. Until then I'd only heard that you used inheritance to model is-a relationships, then wandered off because that seemed to suck. + +
+ + +
+
+ +
+ + + + +
+
+ + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:02 PM +
+ +
+ yes how many times has a junior programmer agonized over "is-a" vs "has-a" + +
+ + + + +
+
+
+
+ + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
demetrispanos
+
+ +yes how many times has a junior programmer agonized over "is-a" vs "has-a" + +
+
+
+ bvisness + + + 28-May-22 12:03 PM +
+ +
+ I did this for years + +
+ + + + +
+
+
+
+
+
+
12:03
+
+ +
+ +
+ and it was a meaningless question + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:03 PM +
+ +
+ yeah and the memeplex around 90s OOP invites that activity + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:03 PM +
+ +
+ it very strongly implies that this is what you should do + +
+ + + + +
+
+ 👍 + 1 +
+
+
+
+
+
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 12:03 PM +
+ +
+ interface vs implementation inheritance. And then I find that in practice, all inheritance is good for is sharing code. + + (edited) +
+ + + + +
+
+
+
+ + + + + + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
bvisness
+
+ +and it was a meaningless question + +
+
+
+ SirWhinesalot + + + 28-May-22 12:04 PM +
+ +
+ meaningless but unfortunately very critical if you're in an OO language + +
+ + + + +
+
+
+
+
+
+
12:04
+
+ +
+ +
+ because the decision is one you're mostly stuck with + +
+ + + + +
+
+
+
+
+
+
12:04
+
+ +
+ +
+ without a major rewrite + +
+ + + + +
+
+
+
+ + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
SirWhinesalot
+
+ +meaningless but unfortunately very critical if you're in an OO language + +
+
+
+ bvisness + + + 28-May-22 12:04 PM +
+ +
+ this I would say is a strong Java-ism + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 12:05 PM +
+ +
+ In practice, why is a relationship between two concepts being model as a language feature? + +
+ + + + +
+
+
+
+
+
+
12:05
+
+ +
+ +
+ There's absolutely no reason for this + + (edited) +
+ + + + +
+
+
+
+
+
+
12:05
+
+ +
+ +
+ I can model that A is a B in 1000 ways + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:05 PM +
+ +
+ well, the dirty secret is that it's not + +
+ + + + +
+
+
+
+
+
+
12:05
+
+ +
+ +
+ there is not even an attempt at it + +
+ + + + +
+
+
+
+
+
+
12:05
+
+ +
+ +
+ all that is attempted is sharing implementation details with ancestors + +
+ + + + +
+
+
+
+
+
+
12:06
+
+ +
+ +
+ the language never engages with whether the alleged is-a relationship is valid + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 12:06 PM +
+ +
+ true, you actually have to be careful to ensure an A is actually a B + +
+ + + + +
+
+
+
+
+
+
12:06
+
+ +
+ +
+ in fact traps like that are typical exam questions + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:06 PM +
+ +
+ the is-a aspect is entirely in people's minds + +
+ + + + +
+
+ ☝️ + 2 +
+
+
+
+
+
+
+
+
12:06
+
+ +
+ +
+ the thing that exists in the material world is sharing code + +
+ + + + +
+
+ 💯 + 2 +
+
+
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 12:06 PM +
+ +
+ which is much better done with before/after advice or hooks that receive anonymous functions + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 12:08 PM +
+ +
+ When teaching my FIRST robotics students, I've struggled in the past with better examples to illustrate how inheritance works in Java than the classic "Cat is-a Animal" thing, and I suppose that's largely because inheritance isn't actually very good at modeling anything practical + +
+ + + + +
+
+
+
+
+
+
12:08
+
+ +
+ +
+ but the concept must be taught if we are to use the language + +
+ + + + +
+
+
+
+
+
+
12:08
+
+ +
+ +
+ (we no longer use the language) + +
+ + + + +
+
+ 👍 + 2 +
+
+
+
+
+
+ + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
demetrispanos
+
+ +yes how many times has a junior programmer agonized over "is-a" vs "has-a" + +
+
+
+ bvisness + + + 28-May-22 12:09 PM +
+ +
+ One other aspect of OOP I think might be worth exploring is the idea of "agency" of objects, which "has-a" gets into + +
+ + + + +
+
+
+
+
+
+
12:09
+
+ +
+ +
+ I'm not sure if we've really touched on that yet + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 12:09 PM +
+ +
+ perhaps in passing but we haven't deep dived on it + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 12:10 PM +
+ +
+ This also relates in my mind to the actor model and perhaps the talk @Kartik Agaram mentioned by Richard Feldman about how OOP design makes each object a "small computer" on its own + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:11 PM +
+ +
+ I might say "small machine" but yes, and indeed this is the origin in Simula + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 12:11 PM +
+ +
+ This is to me different from the taxonomy issue + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 12:11 PM +
+ +
+ indeed, separate concern + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:11 PM +
+ +
+ the execution of the program is a simulation of many independent machines doing things to each other + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 12:12 PM +
+ +
+ this is "OOP as a model of computation" + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 12:13 PM +
+ +
+ With hindsight, the question I'm left with is, why did anyone ever consider this a good thing. Alan Kay made the analogy with biological cells in http://gagne.homedns.org/~tgagne/contrib/EarlyHistoryST.html#4, but back then (i.e. until the 90s when I started programming) we all assumed that was a good thing. + +
+ + + + +
+
+ ☝️ + 1 +
+
+
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:14 PM +
+ +
+ I think it became popular because of the idea that you'd use "code objects" the same way you use, say, screws from Home Depot + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 12:14 PM +
+ +
+ ah yes, software components. The ubiquitous siren of lego blocks. + +
+ + + + +
+
+ legobrick + 1 +
+
+
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:14 PM +
+ +
+ starting a new blog engine? go get some XYZ database screws and some PQR rendering bolts and you're 90% done + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 12:14 PM +
+ +
+ one important distinction between the smalltalk view (that affects how "good" it is) is the fact that objects are "live". You're not describing a simulation in terms of a software description of communicating objects (as in Java or C++), but actually witnessing the objects interact and changing their behavior as appropriate + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:15 PM +
+ +
+ this always felt like Alan Kay marketing speak to me + +
+ + + + +
+
+
+
+
+
+
12:15
+
+ +
+ +
+ databases are similarly "alive" in that the tables change with each insert + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 12:16 PM +
+ +
+ live editing is also not dependent on any sort of "object" 🙂 + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:16 PM +
+ +
+ Kay is a very creative guy, but he is also easily tempted by marketing language + +
+ + + + +
+
+
+
+
+
+
12:16
+
+ +
+ +
+ (this is fine, good ideas need marketing) + +
+ + + + +
+
+
+
+
+
+
12:16
+
+ +
+ +
+ anyway, it is indeed important to address OOP and the subject of software components/reuse + +
+ + + + +
+
+
+
+
+
+
12:17
+
+ +
+ +
+ because it definitely was perceived as the way to achieve the latter + +
+ + + + +
+
+
+
+
+
+
12:17
+
+ +
+ +
+ you no longer would do the "unimportant" "tedious" work of writing a string formatting function, you'd just use a java.util.StringFormatter + +
+ + + + +
+
+
+
+
+
+
12:17
+
+ +
+ +
+ (I don't know if that exists, it probably doesn't) + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 12:18 PM +
+ + + + + + +
+
+
+
+
+
+
12:18
+
+ +
+ +
+ so close 🙂 + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:18 PM +
+ +
+ and this overlaps with Java's enormous standard library, because it was meant to be analogous to walking into Home Depot and getting the screws you need + +
+ + + + +
+
+
+
+
+
+
12:18
+
+ +
+ +
+ haha closer than I thought + +
+ + + + +
+
+
+
+
+
+
12:18
+
+ +
+ +
+ importantly, I never saw any kind of argument for why an "object" would be more reusable than a function + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:18 PM +
+ +
+ but it was widely believed to be the case + +
+ + + + +
+
+
+
+
+
+
12:19
+
+ +
+ +
+ and that was a big part of the Java marketing agenda + +
+ + + + +
+
+
+
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 12:18 PM +
+ +
+ but again, this has nothing to do with objects, a module will do just fine for this purpose + +
+ + + + +
+
+
+
+
+
+
12:18
+
+ +
+ +
+ yup + +
+ + + + +
+
+
+
+ + + + + + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 12:19 PM +
+ +
+ the only case I can see for it is when the object is "live", meaning you acquire the object already in the state you want, but that's a big stretch + +
+ + + + +
+
+
+
+
+
+
12:19
+
+ +
+ +
+ why not just... configure the thing? + +
+ + + + +
+
+
+
+
+
+
12:19
+
+ +
+ +
+ was never clear either + +
+ + + + +
+
+
+
+
+
+
12:20
+
+ +
+ +
+ specially not in a Java like language where Classes may as well be modules with extra steps + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:20 PM +
+ +
+ yes and actually you can see some of this in how Python played out, because it was very oriented toward modules + +
+ + + + +
+
+
+
+
+
+
12:20
+
+ +
+ +
+ but then got a large influx of what I'll uncharitably call "java refugees" in the mid 00s + +
+ + + + +
+
+
+
+
+
+
12:21
+
+ +
+ +
+ and suddenly you started seeing a lot of python that looked like java + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 12:21 PM +
+ +
+ Reuse does feel like an idea important enough to be worth trying for a couple of decades. I'm glad we're past it now. At least for some people today, a library you can reuse registers as more liability than asset. Now you gotta wire it into your supply chain and watch out for vulnerabilities. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
Kartik Agaram
+
+ +Reuse does feel like an idea important enough to be worth trying for a couple of decades. I'm glad we're past it now. At least for some people today, a library you can reuse registers as more liability than asset. Now you gotta wire it into your supply chain and watch out for vulnerabilities. + +
+
+
+ bvisness + + + 28-May-22 12:22 PM +
+ +
+ It does feel like that's the trend, thankfully, but I suspect the dream of perfect reuse will never die out + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:22 PM +
+ +
+ I think the reuse concern is largely mercenary + +
+ + + + +
+
+
+
+
+
+
12:22
+
+ +
+ +
+ I mean it's mainly something businesses care about to reduce costs + +
+ + + + +
+
+
+
+
+
+
12:22
+
+ +
+ +
+ this is fine, keeping costs low is a reasonable concern + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 12:23 PM +
+ +
+ The key for me is to minimize zones of ownership. Reuse makes most sense when a vocabulary of components was coherently designed to compose well. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:23 PM +
+ +
+ but I don't think it's ultimately a deep concern about quality of code (even if it overlaps with quality concerns like single-point-of-truth) + +
+ + + + +
+
+
+
+
+
+
12:24
+
+ +
+ +
+ I want to distinguish between "reuse" and just "use by someone else" + +
+ + + + +
+
+
+
+
+
+
12:24
+
+ +
+ +
+ because I think they're conflated, but really only the second thing matters in most cases + +
+ + + + +
+
+
+
+
+
+
12:24
+
+ +
+ +
+ if I write the postgres database engine, what's important is that many people can use it (and not write their own) + +
+ + + + +
+
+
+
+
+
+
12:24
+
+ +
+ +
+ what's not important is that it can be used to make a substantially different database engine + +
+ + + + +
+
+
+
+
+
+
12:24
+
+ +
+ +
+ but that's the "just like screws" idea + +
+ + + + +
+
+
+
+
+
+
12:25
+
+ +
+ +
+ the same screws can make a table or a bookshelf etc. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 12:26 PM +
+ +
+ Do you think object-oriented design is worse at providing reuse than other approaches, or just completely unrelated? + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 12:26 PM +
+ +
+ one are where OOP matters for reuse is the idea of an interface that can be implemented in many different ways + +
+ + + + +
+
+
+
+
+
+
12:26
+
+ +
+ +
+ it sets a boundary between parts of the code + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 12:26 PM +
+ +
+ I think OOP tilted harder at that particular problem. Making it easier to build things that you can reuse with anything else. It failed, but that's ok. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:26 PM +
+ +
+ I would hesitate to attribute interfaces to any particular discipline + +
+ + + + +
+
+
+
+ + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
bvisness
+
+ +Do you think object-oriented design is worse at providing reuse than other approaches, or just completely unrelated? + +
+
+
+ demetrispanos + + + 28-May-22 12:27 PM +
+ +
+ I think it is in practice worse because it forces you to buy into the author's specific set of branded lego pieces that don't quite fit anyone else's + +
+ + + + +
+
+
+
+
+
+
12:27
+
+ +
+ +
+ in my experience the things that are easiest to glue together have extremely simple and unopinionated representations + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:28 PM +
+ +
+ but if you have to instantiate an object from some complex hierarchy merely to get started, you have a lot of friction + +
+ + + + +
+
+
+
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 12:28 PM +
+ +
+ It seems to me that easy reuse is in direct conflict with ideas of taxonomy and ownership and agency + + (edited) +
+ + + + +
+
+
+
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:28 PM +
+ +
+ the unix way is "almost everything is lines of text, and you have to parse them" + +
+ + + + +
+
+
+
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:28 PM +
+ +
+ it's annoying, but easy to glue together + + (edited) +
+ + + + +
+
+
+
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
bvisness
+
+ +Do you think object-oriented design is worse at providing reuse than other approaches, or just completely unrelated? + +
+
+
+ gingerBill + + + 28-May-22 12:28 PM +
+ +
+ So this depends. Most traditonal inheritance based OOP are worse than plain procedural, but something like Go's implicit interfaces (which some don't even call OOP) is a lot more reusable. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
gingerBill
+
+ +So this depends. Most traditonal inheritance based OOP are worse than plain procedural, but something like Go's implicit interfaces (which some don't even call OOP) is a lot more reusable. + +
+
+
+ gingerBill + + + 28-May-22 12:28 PM +
+ +
+ The big issue is that Go's interfaces require GC and have many performance issues. + +
+ + + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 12:29 PM +
+ +
+ as @skejeton was getting at in #fishbowl-audience, a table doesn't own a screw, a table leg doesn't own a screw, they're just all there + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:29 PM +
+ +
+ the C way is "almost everything is arrays of a few machine-type primitives" + +
+ + + + +
+
+
+
+
+
+
12:29
+
+ +
+ +
+ and that too has proven to be a very productive way to glue things together, as it is the basis of almost every practical FFI design + +
+ + + + +
+
+
+
+
+
+
12:29
+
+ +
+ +
+ the web way is "almost everything is JSON" + +
+ + + + +
+
+
+
+
+
+
12:29
+
+ +
+ +
+ and again, that is easy to glue together + +
+ + + + +
+
+
+
+
+
+
12:30
+
+ +
+ +
+ Java attempted "amost everything is XML" but it rightfully went up in flames + +
+ + + + +
+
+
+
+
+
+
12:30
+
+ +
+ +
+ because XML has many of the same problems vs JSON as Java OOP vs procedural + +
+ + + + +
+
+
+
+
+
+
12:31
+
+ +
+ +
+ JSON makes no pretense of modeling the real world, it's just a record + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 12:32 PM +
+ +
+ rich hickey goes into this on why systems level concerns are different from application level concerns, and the data exchange between "processes" or "entities" in a system should be very "loose" + +
+ + + + +
+
+
+
+
+
+
12:32
+
+ +
+ +
+ it's why unix has just strings, or the web has json everywhere + +
+ + + + +
+
+
+
+
+
+
12:33
+
+ +
+ +
+ this is also why stuff like dependency injection frameworks exist, their job is to set up the "wiring" between various components, which gets more and more complicated the more detailed the interface specification they have to communicate is + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 12:35 PM +
+ +
+ Complexity feels like something worth talking about head on. A lot of our discussion has had it implicitly in the background. The promise of many languages/tools/paradigms is "treat complexity as an externality. Infinite scale!" This never bears out, and lately I consider it a bad direction. Why is it so important to be able to scale up in complexity? + +Oh wait, where am I, this is Handmade Network. I'm preaching to the choir 😅 + +
+ + + + +
+
+
+
+ + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
Kartik Agaram
+
+ +Complexity feels like something worth talking about head on. A lot of our discussion has had it implicitly in the background. The promise of many languages/tools/paradigms is "treat complexity as an externality. Infinite scale!" This never bears out, and lately I consider it a bad direction. Why is it so important to be able to scale up in complexity? + +Oh wait, where am I, this is Handmade Network. I'm preaching to the choir 😅 + +
+
+
+ bvisness + + + 28-May-22 12:37 PM +
+ +
+ Well on that note, another thing that I had on my list was the idea that OOP allows you to scale up development and solve more complex problems. One of the links you posted during planning directly stated this exact idea. But...is there any merit to that idea at all? + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 12:38 PM +
+ +
+ Was that perhaps just an accident of all the other things Java provided out of the box? + +
+ + + + +
+
+
+
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 12:38 PM +
+ +
+ Namespacing does help. + +
+ + + + +
+
+
+
+ + + + + + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 12:39 PM +
+ +
+ I think a lot of these ideas do help. Perhaps it's a matter of setting expectations. "This is awesome, rock out with it!" vs "You're trying to do something really hard, this thing will help mitigate the pain." + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 12:40 PM +
+ +
+ I now see that my prep notes actually say "OOP allows us to write larger programs" and that is definitely true troll + + (edited) +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 12:41 PM +
+ +
+ breaking down systems into components definitely helps with scaling things up, this is done all the time in hardware land, but components are not objects + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:41 PM +
+ +
+ I think the steelman version of this argument goes like this +1. OOP encourages you to assemble your program from many small objects, one per file +2. since each object has a single responsibility, individual changes that happen in the future usually belong in only one file +3. so even if you have 10k class files, only one matters at any given time +4. so you can scale your classes across your people + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 12:42 PM +
+ +
+ that's among the weaker steelmans I've seen + +
+ + + + +
+
+ 😂 + 1 +
+
+
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:42 PM +
+ +
+ and this is mostly true for changes like "instead of saying Hello Newcomer, it should say Howdy Stranger when the player logs in" + +
+ + + + +
+
+ 💯 + 1 +
+
+
+
+
+
+ + + + + + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:42 PM +
+ +
+ you look up the PlayerGreeter.java + +
+ + + + +
+
+
+
+
+
+
12:42
+
+ +
+ +
+ you change the greeting + +
+ + + + +
+
+
+
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 12:42 PM +
+ +
+ I do often find myself needing to modify multiple classes/files in a single tiny commit. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 12:43 PM +
+ +
+ For a while I used to have my build script show me the average number of files modified in the last 10 commits. That did give an interesting sort of peripheral awareness. + +
+ + + + +
+
+ 🤔 + 1 +
+
+
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 12:44 PM +
+ +
+ one thing that's important to note is that OOP makes changing the architecture rather hard, i.e. since objects store their references to other objects, you have to jump around everywhere to change things + +
+ + + + +
+
+
+
+
+
+
12:44
+
+ +
+ +
+ if you try to avoid this by using some pattern where an "upper level" object sets everything up + +
+ + + + +
+
+
+
+
+
+
12:44
+
+ +
+ +
+ you end up with way too much argument passing to constructors + +
+ + + + +
+
+
+
+
+
+
12:44
+
+ +
+ +
+ which, in turn, leads to awful dependency injection frameworks + +
+ + + + +
+
+
+
+
+
+
12:45
+
+ +
+ +
+ in most component-based design systems for hardware, the connections between the components are a directly editable thing + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 12:45 PM +
+ +
+ 💯 But then doesn't everything? I define architecture as "that which is hard to change." + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 12:45 PM +
+ +
+ That feels like it's mostly caused by the inheritance / taxonomy / hierarchy kinds of design problems we were talking about before + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 12:46 PM +
+ +
+ even with composition it's an issue, because of how communication between objects occurs + +
+ + + + +
+
+
+
+
+
+
12:46
+
+ +
+ +
+ i.e. For A to send messages to B, it needs to remember B + + (edited) +
+ + + + +
+
+
+
+
+
+
12:46
+
+ +
+ +
+ somehow, one way or another + +
+ + + + +
+
+
+
+
+
+
12:46
+
+ +
+ +
+ whereas in actual component-based systems, that "memory" is stored externally + +
+ + + + +
+
+
+
+
+
+
12:46
+
+ +
+ +
+ importantly, A does not own B here + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 12:46 PM +
+ +
+ sure, I guess I could see how it's a problem with "agency" ideas too + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:47 PM +
+ +
+ perhaps another thing worth noting here is that OOP overlapped with many general-good-practice "discoveries" and I think inherited some of their reputation, e.g. avoiding unnecessary globals + +
+ + + + +
+
+
+
+
+
+
12:47
+
+ +
+ +
+ (which OOP then undoes by inventing singletons :P) + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 12:48 PM +
+ +
+ I suppose so, yeah + +
+ + + + +
+
+
+
+ + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
SirWhinesalot
+
+ +breaking down systems into components definitely helps with scaling things up, this is done all the time in hardware land, but components are not objects + +
+
+
+ bvisness + + + 28-May-22 12:49 PM +
+ +
+ Going back to this, I would agree that breaking down systems into more-independent modules is certainly very important to solving larger problems; avoiding unnecessary globals is another example of a useful design tactic for tackling complexity + + (edited) +
+ + + + +
+
+
+
+
+
+
12:49
+
+ +
+ +
+ Was it really all that bad before OOP languages became popular though? + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 12:49 PM +
+ +
+ All the fun there is in that word "unnecessary" 🙂 + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 12:49 PM +
+ +
+ That might be too big a question 😛 + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:50 PM +
+ +
+ well, OOP also largely coincided with the establishment of "programmer" as a known profession + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 12:50 PM +
+ +
+ Our programs did grow by several orders of magnitude in the period of the OO paradigm. I feel like it should take some of the credit/blame for that. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:50 PM +
+ +
+ indeed in the 80s it was common for people to conflate the "IT guy" with a programmer, and it was even riffed a bit in movies + +
+ + + + +
+
+
+
+
+
+
12:51
+
+ +
+ +
+ so I think it's hard to separate the professionalization of the field from the techniques that were popular at the time + +
+ + + + +
+
+
+
+
+
+
12:51
+
+ +
+ +
+ far fewer people were programming in the 80s + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 12:52 PM +
+ +
+ I suppose then that programming was just running into the very real problems of working with larger teams + + (edited) +
+ + + + +
+
+
+
+
+
+
12:52
+
+ +
+ +
+ "software engineering", to use Russ Cox's definition + + (edited) +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:52 PM +
+ +
+ yeah + +
+ + + + +
+
+
+
+ + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
bvisness
+
+ +I suppose then that programming was just running into the very real problems of working with larger teams + + (edited) +
+
+
+ Kartik Agaram + + + 28-May-22 12:53 PM +
+ +
+ Oh very interesting, hadn't seen this before: https://research.swtch.com/vgo-eng + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 12:53 PM +
+ +
+ yep I was just gonna share the full quote: +
Software engineering is what happens to programming +when you add time and other programmers.
+ +
+ + + + +
+
+
+
+
+
+
12:54
+
+ +
+ +
+ Is it fair to say that OOP languages offered some useful tools for "software engineering", but that those tools were misused? + + (edited) +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:55 PM +
+ +
+ I'd say Java/C++ offered the versions of various things that became popular (e.g. modularity was a general useful idea, and the way it came to the market was classes) + +
+ + + + +
+
+
+
+ + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
bvisness
+
+ +Is it fair to say that OOP languages offered some useful tools for "software engineering", but that those tools were misused? + + (edited) +
+
+
+ Kartik Agaram + + + 28-May-22 12:56 PM +
+ +
+ Yeah it feels like the nature of the world. You get some promises, you build something. You get some benefits, you get some problems you now have to live with. There's no going back. You can't enter a river twice. + +
+ + + + +
+
+
+
+
+
+
12:56
+
+ +
+ +
+ Even the bad parts, we had to explore them to understand why they're bad. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:56 PM +
+ +
+ it's worth trying to eliminate the "sturgeon contribution" (sturgeons law: 90% of everything is bad) + +
+ + + + +
+
+
+
+
+
+
12:57
+
+ +
+ +
+ a lot of bad stuff was done with OOP, but a lot of bad stuff would be done regardless + +
+ + + + +
+
+
+
+
+
+
12:57
+
+ +
+ +
+ so it's useful to think about what badness was imposed on top of the sturgeon fraction + +
+ + + + +
+
+
+
+
+
+
12:57
+
+ +
+ +
+ personally I think the "model the real world" thing is above-sturgeon badness + +
+ + + + +
+
+
+
+
+
+
12:58
+
+ +
+ +
+ it infected everything and everyone, it wasn't just the usual "most people do bad work" + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 12:58 PM +
+ +
+ you could argue that it's a sturgeon-multiplier + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:58 PM +
+ +
+ yes quite plausible + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 12:58 PM +
+ +
+ it makes the 90% even worse 😛 + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 12:58 PM +
+ +
+ I tend to think all the above-sturgeon badness came from social context. Mostly incentives. Hard to blame a tech paradigm for it. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:59 PM +
+ +
+ but the paradigm clearly invites some forms of badness + +
+ + + + +
+
+
+
+
+
+
12:59
+
+ +
+ +
+ and deserves blame for something it invites + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 01:00 PM +
+ +
+ so for example, the problems with modeling + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 01:00 PM +
+ +
+ I can't blame OOP for people applying it lazily or in a way that it doesn't invite, but I can absolutely blame it for people using it the way it advertises itself + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 01:01 PM +
+ +
+ you yourself did talk though about the level of marketing behind Java - so both factors are certainly in play + +
+ + + + +
+
+
+
+ + + + + + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 01:01 PM +
+ +
+ well ok but the thing that was marketed is not separable right? + +
+ + + + +
+
+
+
+
+
+
13:01
+
+ +
+ +
+ they didn't randomly choose something to promote, they chose that thing to promote + +
+ + + + +
+
+
+
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 01:01 PM +
+ +
+ going from "I have this problem, how do I solve it with a combination of data structures and algorithms" to "how do I model these real-world concepts as agents with data + behavior" was one of the greatest mistakes we did as an industry + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 01:02 PM +
+ +
+ As an example, a nameless org I worked at was big on Design Patterns. But that was mostly caused by promotion incentives that reward complex-seeming work. I hate Design Patterns, but have a hard time blaming it for the ills created in its name. + +
+ + + + +
+
+ z_OOF + 2 +
+
+
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 01:02 PM +
+ +
+ ok but Design Patterns didn't say "you should base promotions on complex patterns" + +
+ + + + +
+
+
+
+
+
+
13:02
+
+ +
+ +
+ whereas OOP does say "you should have your program model concepts in the real world" + + (edited) +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 01:03 PM +
+ +
+ they (Design Patterns) were meant as a tool of communication, something to help explain what a certain structure in the code (that occurs often) is doing, but they turned into "best practices" somehow + + (edited) +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 01:03 PM +
+ +
+ True. I think I just give it some leeway as an honest mistake.. + +
+ + + + +
+
+
+
+
+
+
13:04
+
+ +
+ +
+ Design Patterns were also an honest mistake. They thought the problem they were solving was how to work in complex domains. The problem they turned out to solve was how to smuggle complexity and over-engineering into anything. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 01:05 PM +
+ +
+ I think they started from a very true and valuable observation, which is that code-as-characters-in-files reuse is [NOT] important compared to design reuse + + (edited) +
+ + + + +
+
+
+
+
+
+
13:05
+
+ +
+ +
+ that one insight was enough to persuade me to keep trying to find value in the book for years + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 01:05 PM +
+ +
+ this is Design Patterns, you mean? + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 01:05 PM +
+ +
+ yeah + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 01:05 PM +
+ +
+ yeah that makes sense + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 01:06 PM +
+ +
+ if you already have a design of a solution you can reuse from the past, you're 80% done + +
+ + + + +
+
+
+
+
+
+
13:06
+
+ +
+ +
+ because most of programming is discovering a good-enough design + +
+ + + + +
+
+ 💯 + 1 +
+
+
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 01:06 PM +
+ +
+ Design Patterns are certainly useful. I.e. "I need to model sum types in this language that doesn't have them, how do I do it?" -> "Visitor Pattern, here's how you set it up" + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 01:06 PM +
+ +
+ right well that's the Norvig argument, that design patterns are actually just papering over language deficiencies + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 01:07 PM +
+ +
+ they are 🙂 + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 01:07 PM +
+ +
+ you don't need Command Pattern when you have first class functions + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 01:07 PM +
+ +
+ they're actually a great source of language design inspiration + +
+ + + + +
+
+
+
+
+
+
13:07
+
+ +
+ +
+ "how does your language avoid the need for this pattern" + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 01:08 PM +
+ +
+ yes and this would bring it back to the tried-and-true tradition of standardizing extant patterns of use + +
+ + + + +
+
+
+
+
+
+
13:08
+
+ +
+ +
+ just like the for-loop, or the mere method + +
+ + + + +
+
+
+
+
+
+
13:08
+
+ +
+ +
+ if you write an assembly program, you will at some point write what amounts to a for-loop + +
+ + + + +
+
+
+
+
+
+
13:08
+
+ +
+ +
+ so the language just makes that standard + +
+ + + + +
+
+
+
+
+
+
13:08
+
+ +
+ +
+ to the extent that can be done for design patterns I consider it useful + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 01:09 PM +
+ +
+ I think the problem was that "applying" design patterns somehow became a point of pride? which is silly? they're a shopping list of solutions to particular problems + +
+ + + + +
+
+
+
+
+
+
13:09
+
+ +
+ +
+ i.e. the more patterns in your code the better + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 01:09 PM +
+ +
+ yes, well ... this would be far afield but this is tied to bigtech interviewing/hiring practices in the late 90s + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 01:10 PM +
+ +
+ oh man + +
+ + + + +
+
+ 😄 + 1 +
+
+
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 01:10 PM +
+ +
+ in the same way universities need a thing to teach as a theory of programming, tech companies needed a thing they could quiz + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 01:10 PM +
+ +
+ as much as I would love to crack the coding interview right now, we are past the three-hour mark and I think it would be a good idea to step back and summarize what we've discussed today + +
+ + + + +
+
+
+
+
+
+
13:11
+
+ +
+ +
+ although that would be a great subject for continued discussion afterward + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 01:11 PM +
+ +
+ yes I agree it's too far a tangent + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 01:11 PM +
+ +
+ perhaps a future fishbowl, since it's not really OOP specific + +
+ + + + +
+
+
+
+
+
+
13:11
+
+ +
+ +
+ but also a problem + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 01:11 PM +
+ +
+ definitely + +
+ + + + +
+
+
+
+
+
+
13:12
+
+ +
+ +
+ So here's my summary of what we've covered: +- "OOP is when you associate behavior with data": This is present in OOP, but not really the heart of the issue. That is, just because you have methods doesn't necessarily mean you have anything more than simple procedural programming with some syntax sugar. +- "OOP models the real world": This is categorically not true or effective, no matter what language you use. The real world resists taxonomy, and doesn't have anything to do with the problems you are solving. +- "OOP is Java": Well, we didn't say it as such, but we did discuss many of the specific problems of Java, and the promises it failed to live up to, despite its takeover of industry. +- "OOP as a model of computation": This idea was appealing largely because of promises of independent components and easy reuse - but arguably OOP is worse at providing this than other programming paradigms (especially the Java flavor of OOP). +- "OOP tackles complexity": There are some good concepts, such as modularity and avoiding globals, that became popular along with OOP languages, but OOP itself makes things more complex. + + (edited) +
+ + + + +
+
+
+
+
+
+
13:13
+
+ +
+ +
+ Is this a fair representation or am I leaving things out? + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 01:13 PM +
+ +
+ I'd been writing a summary as well over the conversation, and it is much more instrumental, through the lens of "how to write better programs" + +- if you have lots of one kind of thing, give them a common template +- when building a program, take a moment to plan such schemas first +- as a schema proves valuable, rework it to be more timeless. This includes making it easy to change the memory layout, but much more. + +Some rules of thumb like these capture all that is valuable about OO, to my mind. And what programming languages can contribute here are late-binding capabilities that preserve optionality for the programmer. + +What they don't capture is the hardest problem of all: how you can preserve an executable, checkable model of the world that acts as a history of why your program is as it is. + +Tests are one way to do that. Formal models are another, though formal models can also be used for modeling solutions rather than contexts. Prose documents are a third. They have limitations, but they're better than nothing to a future code archeologist. + +A lot of the ills we see with OO dogma lie in the space between my rules of thumb. You have to wait until you understand a domain before you try to generalize. OO languages are particularly bad here, because you're forced to create classes literally on line 1. + +I think design as a general activity makes no sense. Good design comes from understanding a domain. It is by necessity domain-specific. + +And any design activity really has to have a certain level of humility. Pick a bounded problem. Interact with few peers (that themselves have humility in dependencies and goals). Keep things coherent rather than trying to optimize the whole ocean into paperclips. + + (edited) +
+ + + + +
+
+
+
+ + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
bvisness
+
+ +Is this a fair representation or am I leaving things out? + +
+
+
+ SirWhinesalot + + + 28-May-22 01:14 PM +
+ +
+ just that if we split interfaces/vtables from OO, and maybe the nice subject verb object syntax, there's nothing of use left + +
+ + + + +
+
+
+
+
+
+
13:16
+
+ +
+ +
+ I'm willing to leave interfaces/vtables as being "OO", as the one useful thing it has, because they are damn useful when you need them + +
+ + + + +
+
+ ❤️ + 1 +
+
+
+
+
+
+
+
+
13:17
+
+ +
+ +
+ but other people disagree that they're even "OO", since stuff like modules in SML have many similarities without the runtime dispatch for example, and there are many ways to do runtime dispatch that are not interface based + + (edited) +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 01:19 PM +
+ +
+ So in that case...I'd like to return to the original age-old question: "is OOP bad or what?" + +It sounds like the prevailing opinion here is that: +- Object-oriented programming is fundamentally an approach to modeling and design, not merely some nice syntax in your language +- Object-oriented design is fundamentally flawed, since the idea of solving problems by modeling the world is fundamentally flawed +- The flaws of object-oriented design also prevent OOP from being a useful model of computation, or from meaningfully tackling complexity + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 01:19 PM +
+ +
+ that's my view on the matter yes + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 01:19 PM +
+ +
+
A lot of the ills we see with OO dogma lie in the space between my rules of thumb. You have to wait until you understand a domain before you try to generalize. OO languages are particularly bad here, because you're forced to create classes literally on line 1. + +I think design as a general activity makes no sense. Good design comes from understanding a domain. It is by necessity domain-specific. +
And I appreciate these thoughts by @Kartik Agaram a lot.
+ +
+ + + + +
+
+
+
+
+
+
13:20
+
+ +
+ +
+ Not only does object-oriented design fail to model problems well, but the tools force you into bad designs immediately. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
bvisness
+
+ +Not only does object-oriented design fail to model problems well, but the tools force you into bad designs immediately. + +
+
+
+ demetrispanos + + + 28-May-22 01:21 PM +
+ +
+ yes in particular "in what class does this activity belong?" is a useless question that has wasted an enormous amount of time + +
+ + + + +
+
+
+
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 01:20 PM +
+ +
+ btw, just to answer the question I posted when I did my design introduction + +
+ + + + +
+
+
+
+
+
+
13:21
+
+ +
+ +
+ What is the single responsibility of the Customer class? + + (edited) +
+ + + + +
+
+
+
+
+
+
13:21
+
+ +
+ +
+ it is to uniquely identify a customer, it's a primary key + +
+ + + + +
+
+
+
+
+
+
13:21
+
+ +
+ +
+ here's a Customer class in Odin + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 01:21 PM +
+ +
+
Customer :: distinct u64
+ +
+ + + + +
+
+
+
+ + + + + + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 01:22 PM +
+ +
+ I think I can also reasonably conclude that, while OOP languages and practices may contain some good ideas, those are mostly unrelated to the core of object-oriented design. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 01:24 PM +
+ +
+ I think "ownership" should maybe go in another fishbowl as well, since it has some similar issues with rigid tree-like structures and assigning "agency" to bits of data + +
+ + + + +
+
+
+
+
+
+
13:24
+
+ +
+ +
+ ownership is quite central to OOP + +
+ + + + +
+
+
+
+
+
+
13:24
+
+ +
+ +
+ even in GC languages + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 01:24 PM +
+ +
+ because there's a distinction between an object that "contains" another object within itself, and an object that "knows" about another object + +
+ + + + +
+
+
+
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 01:25 PM +
+ +
+ in Rust there's a syntactical distinction, but in Java there isn't + +
+ + + + +
+
+
+
+
+
+
+ Avatar +
+ +
+
+ gingerBill + + + 28-May-22 01:24 PM +
+ +
+ Ownership semantics is surprisingly related to OOP from an ontological perspective + +
+ + + + +
+
+
+
+ + + + + + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 01:25 PM +
+ +
+ and there we have massive tangent #2 + +
+ + + + +
+
+
+
+ + + + + + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 01:25 PM +
+ +
+ But yeah I agree that it could be a valuable topic to fishbowl about someday. + +
+ + + + +
+
+
+
+
+
+
13:26
+
+ +
+ +
+ Thanks @Kartik Agaram for the summary thoughts - are there any other summary thoughts our other participants would like to provide before we close? + +
+ + + + +
+
+ ❤️ + 1 +
+
+
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 01:26 PM +
+ + + + + + +
+
+
+
+
+
+
13:26
+
+ +
+ +
+ so I'll shut up now 😛 + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 01:27 PM +
+ +
+ Thanks everyone for this introduction to the fishbowl format. I'm a huge convert, to the extent that I think we should stop having in-person conferences. + +
+ + + + +
+
+ 😂 + 3 +
+
+ AbnerHangry + 3 +
+
+
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 01:28 PM +
+ +
+ Thank you very much for participating! I am really glad we finally had the opportunity to discuss this topic thoroughly. + +
+ + + + +
+
+
+
+
+
+
13:29
+
+ +
+ +
+ Thank you all for helping me with my secret moderator agenda of being able to say "before you discuss OOP any further, read this conversation" 😈 + +
+ + + + +
+
+ brain + 6 +
+
+
+
+
+
+
+
+
13:30
+
+ +
+ +
+ I hope everyone found the conversation useful, that it helps you understand OOP better, and that it helps you understand how to write better programs. + +
+ + + + +
+
+
+
+
+
+
13:31
+
+ +
+ +
+ See you in a couple months for our next fishbowl! + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 01:31 PM +
+ +
+ Thank you @bvisness for organizing! + +
+ + + + +
+
+ coolben + 2 +
+
+
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 01:32 PM +
+ +
+ Indeed, thanks a lot @bvisness , and also thank you to all the participants + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 01:36 PM +
+ + + + + + +
+
+
+
+ + +
+ +
+
Exported 463 message(s)
+
+ + + + + \ No newline at end of file diff --git a/src/templates/src/fishbowls/oop/OOP_down.html_Files/1963eacbf364164efce1c597dc66aeab-E6901.png b/src/templates/src/fishbowls/oop/OOP_down.html_Files/1963eacbf364164efce1c597dc66aeab-E6901.png new file mode 100644 index 0000000..ccf4824 Binary files /dev/null and b/src/templates/src/fishbowls/oop/OOP_down.html_Files/1963eacbf364164efce1c597dc66aeab-E6901.png differ diff --git a/src/templates/src/fishbowls/oop/OOP_down.html_Files/1f3f4-200d-2620-6E400.svg b/src/templates/src/fishbowls/oop/OOP_down.html_Files/1f3f4-200d-2620-6E400.svg new file mode 100644 index 0000000..ae0d531 --- /dev/null +++ b/src/templates/src/fishbowls/oop/OOP_down.html_Files/1f3f4-200d-2620-6E400.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/templates/src/fishbowls/oop/OOP_down.html_Files/1f44d-B3F5F.svg b/src/templates/src/fishbowls/oop/OOP_down.html_Files/1f44d-B3F5F.svg new file mode 100644 index 0000000..595672d --- /dev/null +++ b/src/templates/src/fishbowls/oop/OOP_down.html_Files/1f44d-B3F5F.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/templates/src/fishbowls/oop/OOP_down.html_Files/1f4a1-26401.svg b/src/templates/src/fishbowls/oop/OOP_down.html_Files/1f4a1-26401.svg new file mode 100644 index 0000000..88b62e3 --- /dev/null +++ b/src/templates/src/fishbowls/oop/OOP_down.html_Files/1f4a1-26401.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/templates/src/fishbowls/oop/OOP_down.html_Files/1f4a5-61C11.svg b/src/templates/src/fishbowls/oop/OOP_down.html_Files/1f4a5-61C11.svg new file mode 100644 index 0000000..36c50d6 --- /dev/null +++ b/src/templates/src/fishbowls/oop/OOP_down.html_Files/1f4a5-61C11.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/templates/src/fishbowls/oop/OOP_down.html_Files/1f4af-2188D.svg b/src/templates/src/fishbowls/oop/OOP_down.html_Files/1f4af-2188D.svg new file mode 100644 index 0000000..3d565cc --- /dev/null +++ b/src/templates/src/fishbowls/oop/OOP_down.html_Files/1f4af-2188D.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/templates/src/fishbowls/oop/OOP_down.html_Files/1f4f7-B9213.svg b/src/templates/src/fishbowls/oop/OOP_down.html_Files/1f4f7-B9213.svg new file mode 100644 index 0000000..aa2d9c5 --- /dev/null +++ b/src/templates/src/fishbowls/oop/OOP_down.html_Files/1f4f7-B9213.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/templates/src/fishbowls/oop/OOP_down.html_Files/1f5e1-9D0D3.svg b/src/templates/src/fishbowls/oop/OOP_down.html_Files/1f5e1-9D0D3.svg new file mode 100644 index 0000000..d1d7712 --- /dev/null +++ b/src/templates/src/fishbowls/oop/OOP_down.html_Files/1f5e1-9D0D3.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/templates/src/fishbowls/oop/OOP_down.html_Files/1f602-20224.svg b/src/templates/src/fishbowls/oop/OOP_down.html_Files/1f602-20224.svg new file mode 100644 index 0000000..1ec7937 --- /dev/null +++ b/src/templates/src/fishbowls/oop/OOP_down.html_Files/1f602-20224.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/templates/src/fishbowls/oop/OOP_down.html_Files/1f604-6061B.svg b/src/templates/src/fishbowls/oop/OOP_down.html_Files/1f604-6061B.svg new file mode 100644 index 0000000..99ac39c --- /dev/null +++ b/src/templates/src/fishbowls/oop/OOP_down.html_Files/1f604-6061B.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/templates/src/fishbowls/oop/OOP_down.html_Files/1f914-54FF1.svg b/src/templates/src/fishbowls/oop/OOP_down.html_Files/1f914-54FF1.svg new file mode 100644 index 0000000..4e8c4cc --- /dev/null +++ b/src/templates/src/fishbowls/oop/OOP_down.html_Files/1f914-54FF1.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/templates/src/fishbowls/oop/OOP_down.html_Files/261d-3A498.svg b/src/templates/src/fishbowls/oop/OOP_down.html_Files/261d-3A498.svg new file mode 100644 index 0000000..95d8ddd --- /dev/null +++ b/src/templates/src/fishbowls/oop/OOP_down.html_Files/261d-3A498.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/templates/src/fishbowls/oop/OOP_down.html_Files/26ab-FC554.svg b/src/templates/src/fishbowls/oop/OOP_down.html_Files/26ab-FC554.svg new file mode 100644 index 0000000..169b72c --- /dev/null +++ b/src/templates/src/fishbowls/oop/OOP_down.html_Files/26ab-FC554.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/templates/src/fishbowls/oop/OOP_down.html_Files/2757-5311E.svg b/src/templates/src/fishbowls/oop/OOP_down.html_Files/2757-5311E.svg new file mode 100644 index 0000000..e730a08 --- /dev/null +++ b/src/templates/src/fishbowls/oop/OOP_down.html_Files/2757-5311E.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/templates/src/fishbowls/oop/OOP_down.html_Files/2764-02CD4.svg b/src/templates/src/fishbowls/oop/OOP_down.html_Files/2764-02CD4.svg new file mode 100644 index 0000000..7eb5c59 --- /dev/null +++ b/src/templates/src/fishbowls/oop/OOP_down.html_Files/2764-02CD4.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/templates/src/fishbowls/oop/OOP_down.html_Files/3bf987dc7a33d0b2f989878615544d6a-D4B96.png b/src/templates/src/fishbowls/oop/OOP_down.html_Files/3bf987dc7a33d0b2f989878615544d6a-D4B96.png new file mode 100644 index 0000000..833cb87 Binary files /dev/null and b/src/templates/src/fishbowls/oop/OOP_down.html_Files/3bf987dc7a33d0b2f989878615544d6a-D4B96.png differ diff --git a/src/templates/src/fishbowls/oop/OOP_down.html_Files/418ec586b1074c5304d2bdfde2d725c9-F2143.png b/src/templates/src/fishbowls/oop/OOP_down.html_Files/418ec586b1074c5304d2bdfde2d725c9-F2143.png new file mode 100644 index 0000000..fbb67b6 Binary files /dev/null and b/src/templates/src/fishbowls/oop/OOP_down.html_Files/418ec586b1074c5304d2bdfde2d725c9-F2143.png differ diff --git a/src/templates/src/fishbowls/oop/OOP_down.html_Files/487994603568496650-3FA2C.png b/src/templates/src/fishbowls/oop/OOP_down.html_Files/487994603568496650-3FA2C.png new file mode 100644 index 0000000..a57e0da Binary files /dev/null and b/src/templates/src/fishbowls/oop/OOP_down.html_Files/487994603568496650-3FA2C.png differ diff --git a/src/templates/src/fishbowls/oop/OOP_down.html_Files/597863487032786944-538BB.png b/src/templates/src/fishbowls/oop/OOP_down.html_Files/597863487032786944-538BB.png new file mode 100644 index 0000000..fc352f2 Binary files /dev/null and b/src/templates/src/fishbowls/oop/OOP_down.html_Files/597863487032786944-538BB.png differ diff --git a/src/templates/src/fishbowls/oop/OOP_down.html_Files/62e486caf24d352ab938701a8d972730-5ADCF.png b/src/templates/src/fishbowls/oop/OOP_down.html_Files/62e486caf24d352ab938701a8d972730-5ADCF.png new file mode 100644 index 0000000..8c3d6c9 Binary files /dev/null and b/src/templates/src/fishbowls/oop/OOP_down.html_Files/62e486caf24d352ab938701a8d972730-5ADCF.png differ diff --git a/src/templates/src/fishbowls/oop/OOP_down.html_Files/777941313546092555-41FE8.png b/src/templates/src/fishbowls/oop/OOP_down.html_Files/777941313546092555-41FE8.png new file mode 100644 index 0000000..8042e68 Binary files /dev/null and b/src/templates/src/fishbowls/oop/OOP_down.html_Files/777941313546092555-41FE8.png differ diff --git a/src/templates/src/fishbowls/oop/OOP_down.html_Files/798990517714419714-A5156.png b/src/templates/src/fishbowls/oop/OOP_down.html_Files/798990517714419714-A5156.png new file mode 100644 index 0000000..a14473a Binary files /dev/null and b/src/templates/src/fishbowls/oop/OOP_down.html_Files/798990517714419714-A5156.png differ diff --git a/src/templates/src/fishbowls/oop/OOP_down.html_Files/851646609917476884-15D55.png b/src/templates/src/fishbowls/oop/OOP_down.html_Files/851646609917476884-15D55.png new file mode 100644 index 0000000..f6d346b Binary files /dev/null and b/src/templates/src/fishbowls/oop/OOP_down.html_Files/851646609917476884-15D55.png differ diff --git a/src/templates/src/fishbowls/oop/OOP_down.html_Files/89747c254631bcfd05c5c3e7141389aa-A1FB9.png b/src/templates/src/fishbowls/oop/OOP_down.html_Files/89747c254631bcfd05c5c3e7141389aa-A1FB9.png new file mode 100644 index 0000000..6fe1dbd Binary files /dev/null and b/src/templates/src/fishbowls/oop/OOP_down.html_Files/89747c254631bcfd05c5c3e7141389aa-A1FB9.png differ diff --git a/src/templates/src/fishbowls/oop/OOP_down.html_Files/db36a06d98bf0e98017ec3559150c05c-F4AEF.png b/src/templates/src/fishbowls/oop/OOP_down.html_Files/db36a06d98bf0e98017ec3559150c05c-F4AEF.png new file mode 100644 index 0000000..fea5ea2 Binary files /dev/null and b/src/templates/src/fishbowls/oop/OOP_down.html_Files/db36a06d98bf0e98017ec3559150c05c-F4AEF.png differ diff --git a/src/templates/src/fishbowls/oop/OOP_down.html_Files/highlight.min-D8D27.js b/src/templates/src/fishbowls/oop/OOP_down.html_Files/highlight.min-D8D27.js new file mode 100644 index 0000000..1f06ffc --- /dev/null +++ b/src/templates/src/fishbowls/oop/OOP_down.html_Files/highlight.min-D8D27.js @@ -0,0 +1,2 @@ +/*! highlight.js v9.15.6 | BSD3 License | git.io/hljslicense */ +!function(e){var t="object"==typeof window&&window||"object"==typeof self&&self;"undefined"!=typeof exports?e(exports):t&&(t.hljs=e({}),"function"==typeof define&&define.amd&&define([],function(){return t.hljs}))}(function(n){var b=[],o=Object.keys,h={},p={},t=/^(no-?highlight|plain|text)$/i,m=/\blang(?:uage)?-([\w-]+)\b/i,r=/((^(<[^>]+>|\t|)+|(?:\n)))/gm,a={case_insensitive:"cI",lexemes:"l",contains:"c",keywords:"k",subLanguage:"sL",className:"cN",begin:"b",beginKeywords:"bK",end:"e",endsWithParent:"eW",illegal:"i",excludeBegin:"eB",excludeEnd:"eE",returnBegin:"rB",returnEnd:"rE",relevance:"r",variants:"v",IDENT_RE:"IR",UNDERSCORE_IDENT_RE:"UIR",NUMBER_RE:"NR",C_NUMBER_RE:"CNR",BINARY_NUMBER_RE:"BNR",RE_STARTERS_RE:"RSR",BACKSLASH_ESCAPE:"BE",APOS_STRING_MODE:"ASM",QUOTE_STRING_MODE:"QSM",PHRASAL_WORDS_MODE:"PWM",C_LINE_COMMENT_MODE:"CLCM",C_BLOCK_COMMENT_MODE:"CBCM",HASH_COMMENT_MODE:"HCM",NUMBER_MODE:"NM",C_NUMBER_MODE:"CNM",BINARY_NUMBER_MODE:"BNM",CSS_NUMBER_MODE:"CSSNM",REGEXP_MODE:"RM",TITLE_MODE:"TM",UNDERSCORE_TITLE_MODE:"UTM",COMMENT:"C",beginRe:"bR",endRe:"eR",illegalRe:"iR",lexemesRe:"lR",terminators:"t",terminator_end:"tE"},N="",v={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0};function y(e){return e.replace(/&/g,"&").replace(//g,">")}function f(e){return e.nodeName.toLowerCase()}function w(e,t){var r=e&&e.exec(t);return r&&0===r.index}function g(e){return t.test(e)}function u(e){var t,r={},a=Array.prototype.slice.call(arguments,1);for(t in e)r[t]=e[t];return a.forEach(function(e){for(t in e)r[t]=e[t]}),r}function _(e){var n=[];return function e(t,r){for(var a=t.firstChild;a;a=a.nextSibling)3===a.nodeType?r+=a.nodeValue.length:1===a.nodeType&&(n.push({event:"start",offset:r,node:a}),r=e(a,r),f(a).match(/br|hr|img|input/)||n.push({event:"stop",offset:r,node:a}));return r}(e,0),n}function i(e){if(a&&!e.langApiRestored){for(var t in e.langApiRestored=!0,a)e[t]&&(e[a[t]]=e[t]);(e.c||[]).concat(e.v||[]).forEach(i)}}function E(s){function l(e){return e&&e.source||e}function c(e,t){return new RegExp(l(e),"m"+(s.cI?"i":"")+(t?"g":""))}!function t(r,e){if(!r.compiled){if(r.compiled=!0,r.k=r.k||r.bK,r.k){var a={},n=function(r,e){s.cI&&(e=e.toLowerCase()),e.split(" ").forEach(function(e){var t=e.split("|");a[t[0]]=[r,t[1]?Number(t[1]):1]})};"string"==typeof r.k?n("keyword",r.k):o(r.k).forEach(function(e){n(e,r.k[e])}),r.k=a}r.lR=c(r.l||/\w+/,!0),e&&(r.bK&&(r.b="\\b("+r.bK.split(" ").join("|")+")\\b"),r.b||(r.b=/\B|\b/),r.bR=c(r.b),r.endSameAsBegin&&(r.e=r.b),r.e||r.eW||(r.e=/\B|\b/),r.e&&(r.eR=c(r.e)),r.tE=l(r.e)||"",r.eW&&e.tE&&(r.tE+=(r.e?"|":"")+e.tE)),r.i&&(r.iR=c(r.i)),null==r.r&&(r.r=1),r.c||(r.c=[]),r.c=Array.prototype.concat.apply([],r.c.map(function(e){return(t="self"===e?r:e).v&&!t.cached_variants&&(t.cached_variants=t.v.map(function(e){return u(t,{v:null},e)})),t.cached_variants||t.eW&&[u(t)]||[t];var t})),r.c.forEach(function(e){t(e,r)}),r.starts&&t(r.starts,e);var i=r.c.map(function(e){return e.bK?"\\.?(?:"+e.b+")\\.?":e.b}).concat([r.tE,r.i]).map(l).filter(Boolean);r.t=i.length?c(function(e,t){for(var r=/\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./,a=0,n="",i=0;i')+t+(r?"":N)}function l(){p+=null!=b.sL?function(){var e="string"==typeof b.sL;if(e&&!h[b.sL])return y(m);var t=e?k(b.sL,m,!0,i[b.sL]):x(m,b.sL.length?b.sL:void 0);return 0")+'"');return m+=t,t.length||1}var d=C(e);if(!d)throw new Error('Unknown language: "'+e+'"');E(d);var n,b=r||d,i={},p="";for(n=b;n!==d;n=n.parent)n.cN&&(p=o(n.cN,"",!0)+p);var m="",f=0;try{for(var s,g,_=0;b.t.lastIndex=_,s=b.t.exec(t);)g=a(t.substring(_,s.index),s[0]),_=s.index+g;for(a(t.substr(_)),n=b;n.parent;n=n.parent)n.cN&&(p+=N);return{r:f,value:p,language:e,top:b}}catch(e){if(e.message&&-1!==e.message.indexOf("Illegal"))return{r:0,value:y(t)};throw e}}function x(r,e){e=e||v.languages||o(h);var a={r:0,value:y(r)},n=a;return e.filter(C).filter(l).forEach(function(e){var t=k(e,r,!1);t.language=e,t.r>n.r&&(n=t),t.r>a.r&&(n=a,a=t)}),n.language&&(a.second_best=n),a}function M(e){return v.tabReplace||v.useBR?e.replace(r,function(e,t){return v.useBR&&"\n"===e?"
":v.tabReplace?t.replace(/\t/g,v.tabReplace):""}):e}function s(e){var t,r,a,n,i,s,c,o,l,u,d=function(e){var t,r,a,n,i=e.className+" ";if(i+=e.parentNode?e.parentNode.className:"",r=m.exec(i))return C(r[1])?r[1]:"no-highlight";for(t=0,a=(i=i.split(/\s+/)).length;t/g,"\n"):t=e,i=t.textContent,a=d?k(d,i,!0):x(i),(r=_(t)).length&&((n=document.createElementNS("http://www.w3.org/1999/xhtml","div")).innerHTML=a.value,a.value=function(e,t,r){var a=0,n="",i=[];function s(){return e.length&&t.length?e[0].offset!==t[0].offset?e[0].offset"}function o(e){n+=""}function l(e){("start"===e.event?c:o)(e.node)}for(;e.length||t.length;){var u=s();if(n+=y(r.substring(a,u[0].offset)),a=u[0].offset,u===e){for(i.reverse().forEach(o);l(u.splice(0,1)[0]),(u=s())===e&&u.length&&u[0].offset===a;);i.reverse().forEach(c)}else"start"===u[0].event?i.push(u[0].node):i.pop(),l(u.splice(0,1)[0])}return n+y(r.substr(a))}(r,_(n),i)),a.value=M(a.value),e.innerHTML=a.value,e.className=(s=e.className,c=d,o=a.language,l=c?p[c]:o,u=[s.trim()],s.match(/\bhljs\b/)||u.push("hljs"),-1===s.indexOf(l)&&u.push(l),u.join(" ").trim()),e.result={language:a.language,re:a.r},a.second_best&&(e.second_best={language:a.second_best.language,re:a.second_best.r}))}function c(){if(!c.called){c.called=!0;var e=document.querySelectorAll("pre code");b.forEach.call(e,s)}}function C(e){return e=(e||"").toLowerCase(),h[e]||h[p[e]]}function l(e){var t=C(e);return t&&!t.disableAutodetect}return n.highlight=k,n.highlightAuto=x,n.fixMarkup=M,n.highlightBlock=s,n.configure=function(e){v=u(v,e)},n.initHighlighting=c,n.initHighlightingOnLoad=function(){addEventListener("DOMContentLoaded",c,!1),addEventListener("load",c,!1)},n.registerLanguage=function(t,e){var r=h[t]=e(n);i(r),r.aliases&&r.aliases.forEach(function(e){p[e]=t})},n.listLanguages=function(){return o(h)},n.getLanguage=C,n.autoDetection=l,n.inherit=u,n.IR=n.IDENT_RE="[a-zA-Z]\\w*",n.UIR=n.UNDERSCORE_IDENT_RE="[a-zA-Z_]\\w*",n.NR=n.NUMBER_RE="\\b\\d+(\\.\\d+)?",n.CNR=n.C_NUMBER_RE="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",n.BNR=n.BINARY_NUMBER_RE="\\b(0b[01]+)",n.RSR=n.RE_STARTERS_RE="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",n.BE=n.BACKSLASH_ESCAPE={b:"\\\\[\\s\\S]",r:0},n.ASM=n.APOS_STRING_MODE={cN:"string",b:"'",e:"'",i:"\\n",c:[n.BE]},n.QSM=n.QUOTE_STRING_MODE={cN:"string",b:'"',e:'"',i:"\\n",c:[n.BE]},n.PWM=n.PHRASAL_WORDS_MODE={b:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},n.C=n.COMMENT=function(e,t,r){var a=n.inherit({cN:"comment",b:e,e:t,c:[]},r||{});return a.c.push(n.PWM),a.c.push({cN:"doctag",b:"(?:TODO|FIXME|NOTE|BUG|XXX):",r:0}),a},n.CLCM=n.C_LINE_COMMENT_MODE=n.C("//","$"),n.CBCM=n.C_BLOCK_COMMENT_MODE=n.C("/\\*","\\*/"),n.HCM=n.HASH_COMMENT_MODE=n.C("#","$"),n.NM=n.NUMBER_MODE={cN:"number",b:n.NR,r:0},n.CNM=n.C_NUMBER_MODE={cN:"number",b:n.CNR,r:0},n.BNM=n.BINARY_NUMBER_MODE={cN:"number",b:n.BNR,r:0},n.CSSNM=n.CSS_NUMBER_MODE={cN:"number",b:n.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},n.RM=n.REGEXP_MODE={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[n.BE,{b:/\[/,e:/\]/,r:0,c:[n.BE]}]},n.TM=n.TITLE_MODE={cN:"title",b:n.IR,r:0},n.UTM=n.UNDERSCORE_TITLE_MODE={cN:"title",b:n.UIR,r:0},n.METHOD_GUARD={b:"\\.\\s*"+n.UIR,r:0},n.registerLanguage("apache",function(e){var t={cN:"number",b:"[\\$%]\\d+"};return{aliases:["apacheconf"],cI:!0,c:[e.HCM,{cN:"section",b:""},{cN:"attribute",b:/\w+/,r:0,k:{nomarkup:"order deny allow setenv rewriterule rewriteengine rewritecond documentroot sethandler errordocument loadmodule options header listen serverroot servername"},starts:{e:/$/,r:0,k:{literal:"on off all"},c:[{cN:"meta",b:"\\s\\[",e:"\\]$"},{cN:"variable",b:"[\\$%]\\{",e:"\\}",c:["self",t]},t,e.QSM]}}],i:/\S/}}),n.registerLanguage("bash",function(e){var t={cN:"variable",v:[{b:/\$[\w\d#@][\w\d_]*/},{b:/\$\{(.*?)}/}]},r={cN:"string",b:/"/,e:/"/,c:[e.BE,t,{cN:"variable",b:/\$\(/,e:/\)/,c:[e.BE]}]};return{aliases:["sh","zsh"],l:/\b-?[a-z\._]+\b/,k:{keyword:"if then else elif fi for while in do done case esac function",literal:"true false",built_in:"break cd continue eval exec exit export getopts hash pwd readonly return shift test times trap umask unset alias bind builtin caller command declare echo enable help let local logout mapfile printf read readarray source type typeset ulimit unalias set shopt autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate fc fg float functions getcap getln history integer jobs kill limit log noglob popd print pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof zpty zregexparse zsocket zstyle ztcp",_:"-ne -eq -lt -gt -f -d -e -s -l -a"},c:[{cN:"meta",b:/^#![^\n]+sh\s*$/,r:10},{cN:"function",b:/\w[\w\d_]*\s*\(\s*\)\s*\{/,rB:!0,c:[e.inherit(e.TM,{b:/\w[\w\d_]*/})],r:0},e.HCM,r,{cN:"string",b:/'/,e:/'/},t]}}),n.registerLanguage("coffeescript",function(e){var t={keyword:"in if for while finally new do return else break catch instanceof throw try this switch continue typeof delete debugger super yield import export from as default await then unless until loop of by when and or is isnt not",literal:"true false null undefined yes no on off",built_in:"npm require console print module global window document"},r="[A-Za-z$_][0-9A-Za-z$_]*",a={cN:"subst",b:/#\{/,e:/}/,k:t},n=[e.BNM,e.inherit(e.CNM,{starts:{e:"(\\s*/)?",r:0}}),{cN:"string",v:[{b:/'''/,e:/'''/,c:[e.BE]},{b:/'/,e:/'/,c:[e.BE]},{b:/"""/,e:/"""/,c:[e.BE,a]},{b:/"/,e:/"/,c:[e.BE,a]}]},{cN:"regexp",v:[{b:"///",e:"///",c:[a,e.HCM]},{b:"//[gim]*",r:0},{b:/\/(?![ *])(\\\/|.)*?\/[gim]*(?=\W|$)/}]},{b:"@"+r},{sL:"javascript",eB:!0,eE:!0,v:[{b:"```",e:"```"},{b:"`",e:"`"}]}];a.c=n;var i=e.inherit(e.TM,{b:r}),s="(\\(.*\\))?\\s*\\B[-=]>",c={cN:"params",b:"\\([^\\(]",rB:!0,c:[{b:/\(/,e:/\)/,k:t,c:["self"].concat(n)}]};return{aliases:["coffee","cson","iced"],k:t,i:/\/\*/,c:n.concat([e.C("###","###"),e.HCM,{cN:"function",b:"^\\s*"+r+"\\s*=\\s*"+s,e:"[-=]>",rB:!0,c:[i,c]},{b:/[:\(,=]\s*/,r:0,c:[{cN:"function",b:s,e:"[-=]>",rB:!0,c:[c]}]},{cN:"class",bK:"class",e:"$",i:/[:="\[\]]/,c:[{bK:"extends",eW:!0,i:/[:="\[\]]/,c:[i]},i]},{b:r+":",e:":",rB:!0,rE:!0,r:0}])}}),n.registerLanguage("cpp",function(e){var t={cN:"keyword",b:"\\b[a-z\\d_]*_t\\b"},r={cN:"string",v:[{b:'(u8?|U|L)?"',e:'"',i:"\\n",c:[e.BE]},{b:/(?:u8?|U|L)?R"([^()\\ ]{0,16})\((?:.|\n)*?\)\1"/},{b:"'\\\\?.",e:"'",i:"."}]},a={cN:"number",v:[{b:"\\b(0b[01']+)"},{b:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)(u|U|l|L|ul|UL|f|F|b|B)"},{b:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)"}],r:0},n={cN:"meta",b:/#\s*[a-z]+\b/,e:/$/,k:{"meta-keyword":"if else elif endif define undef warning error line pragma ifdef ifndef include"},c:[{b:/\\\n/,r:0},e.inherit(r,{cN:"meta-string"}),{cN:"meta-string",b:/<[^\n>]*>/,e:/$/,i:"\\n"},e.CLCM,e.CBCM]},i=e.IR+"\\s*\\(",s={keyword:"int float while private char catch import module export virtual operator sizeof dynamic_cast|10 typedef const_cast|10 const for static_cast|10 union namespace unsigned long volatile static protected bool template mutable if public friend do goto auto void enum else break extern using asm case typeid short reinterpret_cast|10 default double register explicit signed typename try this switch continue inline delete alignof constexpr decltype noexcept static_assert thread_local restrict _Bool complex _Complex _Imaginary atomic_bool atomic_char atomic_schar atomic_uchar atomic_short atomic_ushort atomic_int atomic_uint atomic_long atomic_ulong atomic_llong atomic_ullong new throw return and or not",built_in:"std string cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap array shared_ptr abort abs acos asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp fscanf isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan vfprintf vprintf vsprintf endl initializer_list unique_ptr",literal:"true false nullptr NULL"},c=[t,e.CLCM,e.CBCM,a,r];return{aliases:["c","cc","h","c++","h++","hpp"],k:s,i:"",k:s,c:["self",t]},{b:e.IR+"::",k:s},{v:[{b:/=/,e:/;/},{b:/\(/,e:/\)/},{bK:"new throw return else",e:/;/}],k:s,c:c.concat([{b:/\(/,e:/\)/,k:s,c:c.concat(["self"]),r:0}]),r:0},{cN:"function",b:"("+e.IR+"[\\*&\\s]+)+"+i,rB:!0,e:/[{;=]/,eE:!0,k:s,i:/[^\w\s\*&]/,c:[{b:i,rB:!0,c:[e.TM],r:0},{cN:"params",b:/\(/,e:/\)/,k:s,r:0,c:[e.CLCM,e.CBCM,r,a,t,{b:/\(/,e:/\)/,k:s,r:0,c:["self",e.CLCM,e.CBCM,r,a,t]}]},e.CLCM,e.CBCM,n]},{cN:"class",bK:"class struct",e:/[{;:]/,c:[{b://,c:["self"]},e.TM]}]),exports:{preprocessor:n,strings:r,k:s}}}),n.registerLanguage("cs",function(e){var t={keyword:"abstract as base bool break byte case catch char checked const continue decimal default delegate do double enum event explicit extern finally fixed float for foreach goto if implicit in int interface internal is lock long nameof object operator out override params private protected public readonly ref sbyte sealed short sizeof stackalloc static string struct switch this try typeof uint ulong unchecked unsafe ushort using virtual void volatile while add alias ascending async await by descending dynamic equals from get global group into join let on orderby partial remove select set value var where yield",literal:"null false true"},r={cN:"number",v:[{b:"\\b(0b[01']+)"},{b:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)(u|U|l|L|ul|UL|f|F|b|B)"},{b:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)"}],r:0},a={cN:"string",b:'@"',e:'"',c:[{b:'""'}]},n=e.inherit(a,{i:/\n/}),i={cN:"subst",b:"{",e:"}",k:t},s=e.inherit(i,{i:/\n/}),c={cN:"string",b:/\$"/,e:'"',i:/\n/,c:[{b:"{{"},{b:"}}"},e.BE,s]},o={cN:"string",b:/\$@"/,e:'"',c:[{b:"{{"},{b:"}}"},{b:'""'},i]},l=e.inherit(o,{i:/\n/,c:[{b:"{{"},{b:"}}"},{b:'""'},s]});i.c=[o,c,a,e.ASM,e.QSM,r,e.CBCM],s.c=[l,c,n,e.ASM,e.QSM,r,e.inherit(e.CBCM,{i:/\n/})];var u={v:[o,c,a,e.ASM,e.QSM]},d=e.IR+"(<"+e.IR+"(\\s*,\\s*"+e.IR+")*>)?(\\[\\])?";return{aliases:["csharp","c#"],k:t,i:/::/,c:[e.C("///","$",{rB:!0,c:[{cN:"doctag",v:[{b:"///",r:0},{b:"\x3c!--|--\x3e"},{b:""}]}]}),e.CLCM,e.CBCM,{cN:"meta",b:"#",e:"$",k:{"meta-keyword":"if else elif endif define undef warning error line region endregion pragma checksum"}},u,r,{bK:"class interface",e:/[{;=]/,i:/[^\s:,]/,c:[e.TM,e.CLCM,e.CBCM]},{bK:"namespace",e:/[{;=]/,i:/[^\s:]/,c:[e.inherit(e.TM,{b:"[a-zA-Z](\\.?\\w)*"}),e.CLCM,e.CBCM]},{cN:"meta",b:"^\\s*\\[",eB:!0,e:"\\]",eE:!0,c:[{cN:"meta-string",b:/"/,e:/"/}]},{bK:"new return throw await else",r:0},{cN:"function",b:"("+d+"\\s+)+"+e.IR+"\\s*\\(",rB:!0,e:/\s*[{;=]/,eE:!0,k:t,c:[{b:e.IR+"\\s*\\(",rB:!0,c:[e.TM],r:0},{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,k:t,r:0,c:[u,r,e.CBCM]},e.CLCM,e.CBCM]}]}}),n.registerLanguage("css",function(e){var t={b:/[A-Z\_\.\-]+\s*:/,rB:!0,e:";",eW:!0,c:[{cN:"attribute",b:/\S/,e:":",eE:!0,starts:{eW:!0,eE:!0,c:[{b:/[\w-]+\(/,rB:!0,c:[{cN:"built_in",b:/[\w-]+/},{b:/\(/,e:/\)/,c:[e.ASM,e.QSM]}]},e.CSSNM,e.QSM,e.ASM,e.CBCM,{cN:"number",b:"#[0-9A-Fa-f]+"},{cN:"meta",b:"!important"}]}}]};return{cI:!0,i:/[=\/|'\$]/,c:[e.CBCM,{cN:"selector-id",b:/#[A-Za-z0-9_-]+/},{cN:"selector-class",b:/\.[A-Za-z0-9_-]+/},{cN:"selector-attr",b:/\[/,e:/\]/,i:"$"},{cN:"selector-pseudo",b:/:(:)?[a-zA-Z0-9\_\-\+\(\)"'.]+/},{b:"@(font-face|page)",l:"[a-z-]+",k:"font-face page"},{b:"@",e:"[{;]",i:/:/,c:[{cN:"keyword",b:/\w+/},{b:/\s/,eW:!0,eE:!0,r:0,c:[e.ASM,e.QSM,e.CSSNM]}]},{cN:"selector-tag",b:"[a-zA-Z-][a-zA-Z0-9_-]*",r:0},{b:"{",e:"}",i:/\S/,c:[e.CBCM,t]}]}}),n.registerLanguage("diff",function(e){return{aliases:["patch"],c:[{cN:"meta",r:10,v:[{b:/^@@ +\-\d+,\d+ +\+\d+,\d+ +@@$/},{b:/^\*\*\* +\d+,\d+ +\*\*\*\*$/},{b:/^\-\-\- +\d+,\d+ +\-\-\-\-$/}]},{cN:"comment",v:[{b:/Index: /,e:/$/},{b:/={3,}/,e:/$/},{b:/^\-{3}/,e:/$/},{b:/^\*{3} /,e:/$/},{b:/^\+{3}/,e:/$/},{b:/\*{5}/,e:/\*{5}$/}]},{cN:"addition",b:"^\\+",e:"$"},{cN:"deletion",b:"^\\-",e:"$"},{cN:"addition",b:"^\\!",e:"$"}]}}),n.registerLanguage("http",function(e){var t="HTTP/[0-9\\.]+";return{aliases:["https"],i:"\\S",c:[{b:"^"+t,e:"$",c:[{cN:"number",b:"\\b\\d{3}\\b"}]},{b:"^[A-Z]+ (.*?) "+t+"$",rB:!0,e:"$",c:[{cN:"string",b:" ",e:" ",eB:!0,eE:!0},{b:t},{cN:"keyword",b:"[A-Z]+"}]},{cN:"attribute",b:"^\\w",e:": ",eE:!0,i:"\\n|\\s|=",starts:{e:"$",r:0}},{b:"\\n\\n",starts:{sL:[],eW:!0}}]}}),n.registerLanguage("ini",function(e){var t={cN:"string",c:[e.BE],v:[{b:"'''",e:"'''",r:10},{b:'"""',e:'"""',r:10},{b:'"',e:'"'},{b:"'",e:"'"}]};return{aliases:["toml"],cI:!0,i:/\S/,c:[e.C(";","$"),e.HCM,{cN:"section",b:/^\s*\[+/,e:/\]+/},{b:/^[a-z0-9\[\]_\.-]+\s*=\s*/,e:"$",rB:!0,c:[{cN:"attr",b:/[a-z0-9\[\]_\.-]+/},{b:/=/,eW:!0,r:0,c:[{cN:"literal",b:/\bon|off|true|false|yes|no\b/},{cN:"variable",v:[{b:/\$[\w\d"][\w\d_]*/},{b:/\$\{(.*?)}/}]},t,{cN:"number",b:/([\+\-]+)?[\d]+_[\d_]+/},e.NM]}]}]}}),n.registerLanguage("java",function(e){var t="false synchronized int abstract float private char boolean var static null if const for true while long strictfp finally protected import native final void enum else break transient catch instanceof byte super volatile case assert short package default double public try this switch continue throws protected public private module requires exports do",r={cN:"number",b:"\\b(0[bB]([01]+[01_]+[01]+|[01]+)|0[xX]([a-fA-F0-9]+[a-fA-F0-9_]+[a-fA-F0-9]+|[a-fA-F0-9]+)|(([\\d]+[\\d_]+[\\d]+|[\\d]+)(\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))?|\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))([eE][-+]?\\d+)?)[lLfF]?",r:0};return{aliases:["jsp"],k:t,i:/<\/|#/,c:[e.C("/\\*\\*","\\*/",{r:0,c:[{b:/\w+@/,r:0},{cN:"doctag",b:"@[A-Za-z]+"}]}),e.CLCM,e.CBCM,e.ASM,e.QSM,{cN:"class",bK:"class interface",e:/[{;=]/,eE:!0,k:"class interface",i:/[:"\[\]]/,c:[{bK:"extends implements"},e.UTM]},{bK:"new throw return else",r:0},{cN:"function",b:"([À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*(<[À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*(\\s*,\\s*[À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*)*>)?\\s+)+"+e.UIR+"\\s*\\(",rB:!0,e:/[{;=]/,eE:!0,k:t,c:[{b:e.UIR+"\\s*\\(",rB:!0,r:0,c:[e.UTM]},{cN:"params",b:/\(/,e:/\)/,k:t,r:0,c:[e.ASM,e.QSM,e.CNM,e.CBCM]},e.CLCM,e.CBCM]},r,{cN:"meta",b:"@[A-Za-z]+"}]}}),n.registerLanguage("javascript",function(e){var t="[A-Za-z$_][0-9A-Za-z$_]*",r={keyword:"in of if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const export super debugger as async await static import from as",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document Symbol Set Map WeakSet WeakMap Proxy Reflect Promise"},a={cN:"number",v:[{b:"\\b(0[bB][01]+)"},{b:"\\b(0[oO][0-7]+)"},{b:e.CNR}],r:0},n={cN:"subst",b:"\\$\\{",e:"\\}",k:r,c:[]},i={cN:"string",b:"`",e:"`",c:[e.BE,n]};n.c=[e.ASM,e.QSM,i,a,e.RM];var s=n.c.concat([e.CBCM,e.CLCM]);return{aliases:["js","jsx"],k:r,c:[{cN:"meta",r:10,b:/^\s*['"]use (strict|asm)['"]/},{cN:"meta",b:/^#!/,e:/$/},e.ASM,e.QSM,i,e.CLCM,e.CBCM,a,{b:/[{,]\s*/,r:0,c:[{b:t+"\\s*:",rB:!0,r:0,c:[{cN:"attr",b:t,r:0}]}]},{b:"("+e.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[e.CLCM,e.CBCM,e.RM,{cN:"function",b:"(\\(.*?\\)|"+t+")\\s*=>",rB:!0,e:"\\s*=>",c:[{cN:"params",v:[{b:t},{b:/\(\s*\)/},{b:/\(/,e:/\)/,eB:!0,eE:!0,k:r,c:s}]}]},{b://,sL:"xml",c:[{b:/<\w+\s*\/>/,skip:!0},{b:/<\w+/,e:/(\/\w+|\w+\/)>/,skip:!0,c:[{b:/<\w+\s*\/>/,skip:!0},"self"]}]}],r:0},{cN:"function",bK:"function",e:/\{/,eE:!0,c:[e.inherit(e.TM,{b:t}),{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,c:s}],i:/\[|%/},{b:/\$[(.]/},e.METHOD_GUARD,{cN:"class",bK:"class",e:/[{;=]/,eE:!0,i:/[:"\[\]]/,c:[{bK:"extends"},e.UTM]},{bK:"constructor get set",e:/\{/,eE:!0}],i:/#(?!!)/}}),n.registerLanguage("json",function(e){var t={literal:"true false null"},r=[e.QSM,e.CNM],a={e:",",eW:!0,eE:!0,c:r,k:t},n={b:"{",e:"}",c:[{cN:"attr",b:/"/,e:/"/,c:[e.BE],i:"\\n"},e.inherit(a,{b:/:/})],i:"\\S"},i={b:"\\[",e:"\\]",c:[e.inherit(a)],i:"\\S"};return r.splice(r.length,0,n,i),{c:r,k:t,i:"\\S"}}),n.registerLanguage("makefile",function(e){var t={cN:"variable",v:[{b:"\\$\\("+e.UIR+"\\)",c:[e.BE]},{b:/\$[@%`]+/}]}]}]};return{aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist"],cI:!0,c:[{cN:"meta",b:"",r:10,c:[{b:"\\[",e:"\\]"}]},e.C("\x3c!--","--\x3e",{r:10}),{b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{cN:"meta",b:/<\?xml/,e:/\?>/,r:10},{b:/<\?(php)?/,e:/\?>/,sL:"php",c:[{b:"/\\*",e:"\\*/",skip:!0},{b:'b"',e:'"',skip:!0},{b:"b'",e:"'",skip:!0},e.inherit(e.ASM,{i:null,cN:null,c:null,skip:!0}),e.inherit(e.QSM,{i:null,cN:null,c:null,skip:!0})]},{cN:"tag",b:"|$)",e:">",k:{name:"style"},c:[t],starts:{e:"",rE:!0,sL:["css","xml"]}},{cN:"tag",b:"|$)",e:">",k:{name:"script"},c:[t],starts:{e:"<\/script>",rE:!0,sL:["actionscript","javascript","handlebars","xml"]}},{cN:"tag",b:"",c:[{cN:"name",b:/[^\/><\s]+/,r:0},t]}]}}),n.registerLanguage("markdown",function(e){return{aliases:["md","mkdown","mkd"],c:[{cN:"section",v:[{b:"^#{1,6}",e:"$"},{b:"^.+?\\n[=-]{2,}$"}]},{b:"<",e:">",sL:"xml",r:0},{cN:"bullet",b:"^([*+-]|(\\d+\\.))\\s+"},{cN:"strong",b:"[*_]{2}.+?[*_]{2}"},{cN:"emphasis",v:[{b:"\\*.+?\\*"},{b:"_.+?_",r:0}]},{cN:"quote",b:"^>\\s+",e:"$"},{cN:"code",v:[{b:"^```w*s*$",e:"^```s*$"},{b:"`.+?`"},{b:"^( {4}|\t)",e:"$",r:0}]},{b:"^[-\\*]{3,}",e:"$"},{b:"\\[.+?\\][\\(\\[].*?[\\)\\]]",rB:!0,c:[{cN:"string",b:"\\[",e:"\\]",eB:!0,rE:!0,r:0},{cN:"link",b:"\\]\\(",e:"\\)",eB:!0,eE:!0},{cN:"symbol",b:"\\]\\[",e:"\\]",eB:!0,eE:!0}],r:10},{b:/^\[[^\n]+\]:/,rB:!0,c:[{cN:"symbol",b:/\[/,e:/\]/,eB:!0,eE:!0},{cN:"link",b:/:\s*/,e:/$/,eB:!0}]}]}}),n.registerLanguage("nginx",function(e){var t={cN:"variable",v:[{b:/\$\d+/},{b:/\$\{/,e:/}/},{b:"[\\$\\@]"+e.UIR}]},r={eW:!0,l:"[a-z/_]+",k:{literal:"on off yes no true false none blocked debug info notice warn error crit select break last permanent redirect kqueue rtsig epoll poll /dev/poll"},r:0,i:"=>",c:[e.HCM,{cN:"string",c:[e.BE,t],v:[{b:/"/,e:/"/},{b:/'/,e:/'/}]},{b:"([a-z]+):/",e:"\\s",eW:!0,eE:!0,c:[t]},{cN:"regexp",c:[e.BE,t],v:[{b:"\\s\\^",e:"\\s|{|;",rE:!0},{b:"~\\*?\\s+",e:"\\s|{|;",rE:!0},{b:"\\*(\\.[a-z\\-]+)+"},{b:"([a-z\\-]+\\.)+\\*"}]},{cN:"number",b:"\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(:\\d{1,5})?\\b"},{cN:"number",b:"\\b\\d+[kKmMgGdshdwy]*\\b",r:0},t]};return{aliases:["nginxconf"],c:[e.HCM,{b:e.UIR+"\\s+{",rB:!0,e:"{",c:[{cN:"section",b:e.UIR}],r:0},{b:e.UIR+"\\s",e:";|{",rB:!0,c:[{cN:"attribute",b:e.UIR,starts:r}],r:0}],i:"[^\\s\\}]"}}),n.registerLanguage("objectivec",function(e){var t=/[a-zA-Z@][a-zA-Z0-9_]*/,r="@interface @class @protocol @implementation";return{aliases:["mm","objc","obj-c"],k:{keyword:"int float while char export sizeof typedef const struct for union unsigned long volatile static bool mutable if do return goto void enum else break extern asm case short default double register explicit signed typename this switch continue wchar_t inline readonly assign readwrite self @synchronized id typeof nonatomic super unichar IBOutlet IBAction strong weak copy in out inout bycopy byref oneway __strong __weak __block __autoreleasing @private @protected @public @try @property @end @throw @catch @finally @autoreleasepool @synthesize @dynamic @selector @optional @required @encode @package @import @defs @compatibility_alias __bridge __bridge_transfer __bridge_retained __bridge_retain __covariant __contravariant __kindof _Nonnull _Nullable _Null_unspecified __FUNCTION__ __PRETTY_FUNCTION__ __attribute__ getter setter retain unsafe_unretained nonnull nullable null_unspecified null_resettable class instancetype NS_DESIGNATED_INITIALIZER NS_UNAVAILABLE NS_REQUIRES_SUPER NS_RETURNS_INNER_POINTER NS_INLINE NS_AVAILABLE NS_DEPRECATED NS_ENUM NS_OPTIONS NS_SWIFT_UNAVAILABLE NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_END NS_REFINED_FOR_SWIFT NS_SWIFT_NAME NS_SWIFT_NOTHROW NS_DURING NS_HANDLER NS_ENDHANDLER NS_VALUERETURN NS_VOIDRETURN",literal:"false true FALSE TRUE nil YES NO NULL",built_in:"BOOL dispatch_once_t dispatch_queue_t dispatch_sync dispatch_async dispatch_once"},l:t,i:""}]}]},{cN:"class",b:"("+r.split(" ").join("|")+")\\b",e:"({|$)",eE:!0,k:r,l:t,c:[e.UTM]},{b:"\\."+e.UIR,r:0}]}}),n.registerLanguage("perl",function(e){var t="getpwent getservent quotemeta msgrcv scalar kill dbmclose undef lc ma syswrite tr send umask sysopen shmwrite vec qx utime local oct semctl localtime readpipe do return format read sprintf dbmopen pop getpgrp not getpwnam rewinddir qqfileno qw endprotoent wait sethostent bless s|0 opendir continue each sleep endgrent shutdown dump chomp connect getsockname die socketpair close flock exists index shmgetsub for endpwent redo lstat msgctl setpgrp abs exit select print ref gethostbyaddr unshift fcntl syscall goto getnetbyaddr join gmtime symlink semget splice x|0 getpeername recv log setsockopt cos last reverse gethostbyname getgrnam study formline endhostent times chop length gethostent getnetent pack getprotoent getservbyname rand mkdir pos chmod y|0 substr endnetent printf next open msgsnd readdir use unlink getsockopt getpriority rindex wantarray hex system getservbyport endservent int chr untie rmdir prototype tell listen fork shmread ucfirst setprotoent else sysseek link getgrgid shmctl waitpid unpack getnetbyname reset chdir grep split require caller lcfirst until warn while values shift telldir getpwuid my getprotobynumber delete and sort uc defined srand accept package seekdir getprotobyname semop our rename seek if q|0 chroot sysread setpwent no crypt getc chown sqrt write setnetent setpriority foreach tie sin msgget map stat getlogin unless elsif truncate exec keys glob tied closedirioctl socket readlink eval xor readline binmode setservent eof ord bind alarm pipe atan2 getgrent exp time push setgrent gt lt or ne m|0 break given say state when",r={cN:"subst",b:"[$@]\\{",e:"\\}",k:t},a={b:"->{",e:"}"},n={v:[{b:/\$\d/},{b:/[\$%@](\^\w\b|#\w+(::\w+)*|{\w+}|\w+(::\w*)*)/},{b:/[\$%@][^\s\w{]/,r:0}]},i=[e.BE,r,n],s=[n,e.HCM,e.C("^\\=\\w","\\=cut",{eW:!0}),a,{cN:"string",c:i,v:[{b:"q[qwxr]?\\s*\\(",e:"\\)",r:5},{b:"q[qwxr]?\\s*\\[",e:"\\]",r:5},{b:"q[qwxr]?\\s*\\{",e:"\\}",r:5},{b:"q[qwxr]?\\s*\\|",e:"\\|",r:5},{b:"q[qwxr]?\\s*\\<",e:"\\>",r:5},{b:"qw\\s+q",e:"q",r:5},{b:"'",e:"'",c:[e.BE]},{b:'"',e:'"'},{b:"`",e:"`",c:[e.BE]},{b:"{\\w+}",c:[],r:0},{b:"-?\\w+\\s*\\=\\>",c:[],r:0}]},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{b:"(\\/\\/|"+e.RSR+"|\\b(split|return|print|reverse|grep)\\b)\\s*",k:"split return print reverse grep",r:0,c:[e.HCM,{cN:"regexp",b:"(s|tr|y)/(\\\\.|[^/])*/(\\\\.|[^/])*/[a-z]*",r:10},{cN:"regexp",b:"(m|qr)?/",e:"/[a-z]*",c:[e.BE],r:0}]},{cN:"function",bK:"sub",e:"(\\s*\\(.*?\\))?[;{]",eE:!0,r:5,c:[e.TM]},{b:"-\\w\\b",r:0},{b:"^__DATA__$",e:"^__END__$",sL:"mojolicious",c:[{b:"^@@.*",e:"$",cN:"comment"}]}];return r.c=s,{aliases:["pl","pm"],l:/[\w\.]+/,k:t,c:a.c=s}}),n.registerLanguage("php",function(e){var t={b:"\\$+[a-zA-Z_-ÿ][a-zA-Z0-9_-ÿ]*"},r={cN:"meta",b:/<\?(php)?|\?>/},a={cN:"string",c:[e.BE,r],v:[{b:'b"',e:'"'},{b:"b'",e:"'"},e.inherit(e.ASM,{i:null}),e.inherit(e.QSM,{i:null})]},n={v:[e.BNM,e.CNM]};return{aliases:["php","php3","php4","php5","php6","php7"],cI:!0,k:"and include_once list abstract global private echo interface as static endswitch array null if endwhile or const for endforeach self var while isset public protected exit foreach throw elseif include __FILE__ empty require_once do xor return parent clone use __CLASS__ __LINE__ else break print eval new catch __METHOD__ case exception default die require __FUNCTION__ enddeclare final try switch continue endfor endif declare unset true false trait goto instanceof insteadof __DIR__ __NAMESPACE__ yield finally",c:[e.HCM,e.C("//","$",{c:[r]}),e.C("/\\*","\\*/",{c:[{cN:"doctag",b:"@[A-Za-z]+"}]}),e.C("__halt_compiler.+?;",!1,{eW:!0,k:"__halt_compiler",l:e.UIR}),{cN:"string",b:/<<<['"]?\w+['"]?$/,e:/^\w+;?$/,c:[e.BE,{cN:"subst",v:[{b:/\$\w+/},{b:/\{\$/,e:/\}/}]}]},r,{cN:"keyword",b:/\$this\b/},t,{b:/(::|->)+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/},{cN:"function",bK:"function",e:/[;{]/,eE:!0,i:"\\$|\\[|%",c:[e.UTM,{cN:"params",b:"\\(",e:"\\)",c:["self",t,e.CBCM,a,n]}]},{cN:"class",bK:"class interface",e:"{",eE:!0,i:/[:\(\$"]/,c:[{bK:"extends implements"},e.UTM]},{bK:"namespace",e:";",i:/[\.']/,c:[e.UTM]},{bK:"use",e:";",c:[e.UTM]},{b:"=>"},a,n]}}),n.registerLanguage("properties",function(e){var t="[ \\t\\f]*",r="("+t+"[:=]"+t+"|[ \\t\\f]+)",a="([^\\\\\\W:= \\t\\f\\n]|\\\\.)+",n="([^\\\\:= \\t\\f\\n]|\\\\.)+",i={e:r,r:0,starts:{cN:"string",e:/$/,r:0,c:[{b:"\\\\\\n"}]}};return{cI:!0,i:/\S/,c:[e.C("^\\s*[!#]","$"),{b:a+r,rB:!0,c:[{cN:"attr",b:a,endsParent:!0,r:0}],starts:i},{b:n+r,rB:!0,r:0,c:[{cN:"meta",b:n,endsParent:!0,r:0}],starts:i},{cN:"attr",r:0,b:n+t+"$"}]}}),n.registerLanguage("python",function(e){var t={keyword:"and elif is global as in if from raise for except finally print import pass return exec else break not with class assert yield try while continue del or def lambda async await nonlocal|10",built_in:"Ellipsis NotImplemented",literal:"False None True"},r={cN:"meta",b:/^(>>>|\.\.\.) /},a={cN:"subst",b:/\{/,e:/\}/,k:t,i:/#/},n={cN:"string",c:[e.BE],v:[{b:/(u|b)?r?'''/,e:/'''/,c:[e.BE,r],r:10},{b:/(u|b)?r?"""/,e:/"""/,c:[e.BE,r],r:10},{b:/(fr|rf|f)'''/,e:/'''/,c:[e.BE,r,a]},{b:/(fr|rf|f)"""/,e:/"""/,c:[e.BE,r,a]},{b:/(u|r|ur)'/,e:/'/,r:10},{b:/(u|r|ur)"/,e:/"/,r:10},{b:/(b|br)'/,e:/'/},{b:/(b|br)"/,e:/"/},{b:/(fr|rf|f)'/,e:/'/,c:[e.BE,a]},{b:/(fr|rf|f)"/,e:/"/,c:[e.BE,a]},e.ASM,e.QSM]},i={cN:"number",r:0,v:[{b:e.BNR+"[lLjJ]?"},{b:"\\b(0o[0-7]+)[lLjJ]?"},{b:e.CNR+"[lLjJ]?"}]},s={cN:"params",b:/\(/,e:/\)/,c:["self",r,i,n]};return a.c=[n,i,r],{aliases:["py","gyp","ipython"],k:t,i:/(<\/|->|\?)|=>/,c:[r,i,n,e.HCM,{v:[{cN:"function",bK:"def"},{cN:"class",bK:"class"}],e:/:/,i:/[${=;\n,]/,c:[e.UTM,s,{b:/->/,eW:!0,k:"None"}]},{cN:"meta",b:/^[\t ]*@/,e:/$/},{b:/\b(print|exec)\(/}]}}),n.registerLanguage("ruby",function(e){var t="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?",r={keyword:"and then defined module in return redo if BEGIN retry end for self when next until do begin unless END rescue else break undef not super class case require yield alias while ensure elsif or include attr_reader attr_writer attr_accessor",literal:"true false nil"},a={cN:"doctag",b:"@[A-Za-z]+"},n={b:"#<",e:">"},i=[e.C("#","$",{c:[a]}),e.C("^\\=begin","^\\=end",{c:[a],r:10}),e.C("^__END__","\\n$")],s={cN:"subst",b:"#\\{",e:"}",k:r},c={cN:"string",c:[e.BE,s],v:[{b:/'/,e:/'/},{b:/"/,e:/"/},{b:/`/,e:/`/},{b:"%[qQwWx]?\\(",e:"\\)"},{b:"%[qQwWx]?\\[",e:"\\]"},{b:"%[qQwWx]?{",e:"}"},{b:"%[qQwWx]?<",e:">"},{b:"%[qQwWx]?/",e:"/"},{b:"%[qQwWx]?%",e:"%"},{b:"%[qQwWx]?-",e:"-"},{b:"%[qQwWx]?\\|",e:"\\|"},{b:/\B\?(\\\d{1,3}|\\x[A-Fa-f0-9]{1,2}|\\u[A-Fa-f0-9]{4}|\\?\S)\b/},{b:/<<(-?)\w+$/,e:/^\s*\w+$/}]},o={cN:"params",b:"\\(",e:"\\)",endsParent:!0,k:r},l=[c,n,{cN:"class",bK:"class module",e:"$|;",i:/=/,c:[e.inherit(e.TM,{b:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?"}),{b:"<\\s*",c:[{b:"("+e.IR+"::)?"+e.IR}]}].concat(i)},{cN:"function",bK:"def",e:"$|;",c:[e.inherit(e.TM,{b:t}),o].concat(i)},{b:e.IR+"::"},{cN:"symbol",b:e.UIR+"(\\!|\\?)?:",r:0},{cN:"symbol",b:":(?!\\s)",c:[c,{b:t}],r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{cN:"params",b:/\|/,e:/\|/,k:r},{b:"("+e.RSR+"|unless)\\s*",k:"unless",c:[n,{cN:"regexp",c:[e.BE,s],i:/\n/,v:[{b:"/",e:"/[a-z]*"},{b:"%r{",e:"}[a-z]*"},{b:"%r\\(",e:"\\)[a-z]*"},{b:"%r!",e:"![a-z]*"},{b:"%r\\[",e:"\\][a-z]*"}]}].concat(i),r:0}].concat(i);s.c=l;var u=[{b:/^\s*=>/,starts:{e:"$",c:o.c=l}},{cN:"meta",b:"^([>?]>|[\\w#]+\\(\\w+\\):\\d+:\\d+>|(\\w+-)?\\d+\\.\\d+\\.\\d(p\\d+)?[^>]+>)",starts:{e:"$",c:l}}];return{aliases:["rb","gemspec","podspec","thor","irb"],k:r,i:/\/\*/,c:i.concat(u).concat(l)}}),n.registerLanguage("shell",function(e){return{aliases:["console"],c:[{cN:"meta",b:"^\\s{0,3}[\\w\\d\\[\\]()@-]*[>%$#]",starts:{e:"$",sL:"bash"}}]}}),n.registerLanguage("sql",function(e){var t=e.C("--","$");return{cI:!0,i:/[<>{}*]/,c:[{bK:"begin end start commit rollback savepoint lock alter create drop rename call delete do handler insert load replace select truncate update set show pragma grant merge describe use explain help declare prepare execute deallocate release unlock purge reset change stop analyze cache flush optimize repair kill install uninstall checksum restore check backup revoke comment values with",e:/;/,eW:!0,l:/[\w\.]+/,k:{keyword:"as abort abs absolute acc acce accep accept access accessed accessible account acos action activate add addtime admin administer advanced advise aes_decrypt aes_encrypt after agent aggregate ali alia alias all allocate allow alter always analyze ancillary and anti any anydata anydataset anyschema anytype apply archive archived archivelog are as asc ascii asin assembly assertion associate asynchronous at atan atn2 attr attri attrib attribu attribut attribute attributes audit authenticated authentication authid authors auto autoallocate autodblink autoextend automatic availability avg backup badfile basicfile before begin beginning benchmark between bfile bfile_base big bigfile bin binary_double binary_float binlog bit_and bit_count bit_length bit_or bit_xor bitmap blob_base block blocksize body both bound bucket buffer_cache buffer_pool build bulk by byte byteordermark bytes cache caching call calling cancel capacity cascade cascaded case cast catalog category ceil ceiling chain change changed char_base char_length character_length characters characterset charindex charset charsetform charsetid check checksum checksum_agg child choose chr chunk class cleanup clear client clob clob_base clone close cluster_id cluster_probability cluster_set clustering coalesce coercibility col collate collation collect colu colum column column_value columns columns_updated comment commit compact compatibility compiled complete composite_limit compound compress compute concat concat_ws concurrent confirm conn connec connect connect_by_iscycle connect_by_isleaf connect_by_root connect_time connection consider consistent constant constraint constraints constructor container content contents context contributors controlfile conv convert convert_tz corr corr_k corr_s corresponding corruption cos cost count count_big counted covar_pop covar_samp cpu_per_call cpu_per_session crc32 create creation critical cross cube cume_dist curdate current current_date current_time current_timestamp current_user cursor curtime customdatum cycle data database databases datafile datafiles datalength date_add date_cache date_format date_sub dateadd datediff datefromparts datename datepart datetime2fromparts day day_to_second dayname dayofmonth dayofweek dayofyear days db_role_change dbtimezone ddl deallocate declare decode decompose decrement decrypt deduplicate def defa defau defaul default defaults deferred defi defin define degrees delayed delegate delete delete_all delimited demand dense_rank depth dequeue des_decrypt des_encrypt des_key_file desc descr descri describ describe descriptor deterministic diagnostics difference dimension direct_load directory disable disable_all disallow disassociate discardfile disconnect diskgroup distinct distinctrow distribute distributed div do document domain dotnet double downgrade drop dumpfile duplicate duration each edition editionable editions element ellipsis else elsif elt empty enable enable_all enclosed encode encoding encrypt end end-exec endian enforced engine engines enqueue enterprise entityescaping eomonth error errors escaped evalname evaluate event eventdata events except exception exceptions exchange exclude excluding execu execut execute exempt exists exit exp expire explain explode export export_set extended extent external external_1 external_2 externally extract failed failed_login_attempts failover failure far fast feature_set feature_value fetch field fields file file_name_convert filesystem_like_logging final finish first first_value fixed flash_cache flashback floor flush following follows for forall force foreign form forma format found found_rows freelist freelists freepools fresh from from_base64 from_days ftp full function general generated get get_format get_lock getdate getutcdate global global_name globally go goto grant grants greatest group group_concat group_id grouping grouping_id groups gtid_subtract guarantee guard handler hash hashkeys having hea head headi headin heading heap help hex hierarchy high high_priority hosts hour hours http id ident_current ident_incr ident_seed identified identity idle_time if ifnull ignore iif ilike ilm immediate import in include including increment index indexes indexing indextype indicator indices inet6_aton inet6_ntoa inet_aton inet_ntoa infile initial initialized initially initrans inmemory inner innodb input insert install instance instantiable instr interface interleaved intersect into invalidate invisible is is_free_lock is_ipv4 is_ipv4_compat is_not is_not_null is_used_lock isdate isnull isolation iterate java join json json_exists keep keep_duplicates key keys kill language large last last_day last_insert_id last_value lateral lax lcase lead leading least leaves left len lenght length less level levels library like like2 like4 likec limit lines link list listagg little ln load load_file lob lobs local localtime localtimestamp locate locator lock locked log log10 log2 logfile logfiles logging logical logical_reads_per_call logoff logon logs long loop low low_priority lower lpad lrtrim ltrim main make_set makedate maketime managed management manual map mapping mask master master_pos_wait match matched materialized max maxextents maximize maxinstances maxlen maxlogfiles maxloghistory maxlogmembers maxsize maxtrans md5 measures median medium member memcompress memory merge microsecond mid migration min minextents minimum mining minus minute minutes minvalue missing mod mode model modification modify module monitoring month months mount move movement multiset mutex name name_const names nan national native natural nav nchar nclob nested never new newline next nextval no no_write_to_binlog noarchivelog noaudit nobadfile nocheck nocompress nocopy nocycle nodelay nodiscardfile noentityescaping noguarantee nokeep nologfile nomapping nomaxvalue nominimize nominvalue nomonitoring none noneditionable nonschema noorder nopr nopro noprom nopromp noprompt norely noresetlogs noreverse normal norowdependencies noschemacheck noswitch not nothing notice notnull notrim novalidate now nowait nth_value nullif nulls num numb numbe nvarchar nvarchar2 object ocicoll ocidate ocidatetime ociduration ociinterval ociloblocator ocinumber ociref ocirefcursor ocirowid ocistring ocitype oct octet_length of off offline offset oid oidindex old on online only opaque open operations operator optimal optimize option optionally or oracle oracle_date oradata ord ordaudio orddicom orddoc order ordimage ordinality ordvideo organization orlany orlvary out outer outfile outline output over overflow overriding package pad parallel parallel_enable parameters parent parse partial partition partitions pascal passing password password_grace_time password_lock_time password_reuse_max password_reuse_time password_verify_function patch path patindex pctincrease pctthreshold pctused pctversion percent percent_rank percentile_cont percentile_disc performance period period_add period_diff permanent physical pi pipe pipelined pivot pluggable plugin policy position post_transaction pow power pragma prebuilt precedes preceding precision prediction prediction_cost prediction_details prediction_probability prediction_set prepare present preserve prior priority private private_sga privileges procedural procedure procedure_analyze processlist profiles project prompt protection public publishingservername purge quarter query quick quiesce quota quotename radians raise rand range rank raw read reads readsize rebuild record records recover recovery recursive recycle redo reduced ref reference referenced references referencing refresh regexp_like register regr_avgx regr_avgy regr_count regr_intercept regr_r2 regr_slope regr_sxx regr_sxy reject rekey relational relative relaylog release release_lock relies_on relocate rely rem remainder rename repair repeat replace replicate replication required reset resetlogs resize resource respect restore restricted result result_cache resumable resume retention return returning returns reuse reverse revoke right rlike role roles rollback rolling rollup round row row_count rowdependencies rowid rownum rows rtrim rules safe salt sample save savepoint sb1 sb2 sb4 scan schema schemacheck scn scope scroll sdo_georaster sdo_topo_geometry search sec_to_time second seconds section securefile security seed segment select self semi sequence sequential serializable server servererror session session_user sessions_per_user set sets settings sha sha1 sha2 share shared shared_pool short show shrink shutdown si_averagecolor si_colorhistogram si_featurelist si_positionalcolor si_stillimage si_texture siblings sid sign sin size size_t sizes skip slave sleep smalldatetimefromparts smallfile snapshot some soname sort soundex source space sparse spfile split sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_small_result sql_variant_property sqlcode sqldata sqlerror sqlname sqlstate sqrt square standalone standby start starting startup statement static statistics stats_binomial_test stats_crosstab stats_ks_test stats_mode stats_mw_test stats_one_way_anova stats_t_test_ stats_t_test_indep stats_t_test_one stats_t_test_paired stats_wsr_test status std stddev stddev_pop stddev_samp stdev stop storage store stored str str_to_date straight_join strcmp strict string struct stuff style subdate subpartition subpartitions substitutable substr substring subtime subtring_index subtype success sum suspend switch switchoffset switchover sync synchronous synonym sys sys_xmlagg sysasm sysaux sysdate sysdatetimeoffset sysdba sysoper system system_user sysutcdatetime table tables tablespace tablesample tan tdo template temporary terminated tertiary_weights test than then thread through tier ties time time_format time_zone timediff timefromparts timeout timestamp timestampadd timestampdiff timezone_abbr timezone_minute timezone_region to to_base64 to_date to_days to_seconds todatetimeoffset trace tracking transaction transactional translate translation treat trigger trigger_nestlevel triggers trim truncate try_cast try_convert try_parse type ub1 ub2 ub4 ucase unarchived unbounded uncompress under undo unhex unicode uniform uninstall union unique unix_timestamp unknown unlimited unlock unnest unpivot unrecoverable unsafe unsigned until untrusted unusable unused update updated upgrade upped upper upsert url urowid usable usage use use_stored_outlines user user_data user_resources users using utc_date utc_timestamp uuid uuid_short validate validate_password_strength validation valist value values var var_samp varcharc vari varia variab variabl variable variables variance varp varraw varrawc varray verify version versions view virtual visible void wait wallet warning warnings week weekday weekofyear wellformed when whene whenev wheneve whenever where while whitespace window with within without work wrapped xdb xml xmlagg xmlattributes xmlcast xmlcolattval xmlelement xmlexists xmlforest xmlindex xmlnamespaces xmlpi xmlquery xmlroot xmlschema xmlserialize xmltable xmltype xor year year_to_month years yearweek",literal:"true false null unknown",built_in:"array bigint binary bit blob bool boolean char character date dec decimal float int int8 integer interval number numeric real record serial serial8 smallint text time timestamp tinyint varchar varying void"},c:[{cN:"string",b:"'",e:"'",c:[e.BE,{b:"''"}]},{cN:"string",b:'"',e:'"',c:[e.BE,{b:'""'}]},{cN:"string",b:"`",e:"`",c:[e.BE]},e.CNM,e.CBCM,t,e.HCM]},e.CBCM,t,e.HCM]}}),n}); \ No newline at end of file diff --git a/src/templates/src/fishbowls/oop/OOP_down.html_Files/lottie.min-99657.js b/src/templates/src/fishbowls/oop/OOP_down.html_Files/lottie.min-99657.js new file mode 100644 index 0000000..086aa59 --- /dev/null +++ b/src/templates/src/fishbowls/oop/OOP_down.html_Files/lottie.min-99657.js @@ -0,0 +1,15 @@ +(typeof navigator !== "undefined") && (function(root, factory) { + if (typeof define === "function" && define.amd) { + define(function() { + return factory(root); + }); + } else if (typeof module === "object" && module.exports) { + module.exports = factory(root); + } else { + root.lottie = factory(root); + root.bodymovin = root.lottie; + } +}((window || {}), function(window) { + "use strict";var svgNS="http://www.w3.org/2000/svg",locationHref="",initialDefaultFrame=-999999,_useWebWorker=!1,subframeEnabled=!0,idPrefix="",expressionsPlugin,isSafari=/^((?!chrome|android).)*safari/i.test(navigator.userAgent),cachedColors={},bmRnd,bmPow=Math.pow,bmSqrt=Math.sqrt,bmFloor=Math.floor,bmMax=Math.max,bmMin=Math.min,BMMath={};function ProjectInterface(){return{}}!function(){var t,e=["abs","acos","acosh","asin","asinh","atan","atanh","atan2","ceil","cbrt","expm1","clz32","cos","cosh","exp","floor","fround","hypot","imul","log","log1p","log2","log10","max","min","pow","random","round","sign","sin","sinh","sqrt","tan","tanh","trunc","E","LN10","LN2","LOG10E","LOG2E","PI","SQRT1_2","SQRT2"],r=e.length;for(t=0;t>>=1;return(t+r)/e};return n.int32=function(){return 0|a.g(4)},n.quick=function(){return a.g(4)/4294967296},n.double=n,P(E(a.S),o),(e.pass||r||function(t,e,r,i){return i&&(i.S&&b(i,a),t.state=function(){return b(a,{})}),r?(h[c]=t,e):t})(n,s,"global"in e?e.global:this==h,e.state)},P(h.random(),o)}([],BMMath);var BezierFactory=function(){var t={getBezierEasing:function(t,e,r,i,s){var a=s||("bez_"+t+"_"+e+"_"+r+"_"+i).replace(/\./g,"p");if(o[a])return o[a];var n=new h([t,e,r,i]);return o[a]=n}},o={};var l=11,p=1/(l-1),e="function"==typeof Float32Array;function i(t,e){return 1-3*e+3*t}function s(t,e){return 3*e-6*t}function a(t){return 3*t}function m(t,e,r){return((i(e,r)*t+s(e,r))*t+a(e))*t}function f(t,e,r){return 3*i(e,r)*t*t+2*s(e,r)*t+a(e)}function h(t){this._p=t,this._mSampleValues=e?new Float32Array(l):new Array(l),this._precomputed=!1,this.get=this.get.bind(this)}return h.prototype={get:function(t){var e=this._p[0],r=this._p[1],i=this._p[2],s=this._p[3];return this._precomputed||this._precompute(),e===r&&i===s?t:0===t?0:1===t?1:m(this._getTForX(t),r,s)},_precompute:function(){var t=this._p[0],e=this._p[1],r=this._p[2],i=this._p[3];this._precomputed=!0,t===e&&r===i||this._calcSampleValues()},_calcSampleValues:function(){for(var t=this._p[0],e=this._p[2],r=0;rn?-1:1,l=!0;l;)if(i[a]<=n&&i[a+1]>n?(o=(n-i[a])/(i[a+1]-i[a]),l=!1):a+=h,a<0||s-1<=a){if(a===s-1)return r[a];l=!1}return r[a]+(r[a+1]-r[a])*o}var F=createTypedArray("float32",8);return{getSegmentsLength:function(t){var e,r=segmentsLengthPool.newElement(),i=t.c,s=t.v,a=t.o,n=t.i,o=t._length,h=r.lengths,l=0;for(e=0;er[0]||!(r[0]>t[0])&&(t[1]>r[1]||!(r[1]>t[1])&&(t[2]>r[2]||!(r[2]>t[2])&&null))}var h,e=function(){var i=[4,4,14];function s(t){var e,r,i,s=t.length;for(e=0;e=a.t-i){s.h&&(s=a),c=0;break}if(a.t-i>t){c=d;break}d=r&&r<=t||this._caching.lastFrame=t&&(this._caching._lastKeyframeIndex=-1,this._caching.lastIndex=0);var i=this.interpolateValue(t,this._caching);this.pv=i}return this._caching.lastFrame=t,this.pv}function d(t){var e;if("unidimensional"===this.propType)e=t*this.mult,1e-5=this.p.keyframes[this.p.keyframes.length-1].t?(r=this.p.getValueAtTime(this.p.keyframes[this.p.keyframes.length-1].t/e,0),this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length-1].t-.05)/e,0)):(r=this.p.pv,this.p.getValueAtTime((this.p._caching.lastFrame+this.p.offsetTime-.01)/e,this.p.offsetTime));else if(this.px&&this.px.keyframes&&this.py.keyframes&&this.px.getValueAtTime&&this.py.getValueAtTime){r=[],i=[];var s=this.px,a=this.py;s._caching.lastFrame+s.offsetTime<=s.keyframes[0].t?(r[0]=s.getValueAtTime((s.keyframes[0].t+.01)/e,0),r[1]=a.getValueAtTime((a.keyframes[0].t+.01)/e,0),i[0]=s.getValueAtTime(s.keyframes[0].t/e,0),i[1]=a.getValueAtTime(a.keyframes[0].t/e,0)):s._caching.lastFrame+s.offsetTime>=s.keyframes[s.keyframes.length-1].t?(r[0]=s.getValueAtTime(s.keyframes[s.keyframes.length-1].t/e,0),r[1]=a.getValueAtTime(a.keyframes[a.keyframes.length-1].t/e,0),i[0]=s.getValueAtTime((s.keyframes[s.keyframes.length-1].t-.01)/e,0),i[1]=a.getValueAtTime((a.keyframes[a.keyframes.length-1].t-.01)/e,0)):(r=[s.pv,a.pv],i[0]=s.getValueAtTime((s._caching.lastFrame+s.offsetTime-.01)/e,s.offsetTime),i[1]=a.getValueAtTime((a._caching.lastFrame+a.offsetTime-.01)/e,a.offsetTime))}else r=i=n;this.v.rotate(-Math.atan2(r[1]-i[1],r[0]-i[0]))}this.data.p&&this.data.p.s?this.data.p.z?this.v.translate(this.px.v,this.py.v,-this.pz.v):this.v.translate(this.px.v,this.py.v,0):this.v.translate(this.p.v[0],this.p.v[1],-this.p.v[2])}this.frameId=this.elem.globalData.frameId}},precalculateMatrix:function(){if(!this.a.k&&(this.pre.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.appliedTransformations=1,!this.s.effectsSequence.length)){if(this.pre.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.appliedTransformations=2,this.sk){if(this.sk.effectsSequence.length||this.sa.effectsSequence.length)return;this.pre.skewFromAxis(-this.sk.v,this.sa.v),this.appliedTransformations=3}this.r?this.r.effectsSequence.length||(this.pre.rotate(-this.r.v),this.appliedTransformations=4):this.rz.effectsSequence.length||this.ry.effectsSequence.length||this.rx.effectsSequence.length||this.or.effectsSequence.length||(this.pre.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.appliedTransformations=4)}},autoOrient:function(){}},extendPrototype([DynamicPropertyContainer],i),i.prototype.addDynamicProperty=function(t){this._addDynamicProperty(t),this.elem.addDynamicProperty(t),this._isDirty=!0},i.prototype._addDynamicProperty=DynamicPropertyContainer.prototype.addDynamicProperty,{getTransformProperty:function(t,e,r){return new i(t,e,r)}}}();function ShapePath(){this.c=!1,this._length=0,this._maxLength=8,this.v=createSizedArray(this._maxLength),this.o=createSizedArray(this._maxLength),this.i=createSizedArray(this._maxLength)}ShapePath.prototype.setPathData=function(t,e){this.c=t,this.setLength(e);for(var r=0;r=this._maxLength&&this.doubleArrayLength(),r){case"v":a=this.v;break;case"i":a=this.i;break;case"o":a=this.o;break;default:a=[]}(!a[i]||a[i]&&!s)&&(a[i]=pointPool.newElement()),a[i][0]=t,a[i][1]=e},ShapePath.prototype.setTripleAt=function(t,e,r,i,s,a,n,o){this.setXYAt(t,e,"v",n,o),this.setXYAt(r,i,"o",n,o),this.setXYAt(s,a,"i",n,o)},ShapePath.prototype.reverse=function(){var t=new ShapePath;t.setPathData(this.c,this._length);var e=this.v,r=this.o,i=this.i,s=0;this.c&&(t.setTripleAt(e[0][0],e[0][1],i[0][0],i[0][1],r[0][0],r[0][1],0,!1),s=1);var a,n=this._length-1,o=this._length;for(a=s;a=c[c.length-1].t-this.offsetTime)i=c[c.length-1].s?c[c.length-1].s[0]:c[c.length-2].e[0],a=!0;else{for(var d,u,y,g=f,v=c.length-1,b=!0;b&&(d=c[g],!((u=c[g+1]).t-this.offsetTime>t));)g=u.t-this.offsetTime)p=1;else if(ti+r))p=o.s*s<=i?0:(o.s*s-i)/r,m=o.e*s>=i+r?1:(o.e*s-i)/r,h.push([p,m])}return h.length||h.push([0,0]),h},TrimModifier.prototype.releasePathsData=function(t){var e,r=t.length;for(e=0;ee.e){r.c=!1;break}e.s<=d&&e.e>=d+n.addedLength?(this.addSegment(f[i].v[s-1],f[i].o[s-1],f[i].i[s],f[i].v[s],r,o,y),y=!1):(l=bez.getNewSegment(f[i].v[s-1],f[i].v[s],f[i].o[s-1],f[i].i[s],(e.s-d)/n.addedLength,(e.e-d)/n.addedLength,h[s-1]),this.addSegmentFromArray(l,r,o,y),y=!1,r.c=!1),d+=n.addedLength,o+=1}if(f[i].c&&h.length){if(n=h[s-1],d<=e.e){var g=h[s-1].addedLength;e.s<=d&&e.e>=d+g?(this.addSegment(f[i].v[s-1],f[i].o[s-1],f[i].i[0],f[i].v[0],r,o,y),y=!1):(l=bez.getNewSegment(f[i].v[s-1],f[i].v[0],f[i].o[s-1],f[i].i[0],(e.s-d)/g,(e.e-d)/g,h[s-1]),this.addSegmentFromArray(l,r,o,y),y=!1,r.c=!1)}else r.c=!1;d+=n.addedLength,o+=1}if(r._length&&(r.setXYAt(r.v[p][0],r.v[p][1],"i",p),r.setXYAt(r.v[r._length-1][0],r.v[r._length-1][1],"o",r._length-1)),d>e.e)break;i=d.length&&(m=0,d=u[f+=1]?u[f].points:P.v.c?u[f=m=0].points:(l-=h.partialLength,null)),d&&(c=h,y=(h=d[m]).partialLength));L=T[s].an/2-T[s].add,C.translate(-L,0,0)}else L=T[s].an/2-T[s].add,C.translate(-L,0,0),C.translate(-E[0]*T[s].an*.005,-E[1]*R*.01,0);for(F=0;Fe);)r+=1;return this.keysIndex!==r&&(this.keysIndex=r),this.data.d.k[this.keysIndex].s},TextProperty.prototype.buildFinalText=function(t){for(var e,r,i=[],s=0,a=t.length,n=!1;sthis.minimumFontSize&&k=g(o)&&(n=u(0,y(t-o<0?y(h,1)-(o-t):h-t,1))),a(n));if(100!==this.sm.v){var c=.01*this.sm.v;0===c&&(c=1e-8);var d=.5-.5*c;nt-this.layers[e].st&&this.buildItem(e),this.completeLayers=!!this.elements[e]&&this.completeLayers;this.checkPendingElements()},BaseRenderer.prototype.createItem=function(t){switch(t.ty){case 2:return this.createImage(t);case 0:return this.createComp(t);case 1:return this.createSolid(t);case 3:return this.createNull(t);case 4:return this.createShape(t);case 5:return this.createText(t);case 6:return this.createAudio(t);case 13:return this.createCamera(t);case 15:return this.createFootage(t);default:return this.createNull(t)}},BaseRenderer.prototype.createCamera=function(){throw new Error("You're using a 3d camera. Try the html renderer.")},BaseRenderer.prototype.createAudio=function(t){return new AudioElement(t,this.globalData,this)},BaseRenderer.prototype.createFootage=function(t){return new FootageElement(t,this.globalData,this)},BaseRenderer.prototype.buildAllItems=function(){var t,e=this.layers.length;for(t=0;t=t)return this.threeDElements[e].perspectiveElem;e+=1}return null},HybridRenderer.prototype.createThreeDContainer=function(t,e){var r,i,s=createTag("div");styleDiv(s);var a=createTag("div");if(styleDiv(a),"3d"===e){(r=s.style).width=this.globalData.compSize.w+"px",r.height=this.globalData.compSize.h+"px";var n="50% 50%";r.webkitTransformOrigin=n,r.mozTransformOrigin=n,r.transformOrigin=n;var o="matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)";(i=a.style).transform=o,i.webkitTransform=o}s.appendChild(a);var h={container:a,perspectiveElem:s,startPos:t,endPos:t,type:e};return this.threeDElements.push(h),h},HybridRenderer.prototype.build3dContainers=function(){var t,e,r=this.layers.length,i="";for(t=0;tt?!0!==this.isInRange&&(this.globalData._mdf=!0,this._mdf=!0,this.isInRange=!0,this.show()):!1!==this.isInRange&&(this.globalData._mdf=!0,this.isInRange=!1,this.hide())},renderRenderable:function(){var t,e=this.renderableComponents.length;for(t=0;t=t.x+t.width&&this.currentBBox.height+this.currentBBox.y>=t.y+t.height},HShapeElement.prototype.renderInnerContent=function(){if(this._renderShapeFrame(),!this.hidden&&(this._isFirstFrame||this._mdf)){var t=this.tempBoundingBox,e=999999;if(t.x=e,t.xMax=-e,t.y=e,t.yMax=-e,this.calculateBoundingBox(this.itemsData,t),t.width=t.xMaxthis.animationData.op&&(this.animationData.op=t.op,this.totalFrames=Math.floor(t.op-this.animationData.ip));var e,r,i=this.animationData.layers,s=i.length,a=t.layers,n=a.length;for(r=0;rthis.timeCompleted&&(this.currentFrame=this.timeCompleted),this.trigger("enterFrame"),this.renderFrame(),this.trigger("drawnFrame")},AnimationItem.prototype.renderFrame=function(){if(!1!==this.isLoaded&&this.renderer)try{this.renderer.renderFrame(this.currentFrame+this.firstFrame)}catch(t){this.triggerRenderFrameError(t)}},AnimationItem.prototype.play=function(t){t&&this.name!==t||!0===this.isPaused&&(this.isPaused=!1,this.audioController.resume(),this._idle&&(this._idle=!1,this.trigger("_active")))},AnimationItem.prototype.pause=function(t){t&&this.name!==t||!1===this.isPaused&&(this.isPaused=!0,this._idle=!0,this.trigger("_idle"),this.audioController.pause())},AnimationItem.prototype.togglePause=function(t){t&&this.name!==t||(!0===this.isPaused?this.play():this.pause())},AnimationItem.prototype.stop=function(t){t&&this.name!==t||(this.pause(),this.playCount=0,this._completedLoop=!1,this.setCurrentRawFrameValue(0))},AnimationItem.prototype.getMarkerData=function(t){for(var e,r=0;r=this.totalFrames-1&&0=this.totalFrames?(this.playCount+=1,this.checkSegments(e%this.totalFrames)||(this.setCurrentRawFrameValue(e%this.totalFrames),this._completedLoop=!0,this.trigger("loopComplete"))):this.setCurrentRawFrameValue(e):this.checkSegments(e>this.totalFrames?e%this.totalFrames:0)||(r=!0,e=this.totalFrames-1):e<0?this.checkSegments(e%this.totalFrames)||(!this.loop||this.playCount--<=0&&!0!==this.loop?(r=!0,e=0):(this.setCurrentRawFrameValue(this.totalFrames+e%this.totalFrames),this._completedLoop?this.trigger("loopComplete"):this._completedLoop=!0)):this.setCurrentRawFrameValue(e),r&&(this.setCurrentRawFrameValue(e),this.pause(),this.trigger("complete"))}},AnimationItem.prototype.adjustSegment=function(t,e){this.playCount=0,t[1]t[0]&&(this.frameModifier<0&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(1)),this.totalFrames=t[1]-t[0],this.timeCompleted=this.totalFrames,this.firstFrame=t[0],this.setCurrentRawFrameValue(.001+e)),this.trigger("segmentStart")},AnimationItem.prototype.setSegment=function(t,e){var r=-1;this.isPaused&&(this.currentRawFrame+this.firstFramee&&(r=e-t)),this.firstFrame=t,this.totalFrames=e-t,this.timeCompleted=this.totalFrames,-1!==r&&this.goToAndStop(r,!0)},AnimationItem.prototype.playSegments=function(t,e){if(e&&(this.segments.length=0),"object"==typeof t[0]){var r,i=t.length;for(r=0;rdata.k[e].t&&tdata.k[e+1].t-t?(r=e+2,data.k[e+1].t):(r=e+1,data.k[e].t);break}}-1===r&&(r=e+1,i=data.k[e].t)}else i=r=0;var a={};return a.index=r,a.time=i/elem.comp.globalData.frameRate,a}function key(t){var e,r,i;if(!data.k.length||"number"==typeof data.k[0])throw new Error("The property has no keyframe at index "+t);t-=1,e={time:data.k[t].t/elem.comp.globalData.frameRate,value:[]};var s=Object.prototype.hasOwnProperty.call(data.k[t],"s")?data.k[t].s:data.k[t-1].e;for(i=s.length,r=0;rl.length-1)&&(e=l.length-1),i=p-(s=l[l.length-1-e].t)),"pingpong"===t){if(Math.floor((h-s)/i)%2!=0)return this.getValueAtTime((i-(h-s)%i+s)/this.comp.globalData.frameRate,0)}else{if("offset"===t){var m=this.getValueAtTime(s/this.comp.globalData.frameRate,0),f=this.getValueAtTime(p/this.comp.globalData.frameRate,0),c=this.getValueAtTime(((h-s)%i+s)/this.comp.globalData.frameRate,0),d=Math.floor((h-s)/i);if(this.pv.length){for(n=(o=new Array(m.length)).length,a=0;al.length-1)&&(e=l.length-1),i=(s=l[e].t)-p),"pingpong"===t){if(Math.floor((p-h)/i)%2==0)return this.getValueAtTime(((p-h)%i+p)/this.comp.globalData.frameRate,0)}else{if("offset"===t){var m=this.getValueAtTime(p/this.comp.globalData.frameRate,0),f=this.getValueAtTime(s/this.comp.globalData.frameRate,0),c=this.getValueAtTime((i-(p-h)%i+p)/this.comp.globalData.frameRate,0),d=Math.floor((p-h)/i)+1;if(this.pv.length){for(n=(o=new Array(m.length)).length,a=0;an){var p=o,m=r.c&&o===h-1?0:o+1,f=(n-l)/a[o].addedLength;i=bez.getPointInSegment(r.v[p],r.v[m],r.o[p],r.i[m],f,a[o]);break}l+=a[o].addedLength,o+=1}return i||(i=r.c?[r.v[0][0],r.v[0][1]]:[r.v[r._length-1][0],r.v[r._length-1][1]]),i},vectorOnPath:function(t,e,r){1==t?t=this.v.c:0==t&&(t=.999);var i=this.pointOnPath(t,e),s=this.pointOnPath(t+.001,e),a=s[0]-i[0],n=s[1]-i[1],o=Math.sqrt(Math.pow(a,2)+Math.pow(n,2));return 0===o?[0,0]:"tangent"===r?[a/o,n/o]:[-n/o,a/o]},tangentOnPath:function(t,e){return this.vectorOnPath(t,e,"tangent")},normalOnPath:function(t,e){return this.vectorOnPath(t,e,"normal")},setGroupProperty:expressionHelpers.setGroupProperty,getValueAtTime:expressionHelpers.getStaticValueAtTime},extendPrototype([r],t),extendPrototype([r],e),e.prototype.getValueAtTime=function(t){return this._cachingAtTime||(this._cachingAtTime={shapeValue:shapePool.clone(this.pv),lastIndex:0,lastTime:initialDefaultFrame}),t*=this.elem.globalData.frameRate,(t-=this.offsetTime)!==this._cachingAtTime.lastTime&&(this._cachingAtTime.lastIndex=this._cachingAtTime.lastTime \ No newline at end of file diff --git a/src/templates/src/fishbowls/oop/OOP_down.html_Files/twemoji_1f4af.svg b/src/templates/src/fishbowls/oop/OOP_down.html_Files/twemoji_1f4af.svg new file mode 100644 index 0000000..3d565cc --- /dev/null +++ b/src/templates/src/fishbowls/oop/OOP_down.html_Files/twemoji_1f4af.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/templates/src/fishbowls/oop/OOP_down.html_Files/twemoji_1f604.svg b/src/templates/src/fishbowls/oop/OOP_down.html_Files/twemoji_1f604.svg new file mode 100644 index 0000000..99ac39c --- /dev/null +++ b/src/templates/src/fishbowls/oop/OOP_down.html_Files/twemoji_1f604.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/templates/src/fishbowls/oop/OOP_down.html_Files/twemoji_1f605.svg b/src/templates/src/fishbowls/oop/OOP_down.html_Files/twemoji_1f605.svg new file mode 100644 index 0000000..de6eb5d --- /dev/null +++ b/src/templates/src/fishbowls/oop/OOP_down.html_Files/twemoji_1f605.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/templates/src/fishbowls/oop/OOP_down.html_Files/twemoji_1f608.svg b/src/templates/src/fishbowls/oop/OOP_down.html_Files/twemoji_1f608.svg new file mode 100644 index 0000000..79c2480 --- /dev/null +++ b/src/templates/src/fishbowls/oop/OOP_down.html_Files/twemoji_1f608.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/templates/src/fishbowls/oop/OOP_down.html_Files/twemoji_1f61b.svg b/src/templates/src/fishbowls/oop/OOP_down.html_Files/twemoji_1f61b.svg new file mode 100644 index 0000000..e249672 --- /dev/null +++ b/src/templates/src/fishbowls/oop/OOP_down.html_Files/twemoji_1f61b.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/templates/src/fishbowls/oop/OOP_down.html_Files/twemoji_1f642.svg b/src/templates/src/fishbowls/oop/OOP_down.html_Files/twemoji_1f642.svg new file mode 100644 index 0000000..ff9f989 --- /dev/null +++ b/src/templates/src/fishbowls/oop/OOP_down.html_Files/twemoji_1f642.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/templates/src/fishbowls/oop/OOP_down.html_Files/twemoji_1f914.svg b/src/templates/src/fishbowls/oop/OOP_down.html_Files/twemoji_1f914.svg new file mode 100644 index 0000000..4e8c4cc --- /dev/null +++ b/src/templates/src/fishbowls/oop/OOP_down.html_Files/twemoji_1f914.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/templates/src/fishbowls/oop/OOP_down.html_Files/whitney-300-1FE35.woff b/src/templates/src/fishbowls/oop/OOP_down.html_Files/whitney-300-1FE35.woff new file mode 100644 index 0000000..dc91427 Binary files /dev/null and b/src/templates/src/fishbowls/oop/OOP_down.html_Files/whitney-300-1FE35.woff differ diff --git a/src/templates/src/fishbowls/oop/OOP_down.html_Files/whitney-400-83E7B.woff b/src/templates/src/fishbowls/oop/OOP_down.html_Files/whitney-400-83E7B.woff new file mode 100644 index 0000000..2b33081 Binary files /dev/null and b/src/templates/src/fishbowls/oop/OOP_down.html_Files/whitney-400-83E7B.woff differ diff --git a/src/templates/src/fishbowls/oop/OOP_down.html_Files/whitney-500-47E37.woff b/src/templates/src/fishbowls/oop/OOP_down.html_Files/whitney-500-47E37.woff new file mode 100644 index 0000000..fc82138 Binary files /dev/null and b/src/templates/src/fishbowls/oop/OOP_down.html_Files/whitney-500-47E37.woff differ diff --git a/src/templates/src/fishbowls/oop/OOP_down.html_Files/whitney-600-9EC09.woff b/src/templates/src/fishbowls/oop/OOP_down.html_Files/whitney-600-9EC09.woff new file mode 100644 index 0000000..598a6f8 Binary files /dev/null and b/src/templates/src/fishbowls/oop/OOP_down.html_Files/whitney-600-9EC09.woff differ diff --git a/src/templates/src/fishbowls/oop/OOP_down.html_Files/whitney-700-A7A71.woff b/src/templates/src/fishbowls/oop/OOP_down.html_Files/whitney-700-A7A71.woff new file mode 100644 index 0000000..50565a3 Binary files /dev/null and b/src/templates/src/fishbowls/oop/OOP_down.html_Files/whitney-700-A7A71.woff differ diff --git a/src/templates/src/fishbowls/oop/OOP_down.html_Files/y18-27627.gif b/src/templates/src/fishbowls/oop/OOP_down.html_Files/y18-27627.gif new file mode 100644 index 0000000..2f2daa8 Binary files /dev/null and b/src/templates/src/fishbowls/oop/OOP_down.html_Files/y18-27627.gif differ diff --git a/src/templates/src/fishbowls/oop/index.html b/src/templates/src/fishbowls/oop/index.html new file mode 100644 index 0000000..ccb99aa --- /dev/null +++ b/src/templates/src/fishbowls/oop/index.html @@ -0,0 +1,12287 @@ +
+ + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
bvisness
+
+ +Topic: What, if anything, is OOP? + +
+
+
+ bvisness + + + 28-May-22 09:58 AM +
+ + + + + +
+
+
+
+
+
+
09:58
+
+ +
+ +
+ Welcome to yet another fishbowl, everyone! Just setting things up here. The main conversation is here in this thread, and the #fishbowl-audience conversation starts here: https://discord.com/channels/239737791225790464/708458209131757598/980155512412864552 + +The pinned messages are some "checkpoints" in the discussion; chapter markers of sorts. Check them out if there's a specific aspect of the discussion you'd like to see. + + (edited) +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ gingerBill + + + 28-May-22 09:59 AM +
+ +
+ Welcome, everyone! + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 10:00 AM +
+ +
+ Hi! + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 10:01 AM +
+ +
+ So, this fishbowl is a long time coming. Since the dawn of the network, many people have asked the question: Is object-oriented programming bad, or what? + +
+ + + + +
+
+ 💥 + 4 +
+
+
+
+
+
+
+
+
10:02
+
+ +
+ +
+ That is, unfortunately, not a very nuanced question. 🙂 + +
+ + + + +
+
+
+
+
+
+
10:02
+
+ +
+ +
+ Our conversations about OOP often veer in a lot of different directions, and the subject is hard to discuss productively because it means so many different things to different people. + +
+ + + + +
+
+
+
+
+
+
10:04
+
+ +
+ +
+ There are many different ideas that are bundled into the modern concept of "object-oriented programming". There are also many languages that have taken on these ideas with different decisions and tradeoffs. Our goal in this fishbowl is to break this subject down and discuss these different concepts with more nuance. + +
+ + + + +
+
+
+
+
+
+
10:04
+
+ +
+ +
+ To that end, we're doing things just a little bit differently for this one. Each of our esteemed participants have picked a particular aspect of "OOP" to present, and we'll be working through those over the course of the conversation here. + +
+ + + + +
+
+
+
+
+
+
10:04
+
+ +
+ +
+ On that note, let me introduce our participants: + +
+ + + + +
+
+
+
+
+
+
10:05
+
+ +
+ +
+ - me (hi) + +
+ + + + +
+
+
+
+
+
+
10:05
+
+ +
+ +
+ - @demetrispanos, general wise elder of the community with particular expertise in machine learning and artificial intelligence + +
+ + + + +
+
+
+
+
+
+
10:06
+
+ +
+ +
+ - @gingerBill, creator of the Odin programming language + +
+ + + + +
+
+
+
+
+
+
10:07
+
+ +
+ +
+ - @Kartik Agaram, creator of creative and very low-level programming systems / operating systems such as Mu and Teliva (look them up!) + +
+ + + + +
+
+
+
+
+
+
10:08
+
+ +
+ +
+ - @SirWhinesalot, a community member whose comments were instrumental to the planning process for this fishbowl (if there are projects you've worked on that I'm not aware of, let me know and I'll update this introduction 😅) + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 10:08 AM +
+ +
+ none public 🙂 + +
+ + + + +
+
+
+
+
+
+
10:08
+
+ +
+ +
+ but my expertise is in Domain-Specific Languages and Constraint Solving + +
+ + + + +
+
+ ❗ + 1 +
+
+
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 10:08 AM +
+ +
+ 👍 + +
+ + + + +
+
+
+
+
+
+
10:09
+
+ +
+ +
+ Before we get into the various modern conceptions of OOP, I think it would be good to take a look back at the history of object-oriented programming, and the path that we took to get to where we are today. @Kartik Agaram has graciously volunteered to walk us through that history, so - take it away, Kartik! + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 10:10 AM +
+ +
+ Is this thing on? Ok, let me paste in some prepared remarks. A quick, opinionated timeline of the major ideas that make up OO. + +
+ + + + +
+
+
+
+
+
+
10:10
+
+ +
+ +
+ 1958-1966: A few different people gradually come up with the notion of structured data. Conventions for managing compound data made of multiple words in memory. If you have two points, you want their x and y coordinates close together and in the same relative order. Seems obvious, but wasn't! See http://akkartik.name/sketchpad-oo.png from the Sketchpad thesis [1]. + +1960-1962: Ivan Sutherland works on Sketchpad. It presages many OO ideas, but they're all in the programmer's mind and prose (thesis) because the code is all machine code. + +1961-1962: Simula provides language support for many OO ideas: objects, classes, inheritance, dispatch based on the precise class of an object (virtual methods).[2] + +1960-1975: Data first. This was mostly a mindset thing, but led eventually to notation like obj.method. Had spread fairly wide by around 1975, when Fred Brooks said, "show me your code and I'll be mystified. Show me your data structures and the code will be obvious." [3] + +1973-1975: Abstract data types by Barbara Liskov. Ignore internal details of how objects are laid out in memory. Focus instead on a small vocabulary of operations that can be performed using them. Interfaces, basically.[4] + +1966-1975: Alan Kay coins OO after working on Smalltalk. (The first chapter of http://gagne.homedns.org/~tgagne/contrib/EarlyHistoryST.html is better than my history above.) "Did not have C++ in mind." However, we're only halfway done. + + (edited) +
+ + +
+ + Embedded image + +
+ + +
+
+
+
+
+
+
10:11
+
+ +
+ +
+ 1970-1975: Lexical scope comes into its own, and leads naturally to closures.[5] + +1980-1994: Lisp has been evolving largely in parallel, but now starts to cross-pollinate with OO. MIT Flavors (1982), CommonLOOPS (1986), CLOS (1994). OO is big on late binding. Lisp takes late binding to 11, with before/after advice and dispatch based on the types of multiple arguments. In 1994, Common Lisp decides to adopt lexical scope by default. + +1992: It becomes clear that there's a yin-yang duality between objects and closures.[6] Though objects have the benefit of putting data first. + +1994: The "gang of four" writes the Design Patterns book, based on ideas by the architect Christopher Alexander. Kicks off the field of OO design. + +2001: Joel Spolsky coins "architecture astronauts,"[7] peak of hype cycle for design patterns. (OO design remains in vogue to this day, though.) + +2007: Clojure arrives. Built on an OO foundation (the JVM) but determinedly anti-OO. Peak of the hype cycle for OO? Functional programming is now ascendant, impelled by the value of immutability. + +2008-2014: Growing anti-OO sentiment[8], anti-design-patterns sentiment[9], awareness that composition is superior to inheritance[10]. + +2020: Richard Feldman crystallizes the case against OO[11]: OO wants to make every object a little computer. But why do we want to make all programs distributed? + +
+ + + + +
+
+
+ +
+
+
+
10:12
+
+ +
+ +
+ Ok I'm done 🙂 Summary: there's a lot of ideas baked into "OO". Most of them are great. Some of them are showing their age. And unbundling them all feels more useful than treating them monolithically. End prepared remarks 🙂 + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 10:14 AM +
+ +
+ Excellent, this is a wonderful place to start. I appreciate that you included a lot of the recent takes on OO; I think we'll especially be revisiting a lot of the 2001-present takes as we go along. + +
+ + + + +
+
+
+
+
+
+
10:16
+
+ +
+ +
+ For some more context, what languages were in use around the 60s-70s when Brooks said that quote about data structures, and when Liskov was pioneering abstract data types? + +
+ + + + +
+
+
+
+
+
+
10:16
+
+ +
+ +
+ In general I'm curious how some of these early ideas manifested in the tools that we now use today. (I know Java was a big one along the way, and we'll have a nice long section dedicated just to that...) + + (edited) +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 10:18 AM +
+ +
+ I know CLU (Barbara Liskov's language) came out in 1973 + +
+ + + + +
+
+
+
+
+
+
10:18
+
+ +
+ +
+ Interestingly it was the first language with built-in Tagged Unions as far as I know + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 10:19 AM +
+ +
+ Oh gosh. I wasn't around then 🙂 but my weak sense is that while there were a few different programming languages being researched, the vast majority of people were programming in machine code and Assembly back then. Big ones: Fortran, COBOL, Algol (still getting refined), Lisp 1.5. + +
+ + + + +
+
+
+
+
+
+
10:20
+
+ +
+ +
+ @SirWhinesalot Yes, I think so! Too bad it took so long for them to go "mainstream". + +
+ + + + +
+
+
+
+
+
+
10:21
+
+ +
+ +
+ Going back to that Brooks quote. I think he was mostly talking about how programmers communicate. Languages and compilers weren't really the dominant gatekeepers of notation back then. + +
+ + + + +
+
+
+
+
+
+
10:21
+
+ +
+ +
+ It was paper, in some form. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 10:21 AM +
+ +
+ That makes sense, I suppose that would be the case + +
+ + + + +
+
+
+
+
+
+
10:22
+
+ +
+ +
+ The sense that I get (which may not be very accurate) is that in the 60s and 70s, there was a lot of pioneering work in the field happening mostly in parallel, but that the ideas hadn't really taken hold in "industry" yet. At what point would you say that began to occur? + + (edited) +
+ + + + +
+
+
+
+
+
+
10:22
+
+ +
+ +
+ Certainly from what I've seen of e.g. FORTRAN, the "practical tools" of the day didn't have any such concepts. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 10:25 AM +
+ +
+ That's a good question. I have a hard time thinking of descriptions of production systems and languages used by industry. Even though Bell Labs and PARC came from industry, I think a lot of their work was fed by govt. grants and so tightly coupled with govt. rather than commercial considerations. + +The software industry took off around late 70s? And then it took a while to rediscover the value of programming languages as the PC revolution took off and computers got fast enough to manage HLLs. + +
+ + + + +
+
+
+
+
+
+
10:25
+
+ +
+ +
+ Turbo Pascal was 1983. That was really my introduction to high-level languages. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 10:26 AM +
+ +
+ I know @gingerBill is quite a Pascal fan; I don't know if he would know any more about the history there + +
+ + + + +
+
+
+
+
+
+
10:26
+
+ +
+ +
+ or at least a Wirth fan 🙂 + +
+ + + + +
+
+ ❤️ + 3 +
+
+
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ gingerBill + + + 28-May-22 10:27 AM +
+ +
+ The first Pascal was created by Niklaus Wirth in 1970 as a teaching tool. + +
+ + + + +
+
+
+
+
+
+
10:27
+
+ +
+ +
+ It mostly became popular because of its simplicity and that it was easy to learn, especially amongst many of the minicomputer buyers in the 1970s. + +
+ + + + +
+
+
+
+
+
+
10:28
+
+ +
+ +
+ Pascal (along with C) are part of a language family called ALGOL, specifically ALGOL 60. + +
+ + + + +
+
+
+
+
+
+
10:28
+
+ +
+ +
+ ALGOL is the basis of pretty much every imperative (procedural) programming language to date. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 10:30 AM +
+ +
+ It's honestly pretty crazy to me to look at the timeline here and see that nearly all these fundamental OOP-y designs were all developed independently at around the same time. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ gingerBill + + + 28-May-22 10:31 AM +
+ +
+ ALGOL 60 was created by many designers with many famous names too: +John Backus, Peter Naur (yes, those two of Backus-Naur Form), Friedrich Bauer (discovered the stack data structure), Charles Katz (you'll see his name in many papers), John McCarthy (AI, Lisp, etc), Alan Perlis (APL), and many many more. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 10:31 AM +
+ +
+ And then the whole academic side runs out of steam in the 2000s, in my mind.. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ gingerBill + + + 28-May-22 10:32 AM +
+ +
+ There's the basic history lesson for the roots of all imperative programming languages, as well as some others like Lisp and APL. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 10:33 AM +
+ +
+ The 1980s to early 1990s is when OOP really starts picking up steam, Object Pascal, Objective-C, C++, COM, all culminating in Java in 1995 + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 10:33 AM +
+ +
+ I think I can see traces of all these historical ideas in the languages we use today, and perhaps we can refer back to this list as we go + +
+ + + + +
+
+
+
+
+
+
10:33
+
+ +
+ +
+ What Bill is saying about imperative programming languages may accidentally be a good segue into the first major concept of OOP that I have on my list... + +
+ + + + +
+
+
+
+
+
+
10:34
+
+ +
+ +
+ Which is that OOP is when you associate behavior with data, in a sense just the idea of a "method". (I am not saying this is a completely correct concept, but it is one that I see frequently discussed.) + + (edited) +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ gingerBill + + + 28-May-22 10:34 AM +
+ +
+ One really important thing that I would love to bring up before we dive deep into the philosophy questions is the distinction between Object-Oriented Programming (OOP) and Methods, and why I think this is at the heart of the discussion. + + (edited) +
+ + + + +
+
+
+
+
+
+
10:35
+
+ +
+ +
+ I'd argue that 99% of the reasons people want methods (and what many mean by "OOP" in a weird sense) are for the following reasons: + + (1) Organizing procedures under a data type + + (2) Allowing methods as a form syntactic sugar for writing calls in a subject verb object manner, e.g. do_thing(x, y) vs x.do_thing(y) + + (3) Searching for procedures/methods by a data type, especially with the aid of tools such as an IDE + +Regarding (1), I personally believe this is much better solved with a well designed package/module/library system as part of the language. Most OOP languages do not have such a system and usually use classes as a means to organize code. For my programming language Odin, packages have really aided us in terms of organization a lot better than + +Regarding (2), this is a weird linguistic typology thing which I doubt most people will even know unless they speak multiple languages. If you want to learn more about word orders in different languages, I recommend reading the following: + + * https://en.wikipedia.org/wiki/Subject%E2%80%93verb%E2%80%93object_word_order + * https://en.wikipedia.org/wiki/Verb%E2%80%93subject%E2%80%93object_word_order + + +Regarding (3), this is purely a tooling issue. It comes down to two main aspects: + + * Many people just want to use the tools that they have and how they currently work (there is nothing wrong with that, per se) + * Many people cannot think outside of the current paradigm and think what is being asked for is not possible + + +Doing foo. and waiting for the IDE to autocomplete what is available for that value of a specific data type is extremely useful to many people, but there is not reason it could not work for something that was purely procedural, it is that many languages nowadays do support some form of methods and thus the general need has not arisen. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 10:36 AM +
+ +
+ Like Common Lisp's generic methods. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 10:36 AM +
+ +
+ So in your opinion, is it not correct to say that "associating behavior with data" is essential to OOP, because all functions are associated with some form of data? (Regardless of syntax?) + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 10:37 AM +
+ +
+ "mere methods" (Lua is a good example of this, where they're just sugar for passing in the "subject" pointer) are IMO roughly analogous to for-loops or if-blocks, i.e. a syntactic standardization of a widespread common practice + +
+ + + + +
+
+
+
+
+
+
10:37
+
+ +
+ +
+ "procedural programming" could be seen as just standardizing a handful of assembly language idioms into language constructs + +
+ + + + +
+
+
+
+
+
+
10:37
+
+ +
+ +
+ "mere methods" are, for me, just more of this + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 10:38 AM +
+ +
+ they standardize the pattern
struct mything { + // whatever +} + +void mything_do_cool_stuff (struct mything *m, int x) { + // whatever +}
+ +
+ + + + +
+
+
+
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 10:38 AM +
+ +
+ I would agree with @demetrispanos and @gingerBill , methods as in the little . notation and OOP are independent concerns + +
+ + + + +
+
+
+
+ + + + + + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
demetrispanos
+
+ +they standardize the pattern
struct mything { + // whatever +} + +void mything_do_cool_stuff (struct mything *m, int x) { + // whatever +}
+ +
+
+
+ SirWhinesalot + + + 28-May-22 10:39 AM +
+ +
+ importantly, note how in the pattern above the function is not tied to struct, you can keep adding as many functions as you want + +
+ + + + +
+
+
+
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 10:39 AM +
+ +
+ in OOP, classes have a fixed set of methods, usually + +
+ + + + +
+
+
+
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
SirWhinesalot
+
+ +importantly, note how in the pattern above the function is not tied to struct, you can keep adding as many functions as you want + +
+
+
+ demetrispanos + + + 28-May-22 10:40 AM +
+ +
+ yes exactly, that's part of what I mean by "mere" (i.e. they're not wound up in some other concept like a class) + +
+ + + + +
+
+
+
+
+
+
+ Avatar +
+ +
+
+ gingerBill + + + 28-May-22 10:39 AM +
+ +
+ Lua is an example of something I'd like to call an Emergent OO Programming Language , but I'll leave that for a little later to reduce confusion. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ gingerBill + + + 28-May-22 10:40 AM +
+ +
+ Lua after all is a table oriented language. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 10:39 AM +
+ +
+ There's a few of those 😄 + +
+ + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
SirWhinesalot
+
+ +in OOP, classes have a fixed set of methods, usually + +
+
+
+ Kartik Agaram + + + 28-May-22 10:40 AM +
+ +
+ "open to extension" is another wonderful idea we should discuss at some point. ❤️ Ruby + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 10:40 AM +
+ +
+ Smalltalk as well + +
+ + + + +
+
+ 💡 + 1 +
+
+
+
+
+
+ + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
demetrispanos
+
+ +yes exactly, that's part of what I mean by "mere" (i.e. they're not wound up in some other concept like a class) + +
+
+
+ bvisness + + + 28-May-22 10:40 AM +
+ +
+ Would you elaborate on what extra ideas a "class" adds to the picture? + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 10:42 AM +
+ +
+ I'd say a "mere class" is a struct with a fixed set of "mere methods" (echoing some comments from above) + +
+ + + + +
+
+
+
+
+
+
10:42
+
+ +
+ +
+ but classes as practiced add more ideas like visibility, inheritance, etc. + +
+ + + + +
+
+
+
+
+
+
10:43
+
+ +
+ +
+ I'd note that while "mere methods" are IMO definitely useful, it's not clear to me what you get from a "mere class" + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 10:43 AM +
+ +
+ I think a mere class only becomes useful when subtype polymorphism is involved (i.e., a vtable of some sort) + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 10:43 AM +
+ +
+ ah yes, good point + +
+ + + + +
+
+
+
+
+
+
10:43
+
+ +
+ +
+ I agree + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 10:44 AM +
+ +
+ The evolution I tend to see is: +* Putting the primary data type first is a nice way to organize vocabularies in people's minds. (I think this is what y'all mean by "mere methods") +* Once you do that, you can also generalize and allow different types to do different things. That pulls in inheritance and static dispatch. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 10:45 AM +
+ +
+
* Putting the primary data type first is a nice way to organize vocabularies in people's minds. (I think this is what y'all mean by "mere methods") +
yes
+ +
+ + + + +
+
+
+
+
+
+
10:46
+
+ +
+ +
+ but importantly, the generalization of mere methods has consequences + +
+ + + + +
+
+
+
+
+
+
10:47
+
+ +
+ +
+ because the set of methods is usually fixed + +
+ + + + +
+
+
+
+
+
+
10:47
+
+ +
+ +
+ the moment you do so + +
+ + + + +
+
+
+
+
+
+
10:47
+
+ +
+ +
+ for implementation reasons + +
+ + + + +
+
+
+
+
+
+
10:47
+
+ +
+ +
+ there are alternative formulations but they tend to have severe performance penalties + +
+ + + + +
+
+
+
+
+
+
10:48
+
+ +
+ +
+ this is why I think mere methods and OOP are separate concerns. Having a nice . notation is one thing, introducing the extra machinery is another (and OOP only starts manifesting when the extra machinery comes into play) + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 10:50 AM +
+ +
+ I guess re: methods and subtypes, we should also mention prototype-style ideas because that gives a related view on what "mere classes" would do + +
+ + + + +
+
+
+
+
+
+
10:50
+
+ +
+ +
+ in self (https://en.wikipedia.org/wiki/Self_(programming_language)) you have the idea of a prototype as the unit of implementation delegation + +
+ + + + +
+
+
+
+
+
+
10:51
+
+ +
+ +
+ (and of course this carried over into the original version of Javascript OO) + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 10:52 AM +
+ +
+ Yeah. There's definitely class- and prototype-based OO out there. Also extensible vs closed to extension. + +Trying to demarcate precisely the boundaries of "OOP" might be a time sink. I'd much rather chop OOP up into its component pieces, and then we can discuss each separately. And then the question of, "is there anything we missed?" becomes fruitful. + +
+ + + + +
+
+
+
+
+
+
10:52
+
+ +
+ +
+ In a game you can have a performance-focused substrate that is closed to extension, and a command language like Lua that is open to extension. Both use OO ideas. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 10:52 AM +
+ +
+ I think it's important to address how people think about OO though + +
+ + + + +
+
+
+
+
+
+
10:53
+
+ +
+ +
+ because just chopping up the pieces leads to talking about various pieces in isolation and that's not what gets people confused (or irate) + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 10:53 AM +
+ +
+ Let's talk about some of those pieces though, because getting a more nuanced idea of them will allow us to come back to what does get people confused and irate + +
+ + + + +
+
+
+
+ + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
SirWhinesalot
+
+ +this is why I think mere methods and OOP are separate concerns. Having a nice . notation is one thing, introducing the extra machinery is another (and OOP only starts manifesting when the extra machinery comes into play) + +
+
+
+ bvisness + + + 28-May-22 10:54 AM +
+ +
+ I think we should start discussing this "extra machinery". I'm not sure what angle to discuss first; there's the more nuts-and-bolts ideas such as inheritance and polymorphism, but there's also the very hairy subject of object-oriented design. @SirWhinesalot is our point person for that, but I'd like to make sure we feel we've covered our bases first. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 10:55 AM +
+ +
+ Right, might be worth posting that meme making fun of GeeksForGeeks here 😄 + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 10:56 AM +
+ +
+ heh + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 10:56 AM +
+ +
+ So what we're talking about here is the idea that "OOP models the real world". + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 10:56 AM +
+ +
+ that's indeed the most important meme to address IMO + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 10:56 AM +
+ +
+ Should we tackle that now? or after we split OOP up first? + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 10:57 AM +
+ +
+ and it links up to almost everything else + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 10:57 AM +
+ +
+ Let's just get into it. + +
+ + + + +
+
+
+
+
+
+
10:57
+
+ +
+ +
+ We can branch from there into everything else, like Demetri says + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 10:57 AM +
+ +
+ What does it mean for OOP to model the real world? Here's what Wikipedia has to say (technically from the Domain-Driven Design page, but the two are intimately related): + +
In terms of object-oriented programming it means that the structure and language of software code (class names, class methods, class variables) should match the business domain. For example, if a software processes loan applications, it might have classes like LoanApplication and Customer, and methods such as AcceptOffer and Withdraw.
+ +
+ + + + +
+
+
+
+
+
+
10:57
+
+ +
+ +
+ I would like to focus on that Customer class. Think of a website like Amazon, what does a Customer do? They can login/logout, purchase items, review items, contact customer support, etc. They also have a lot of data about them like their user-info, preferences, purchases, support tickets, etc. + +
+ + + + +
+
+
+
+
+
+
10:58
+
+ +
+ +
+ What data and methods should the Customer class have? + +
+ + + + +
+
+
+
+
+
+
10:58
+
+ +
+ +
+ Really think about this and the consequences it has on the structure of the codebase. All of the above? Classes should have a "single-responsibility" (supposedly). What should the single responsibility of the Customer class be? + +
+ + + + +
+
+
+
+
+
+
10:58
+
+ +
+ +
+ You see how we immediatelly start getting into trouble? + +
+ + + + +
+
+ 😄 + 1 +
+
+
+
+
+
+
+
+
10:58
+
+ +
+ +
+ Then there's the issue of structuring your code into class hierarchies based on real-world concepts, e.g. Customer : Person, Seller : Person, Employee : Person. + +
+ + + + +
+
+
+
+
+
+
10:58
+
+ +
+ +
+ The problem of course is that the same person can not only be all three, they can be different subsets at different times! Even real-world taxonomies need to be updated from time to time, and this modeling style is imposing that kind of rigid structure, with far less certainty, on your data and behavior. + +
+ + + + +
+
+
+
+
+
+
10:59
+
+ +
+ +
+ This style is considered bad practice these days, but even without the taxonomy nonsense the core issue remains, which is trying to model real-world concepts as bundles of encapsulated data + behavior. It just doesn't work well in practice, that idea is the fundamental mistake. + +
+ + + + +
+
+
+
+
+
+
10:59
+
+ +
+ +
+ IMO of course + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 11:00 AM +
+ +
+ One wonderful book that made the rounds last year: https://buttondown.email/hillelwayne/archive/why-you-should-read-data-and-reality + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ gingerBill + + + 28-May-22 11:01 AM +
+ +
+ My personal view that thinking "OOP models the real world" is wrong because it is a category error. You cannot treat [programming objects] as "real objects" since "real objects" and "programming objects" have little connection to each other ontologically. This is why I've previously called OOP a form of misinterpreted and misapplied Aristotelian Metaphysics applied to a domain it was never meant to model[2]. + +By this statement, I mean that artificially conforming to any/all relations between data and types to an artificial hierarchy of agency is a form of naïve-Aristotelian metaphysics. Since there is no actual agency in the programming objects, it is a partial fallacy (and as previously stated, category error). When trying to conform a program to have a particular structure when it does not naturally, the absence of a structure in a program in more useful than a bad structure. + +[1] https://en.wikipedia.org/wiki/Category_mistake +[2] https://www.gingerbill.org/article/2020/05/31/progamming-pragmatist-proverbs/ + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 11:02 AM +
+ +
+ Map vs territory confusion, right? + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ gingerBill + + + 28-May-22 11:02 AM +
+ +
+ There is also the other aspect that in an actual Aristotelian metaphysics, an object can belong to an infinite amount of "classes" in any moment and even change depending on the situation. + +
+ + + + +
+
+
+
+
+
+
11:02
+
+ +
+ +
+ In a way, yes. + +
+ + + + +
+
+
+
+
+
+
11:03
+
+ +
+ +
+ When we discuss of an object, we are speaking of it about what is relevant to us in that situation. + +
+ + + + +
+
+
+
+
+
+
11:03
+
+ +
+ +
+ Let's take a random object off my table right now: a lens cap. + +
+ + + + +
+
+
+
+
+
+
11:03
+
+ +
+ +
+ A lens cap could be in the class of objects that cover a lens. + +
+ + + + +
+
+
+
+
+
+
11:03
+
+ +
+ +
+ But it could also be used a coaster for my drink. + +
+ + + + +
+
+
+
+
+
+
11:04
+
+ +
+ +
+ It could also be used as an eye patch. + +
+ + + + +
+
+ 🏴‍☠️ + 1 +
+
+
+
+
+
+
+
+
11:04
+
+ +
+ +
+ Or a weird weapon. + +
+ + + + +
+
+ 🗡️ + 1 +
+
+ ⚫ + 1 +
+
+ 📷 + 1 +
+
+
+
+
+
+
+
+
11:04
+
+ +
+ +
+ Or a one of an infinite number of things with infinite uses. + +
+ + + + +
+
+
+
+
+
+
11:04
+
+ +
+ +
+ The question is realizing what is relevant for the situation. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 11:05 AM +
+ +
+ Now you've got me thinking about what a computer that can fluidly move between ontologies would look like.. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ gingerBill + + + 28-May-22 11:06 AM +
+ +
+ This is why, in my personal opinion, a huge issue with force something to an "object"/"class"/etc has issues with. Things belong to more than just one class and trying to force it into one category can be very bad, especially when there is no "object" to speak of in the first place, only algorithms and data structures. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 11:06 AM +
+ +
+ The relational/logical model tends to be much better at this, since you can add/retract facts about an object + +
+ + + + +
+
+
+
+
+
+
11:06
+
+ +
+ +
+ Entity-Component Systems are a form of relational model btw + +
+ + + + +
+
+
+
+
+
+
11:06
+
+ +
+ +
+ Some people think they are a form of OO, that's incorrect + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 11:08 AM +
+ +
+ I think whether or not it is wrong, "OO solves problem by modeling the real world" is both believed and practiced, and indeed it is widely used to advertise and teach OO + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 11:08 AM +
+ +
+ Indeed, that's how I was taught in university + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 11:08 AM +
+ +
+ this is what I mean about talking about how people think about it + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 11:08 AM +
+ +
+ The best defense I've heard for OO design is to limit your ambitions to modeling solutions, not problems. That avoids the issues@gingerBill raises, but it's also a much more modest goal. OO design books seem to pay this idea lip service, but quickly go back to thinking symbols are the thing they represent. It's a very easy mental trap to fall into. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 11:09 AM +
+ +
+ modeling solutions is antithetical to OO-best practices (as taught), because the right solution often involves some sort of "Manager" class that handles the data, and these are "frowned upon" because they don't bundle the data and behavior + +
+ + + + +
+
+ 👍 + 2 +
+
+
+
+
+
+ + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
Kartik Agaram
+
+ +The best defense I've heard for OO design is to limit your ambitions to modeling solutions, not problems. That avoids the issues@gingerBill raises, but it's also a much more modest goal. OO design books seem to pay this idea lip service, but quickly go back to thinking symbols are the thing they represent. It's a very easy mental trap to fall into. + +
+
+
+ gingerBill + + + 28-May-22 11:10 AM +
+ +
+ The irony of that statement is that is kind of the opposite of the point. Programming is a form of problem solving. If you have already solved the problem, then redesigning it to be OOP is really weird, and borderline masturbation. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 11:10 AM +
+ +
+
limit your ambitions to modeling solutions, not problems. +
I would phrase this as "[90s style C++/Java] OO offers the ability to form hierarchies of data structures and functions but that this is usually misinterpreted to mean that it will be useful to model hierarchies of concepts in the world outside the program"
+ +
+ + + + +
+
+ 👍 + 1 +
+
+
+
+
+
+ + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
gingerBill
+
+ +The irony of that statement is that is kind of the opposite of the point. Programming is a form of problem solving. If you have already solved the problem, then redesigning it to be OOP is really weird, and borderline masturbation. + +
+
+
+ Kartik Agaram + + + 28-May-22 11:11 AM +
+ +
+ The idea is that once you've solved a problem, OO Design is a good way to continue to maintain the solution without forgetting why you did what you did. Software systems can last a long time! + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 11:12 AM +
+ +
+ I've found no advantage to an OO design vs any other form of design with a clear structure, unless the features provided by OO (like subtype polymorphism) were necessary + +
+ + + + +
+
+
+
+
+
+
11:12
+
+ +
+ +
+ In fact quite the opposite, since OO design can impose a lot of rigidity that is hard to get rid off + +
+ + + + +
+
+
+
+
+
+
11:13
+
+ +
+ +
+ See weird workaround like C# extension methods for an example + +
+ + + + +
+
+
+
+ + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
Kartik Agaram
+
+ +The idea is that once you've solved a problem, OO Design is a good way to continue to maintain the solution without forgetting why you did what you did. Software systems can last a long time! + +
+
+
+ gingerBill + + + 28-May-22 11:13 AM +
+ +
+ See the trick? If it needs to be continuously improved, it's not a solution, yet. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 11:13 AM +
+ +
+ I would say I almost never use inheritance, but I almost always use methods + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 11:13 AM +
+ +
+ and if someone told me I could never use inheritance again I would not consider it a big loss + +
+ + + + +
+
+
+
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 11:13 AM +
+ +
+ I'm actually not familiar with any non-OO design methodology 😄 They kinda sucked the oxygen out of the room, didn't they? + +
+ + + + +
+
+
+
+ + + + + + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
Kartik Agaram
+
+ +I'm actually not familiar with any non-OO design methodology 😄 They kinda sucked the oxygen out of the room, didn't they? + +
+
+
+ SirWhinesalot + + + 28-May-22 11:14 AM +
+ +
+ there are many architectures you can use. Things like publish/subscribe, model-view-update, etc. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 11:14 AM +
+ +
+ Certainly though the term "design patterns" has come to exclusively mean "object-oriented design patterns", and really the gang of four stuff + +
+ + + + +
+
+
+
+ + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
Kartik Agaram
+
+ +I'm actually not familiar with any non-OO design methodology 😄 They kinda sucked the oxygen out of the room, didn't they? + +
+
+
+ gingerBill + + + 28-May-22 11:14 AM +
+ +
+ "JUST SOLVE THE PROBLEM YOU HAVE" is my preferred one. + +
+ + + + +
+
+ 💯 + 7 +
+
+
+
+
+
+ + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
bvisness
+
+ +Certainly though the term "design patterns" has come to exclusively mean "object-oriented design patterns", and really the gang of four stuff + +
+
+
+ bvisness + + + 28-May-22 11:15 AM +
+ +
+ and that persists to this day, thanks probably to universities? + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 11:15 AM +
+ +
+ yes I think the fact that OO has the superficial appearance of a "theory of programming" is important here + +
+ + + + +
+
+
+
+
+
+
11:15
+
+ +
+ +
+ (re: universities) + +
+ + + + +
+
+
+
+ + + + + + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 11:15 AM +
+ +
+ universities had rapidly increasing needs to "produce programmers" but universities loathe doing anything that might look like vocational school + +
+ + + + +
+
+
+
+
+
+
11:16
+
+ +
+ +
+ OOP looked like it had some ideas from type theory, had some kind of taxonomy scheme, had some claims to provable properties + +
+ + + + +
+
+
+
+
+
+
11:16
+
+ +
+ +
+ and so it was compatible with what a university might be persuaded to adopt + +
+ + + + +
+
+
+
+
+
+
11:17
+
+ +
+ +
+ and it also had the claim of "intuitively models the real world, so businesses like it" + +
+ + + + +
+
+ 💡 + 1 +
+
+
+
+
+
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 11:15 AM +
+ +
+ https://en.wikipedia.org/wiki/Software_design does have a list. I guess I'm not aware of it because I don't do design 😅 + +
+ + +
+
+ +
+
+
+ + + +
+
Software design is the process by which an agent creates a specification of a software artifact intended to accomplish goals, using a set of primitive components and subject to constraints. Software design may refer to either "all the activity involved in conceptualizing, framing, implementing, commissioning, and ultimately modifying complex sys...
+
+ +
+ +
+ + +
+
+ + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 11:18 AM +
+ +
+ My university thankfully presented all paradigms (procedural, oo, functional, logical) + +
+ + + + +
+
+
+
+
+
+
11:19
+
+ +
+ +
+ a good question there is if OO is an actual paradigm + + (edited) +
+ + + + +
+
+
+
+
+
+
11:19
+
+ +
+ +
+ Alan Kay certainly thought so, but Smalltalk OO is a very different beast from C++ or Java or whatever + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 11:20 AM +
+ +
+ I think Kay has sufficiently lost that battle that there's not much point talking about it as a peer + +
+ + + + +
+
+
+
+
+
+
11:20
+
+ +
+ +
+ when I want to talk about his stuff I say "Kay style OO" or "message passing OO" + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 11:22 AM +
+ +
+ I personally think Kay-style OO could be seen as a unique programming paradigm (when you include the full reflexivity and the IDE as the OS sort of programming style Smalltalk has), but regular OO is not, it's just procedural programming with a pointless structure on top + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 11:22 AM +
+ +
+ the folk understanding of OO, which IMO is like 90+% of people, is something like +- your program is a collection of classes +- one class per file +- each class represents some concept from the real world +- each class has a single responsibility (this is at odds with above but whatever :P) +- there are "good patterns" of assembling classes into programs to solve problems + + (edited) +
+ + + + +
+
+ 💯 + 1 +
+
+
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ gingerBill + + + 28-May-22 11:23 AM +
+ +
+ I (luckily?) don't have any programming education, let alone academic, so I cannot comment on what is or what is not taught commonly in Universities beyond what I have heard. From what I can tell, they seem to vary extremely widely compared to say harder science such as Physics or Chemistry. If you go to one University for Physics, it'll be similar enough to another. But for Computer Science (Infomatics), it will be very very different + +
+ + + + +
+
+ 👍 + 1 +
+
+
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 11:23 AM +
+ +
+ Among other critiques, this approach causes some blind spots because you get trained to think in terms of nouns and deemphasize verbs: http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 11:24 AM +
+ +
+ yes, a very important essay in this history + + (edited) +
+ + + + +
+
+
+
+ + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
Kartik Agaram
+
+ +Among other critiques, this approach causes some blind spots because you get trained to think in terms of nouns and deemphasize verbs: http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html + +
+
+
+ bvisness + + + 28-May-22 11:24 AM +
+ +
+ I love that post. When Demetri showed it to me for the first time years ago, I was shocked by how much it resonated with me + +
+ + + + +
+
+
+
+
+
+
11:25
+
+ +
+ +
+ This seems like as good a time as any for Demetri to talk about Java and what it did to the world of software + +
+ + + + +
+
+
+
+
+
+
11:25
+
+ +
+ +
+ which he volunteered to do as someone who lived through the Great Javafication + +
+ + + + +
+
+
+
+
+
+
11:31
+
+ +
+ +
+ To give some context for that, though, my understanding is that Java really took over the software industry in the mid-90s for a variety of reasons I'm not entirely familiar with + +
+ + + + +
+
+
+
+
+
+
11:31
+
+ +
+ +
+ He talked about it some on our podcast episode about programming education, as I recall (https://handmade.network/podcast/ep/eeac46c9-5e90-4b1c-9104-cff49734764d) + +
+ + + + +
+
+
+
+
+
+
11:32
+
+ +
+ +
+ And much of what he laid out in his "folk understanding of OO" above is, as far as I know, a direct line from Java + +
+ + + + +
+
+
+
+
+
+
11:32
+
+ +
+ +
+ for example, one class per file + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 11:34 AM +
+ +
+ Java uses classes for everything. Namespacing, modeling the solution, modeling the world, file system organization... + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 11:34 AM +
+ +
+ Yes I believe other languages aren't as restrictive, but the pattern is visible in a lot of C# codebases for example + + (edited) +
+ + + + +
+
+
+
+
+
+
11:34
+
+ +
+ +
+ one file per class + +
+ + + + +
+
+
+
+
+
+
11:34
+
+ +
+ +
+ because they sort of act like modules as well, specially when it's a "static" class with "static" methods + +
+ + + + +
+
+
+
+
+
+
11:35
+
+ +
+ +
+ (read: a bog standard procedural thing with extra keywords) + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 11:36 AM +
+ +
+ Java was the first "real" programming language I learned, and it took me a long time to broaden my understanding enough to unlearn a lot of the decisions it made. static is certainly an example of that; a great way to obscure a very obvious concept. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 11:37 AM +
+ +
+ It was the first question I asked my teacher: "What does static mean?" + +
+ + + + +
+
+
+
+
+
+
11:37
+
+ +
+ +
+ I had been exposed to Pascal before, but not in an educational setting + +
+ + + + +
+
+
+
+
+
+
11:37
+
+ +
+ +
+ So public static void main() inside a class was very confusing + +
+ + + + +
+
+
+
+
+
+
11:38
+
+ +
+ +
+ Btw his answer was "I'll explain that by the end" + +
+ + + + +
+
+
+
+
+
+
11:38
+
+ +
+ +
+ "Ignore it for now, just know it needs to be there" + +
+ + + + +
+
+
+
+
+
+
11:38
+
+ +
+ +
+ never a good start + +
+ + + + +
+
+
+
+
+
+
11:40
+
+ +
+ +
+ it was much worse for my partner, her teacher decided explaining the difference between static and non-static was a great discussion topic for class 2 of newbie bioinformatics learning to program + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 11:40 AM +
+ +
+ static is a great scapegoat example for the problems with Java's design decisions, but I suspect there is a lot more to it than that + +
+ + + + +
+
+
+
+
+
+
11:41
+
+ +
+ +
+ For example, I'm curious if from @demetrispanos's perspective, the design of Java's standard library had an impact here (or if that was just an outflow of the language design) + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 11:42 AM +
+ +
+ the standard library specifically, I'm not sure ... though Java definitely pioneered the idea that the standard library would have a canned solution for almost everything + +
+ + + + +
+
+
+
+
+
+
11:42
+
+ +
+ +
+ I remember buying "Java in a Nutshell" in the late 90s and being genuinely shocked at its size + +
+ + + + +
+
+
+
+
+
+
11:42
+
+ +
+ +
+ I think the large standard library overlapped with the idea of programs as "connecting objects to each other" + + (edited) +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 11:43 AM +
+ +
+ Well perhaps it would be best to just step back then and talk about the shift you saw in the industry when Java hit the scene + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 11:44 AM +
+ +
+ Java was the front runner but C++ in the 90s was also a major participant (indeed Design Patterns came from the C++ community) + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 11:45 AM +
+ +
+ Also Smalltalk! + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 11:45 AM +
+ +
+ I think the biggest change was just how much marketing effort was behind "90s OOP", led primarily by Java (in terms of marketing) + +
+ + + + +
+
+
+
+
+
+
11:46
+
+ +
+ +
+ Java promised everybody a pony + +
+ + + + +
+
+
+
+
+
+
11:46
+
+ +
+ +
+ universities got to teach a thing that looked like a theory of programming + +
+ + + + +
+
+
+
+
+
+
11:46
+
+ +
+ +
+ businesses got programmers that could program in "intuitive real world concepts" + +
+ + + + +
+
+
+
+
+
+
11:46
+
+ +
+ +
+ new programmers were told they didn't have to worry about details their predecessors used to sweat over, and could just draw object/class hierarchy diagrams + +
+ + + + +
+
+
+
+
+
+
11:47
+
+ +
+ +
+ (there were also other Java promises re: security and portability that aren't relevant here) + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 11:48 AM +
+ +
+ I wonder how much of Java being OO was because of the marketing efforts predating it.. 🤔 + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 11:48 AM +
+ +
+ well, to ask a question I think I know the answer to...how did Java live up to the hype :) + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 11:48 AM +
+ +
+ I think Gosling definitely saw himself as successor to Bjarne who was successor to Ritchie etc. + +
+ + + + +
+
+
+
+
+
+
11:49
+
+ +
+ +
+ and indeed Java was conceptualized as a kind of "C++, the good parts" + +
+ + + + +
+
+
+
+
+
+
11:49
+
+ +
+ +
+ and it's telling what they thought were "the good parts" + +
+ + + + +
+
+
+
+
+
+
11:49
+
+ +
+ +
+ class hierarchies + +
+ + + + +
+
+
+
+
+
+
11:49
+
+ +
+ +
+ you don't just have the option of classes, everything is a class (even your program itself) + +
+ + + + +
+
+
+
+
+
+
11:50
+
+ +
+ +
+ I would say that by the end of the 90s the thing we now know as "Java/C++ OOP" was cemented as the responsible way to write software + +
+ + + + +
+
+
+
+
+
+
11:51
+
+ +
+ +
+ or rather, cemented the reputation as such + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 11:51 AM +
+ +
+ One reason it took so long to notice that OO didn't always work well, was that it worked best in the lower levels where people designed and implemented languages like Java. After they put in all the effort to build the language over a decade, it took a decade of using OO methodologies in anger to crystallize its limitations. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 11:51 AM +
+ +
+ well also it genuinely did work reasonably well with widget hierarchies in GUIs + +
+ + + + +
+
+ 👍 + 1 +
+
+
+
+
+
+
+
+
11:52
+
+ +
+ +
+ but that was IMO an accident of overlap between problem and solution domain + +
+ + + + +
+
+
+
+
+
+
11:52
+
+ +
+ +
+ the widgets are code objects, and having hierarchies of code objects is something that OOP delivers as it says on the tin + +
+ + + + +
+
+
+
+
+
+
11:52
+
+ +
+ +
+ and indeed "textbox with a slider" is a reasonable conceptual descendant of "plain textbox" + +
+ + + + +
+
+
+
+
+
+
11:53
+
+ +
+ +
+ so I think many people saw that there was a good solution for an ascendant problem (the 90s saw the rise of GUIs to dominance) + +
+ + + + +
+
+
+
+
+
+
11:53
+
+ +
+ +
+ and they figured this would just be the first major success of many + +
+ + + + +
+
+
+
+
+
+
11:54
+
+ +
+ +
+ but widget hierarchies are much more usefully modeled by OOP than, say, customer/person hierarchies + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 11:55 AM +
+ +
+ That might be an interesting example to break down further + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 11:55 AM +
+ +
+ (Except when widgets used inner classes. That was a whole other can of worms..) + +
+ + + + +
+
+
+
+ + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
demetrispanos
+
+ +but widget hierarchies are much more usefully modeled by OOP than, say, customer/person hierarchies + +
+
+
+ SirWhinesalot + + + 28-May-22 11:56 AM +
+ +
+ Important to note here that UI frameworks moved away from "Split button inherits from Button" to "Split button is a button with a nested dropdown and a vertical line", you see that shift with the introduction of WPF at least + +
+ + + + +
+
+
+
+
+
+
11:57
+
+ +
+ +
+ so the move away from inheritance to composition was definitely ongoing in the 2000s + +
+ + + + +
+
+ 👍 + 1 +
+
+
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 11:57 AM +
+ +
+ yeah this is what I meant by "reasonably well", i.e. it was better than no organization at all but didn't end up being the one abstraction to rule all of GUI + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 11:58 AM +
+ +
+ I do think it's interesting though that it was still a more effective model than what you tend to see elsewhere. @Kartik Agaram and @SirWhinesalot talked in the planning doc about objects needing to belong to the "solution domain", not the "problem domain", and this feels like a similar situation to me + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 11:59 AM +
+ +
+ One thing I still grapple with is that it's easier to use computers to talk about computers than it is to do something useful. That leads to all our yak shaving and abstraction-tower-building tendencies. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 12:01 PM +
+ +
+ Yeah, OO is a rather natural way to model GUIs (not necessarily the only way, nor the best), but it works. A button has some internal state, it responds to some events, those events are shared between all kinds of GUI entities. A "Widget" interface that gets implemented by many different Widget classes is a rather obvious way to model this + +
+ + + + +
+
+
+
+
+
+
12:02
+
+ +
+ +
+ even in languages without native OO support + +
+ + + + +
+
+
+
+
+
+
12:02
+
+ +
+ +
+ See COM or GTK in C for examples + +
+ + + + +
+
+
+
+ + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
bvisness
+
+ +I do think it's interesting though that it was still a more effective model than what you tend to see elsewhere. @Kartik Agaram and @SirWhinesalot talked in the planning doc about objects needing to belong to the "solution domain", not the "problem domain", and this feels like a similar situation to me + +
+
+
+ Kartik Agaram + + + 28-May-22 12:02 PM +
+ +
+ That HN comment (https://news.ycombinator.com/item?id=785601#785833) actually hit me like a pile of bricks. Until then I'd only heard that you used inheritance to model is-a relationships, then wandered off because that seemed to suck. + +
+ + +
+
+ +
+ + + + +
+
+ + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:02 PM +
+ +
+ yes how many times has a junior programmer agonized over "is-a" vs "has-a" + +
+ + + + +
+
+
+
+ + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
demetrispanos
+
+ +yes how many times has a junior programmer agonized over "is-a" vs "has-a" + +
+
+
+ bvisness + + + 28-May-22 12:03 PM +
+ +
+ I did this for years + +
+ + + + +
+
+
+
+
+
+
12:03
+
+ +
+ +
+ and it was a meaningless question + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:03 PM +
+ +
+ yeah and the memeplex around 90s OOP invites that activity + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:03 PM +
+ +
+ it very strongly implies that this is what you should do + +
+ + + + +
+
+ 👍 + 1 +
+
+
+
+
+
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 12:03 PM +
+ +
+ interface vs implementation inheritance. And then I find that in practice, all inheritance is good for is sharing code. + + (edited) +
+ + + + +
+
+
+
+ + + + + + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
bvisness
+
+ +and it was a meaningless question + +
+
+
+ SirWhinesalot + + + 28-May-22 12:04 PM +
+ +
+ meaningless but unfortunately very critical if you're in an OO language + +
+ + + + +
+
+
+
+
+
+
12:04
+
+ +
+ +
+ because the decision is one you're mostly stuck with + +
+ + + + +
+
+
+
+
+
+
12:04
+
+ +
+ +
+ without a major rewrite + +
+ + + + +
+
+
+
+ + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
SirWhinesalot
+
+ +meaningless but unfortunately very critical if you're in an OO language + +
+
+
+ bvisness + + + 28-May-22 12:04 PM +
+ +
+ this I would say is a strong Java-ism + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 12:05 PM +
+ +
+ In practice, why is a relationship between two concepts being model as a language feature? + +
+ + + + +
+
+
+
+
+
+
12:05
+
+ +
+ +
+ There's absolutely no reason for this + + (edited) +
+ + + + +
+
+
+
+
+
+
12:05
+
+ +
+ +
+ I can model that A is a B in 1000 ways + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:05 PM +
+ +
+ well, the dirty secret is that it's not + +
+ + + + +
+
+
+
+
+
+
12:05
+
+ +
+ +
+ there is not even an attempt at it + +
+ + + + +
+
+
+
+
+
+
12:05
+
+ +
+ +
+ all that is attempted is sharing implementation details with ancestors + +
+ + + + +
+
+
+
+
+
+
12:06
+
+ +
+ +
+ the language never engages with whether the alleged is-a relationship is valid + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 12:06 PM +
+ +
+ true, you actually have to be careful to ensure an A is actually a B + +
+ + + + +
+
+
+
+
+
+
12:06
+
+ +
+ +
+ in fact traps like that are typical exam questions + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:06 PM +
+ +
+ the is-a aspect is entirely in people's minds + +
+ + + + +
+
+ ☝️ + 2 +
+
+
+
+
+
+
+
+
12:06
+
+ +
+ +
+ the thing that exists in the material world is sharing code + +
+ + + + +
+
+ 💯 + 2 +
+
+
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 12:06 PM +
+ +
+ which is much better done with before/after advice or hooks that receive anonymous functions + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 12:08 PM +
+ +
+ When teaching my FIRST robotics students, I've struggled in the past with better examples to illustrate how inheritance works in Java than the classic "Cat is-a Animal" thing, and I suppose that's largely because inheritance isn't actually very good at modeling anything practical + +
+ + + + +
+
+
+
+
+
+
12:08
+
+ +
+ +
+ but the concept must be taught if we are to use the language + +
+ + + + +
+
+
+
+
+
+
12:08
+
+ +
+ +
+ (we no longer use the language) + +
+ + + + +
+
+ 👍 + 2 +
+
+
+
+
+
+ + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
demetrispanos
+
+ +yes how many times has a junior programmer agonized over "is-a" vs "has-a" + +
+
+
+ bvisness + + + 28-May-22 12:09 PM +
+ +
+ One other aspect of OOP I think might be worth exploring is the idea of "agency" of objects, which "has-a" gets into + +
+ + + + +
+
+
+
+
+
+
12:09
+
+ +
+ +
+ I'm not sure if we've really touched on that yet + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 12:09 PM +
+ +
+ perhaps in passing but we haven't deep dived on it + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 12:10 PM +
+ +
+ This also relates in my mind to the actor model and perhaps the talk @Kartik Agaram mentioned by Richard Feldman about how OOP design makes each object a "small computer" on its own + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:11 PM +
+ +
+ I might say "small machine" but yes, and indeed this is the origin in Simula + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 12:11 PM +
+ +
+ This is to me different from the taxonomy issue + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 12:11 PM +
+ +
+ indeed, separate concern + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:11 PM +
+ +
+ the execution of the program is a simulation of many independent machines doing things to each other + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 12:12 PM +
+ +
+ this is "OOP as a model of computation" + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 12:13 PM +
+ +
+ With hindsight, the question I'm left with is, why did anyone ever consider this a good thing. Alan Kay made the analogy with biological cells in http://gagne.homedns.org/~tgagne/contrib/EarlyHistoryST.html#4, but back then (i.e. until the 90s when I started programming) we all assumed that was a good thing. + +
+ + + + +
+
+ ☝️ + 1 +
+
+
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:14 PM +
+ +
+ I think it became popular because of the idea that you'd use "code objects" the same way you use, say, screws from Home Depot + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 12:14 PM +
+ +
+ ah yes, software components. The ubiquitous siren of lego blocks. + +
+ + + + +
+
+ legobrick + 1 +
+
+
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:14 PM +
+ +
+ starting a new blog engine? go get some XYZ database screws and some PQR rendering bolts and you're 90% done + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 12:14 PM +
+ +
+ one important distinction between the smalltalk view (that affects how "good" it is) is the fact that objects are "live". You're not describing a simulation in terms of a software description of communicating objects (as in Java or C++), but actually witnessing the objects interact and changing their behavior as appropriate + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:15 PM +
+ +
+ this always felt like Alan Kay marketing speak to me + +
+ + + + +
+
+
+
+
+
+
12:15
+
+ +
+ +
+ databases are similarly "alive" in that the tables change with each insert + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 12:16 PM +
+ +
+ live editing is also not dependent on any sort of "object" 🙂 + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:16 PM +
+ +
+ Kay is a very creative guy, but he is also easily tempted by marketing language + +
+ + + + +
+
+
+
+
+
+
12:16
+
+ +
+ +
+ (this is fine, good ideas need marketing) + +
+ + + + +
+
+
+
+
+
+
12:16
+
+ +
+ +
+ anyway, it is indeed important to address OOP and the subject of software components/reuse + +
+ + + + +
+
+
+
+
+
+
12:17
+
+ +
+ +
+ because it definitely was perceived as the way to achieve the latter + +
+ + + + +
+
+
+
+
+
+
12:17
+
+ +
+ +
+ you no longer would do the "unimportant" "tedious" work of writing a string formatting function, you'd just use a java.util.StringFormatter + +
+ + + + +
+
+
+
+
+
+
12:17
+
+ +
+ +
+ (I don't know if that exists, it probably doesn't) + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 12:18 PM +
+ + + + + + +
+
+
+
+
+
+
12:18
+
+ +
+ +
+ so close 🙂 + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:18 PM +
+ +
+ and this overlaps with Java's enormous standard library, because it was meant to be analogous to walking into Home Depot and getting the screws you need + +
+ + + + +
+
+
+
+
+
+
12:18
+
+ +
+ +
+ haha closer than I thought + +
+ + + + +
+
+
+
+
+
+
12:18
+
+ +
+ +
+ importantly, I never saw any kind of argument for why an "object" would be more reusable than a function + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:18 PM +
+ +
+ but it was widely believed to be the case + +
+ + + + +
+
+
+
+
+
+
12:19
+
+ +
+ +
+ and that was a big part of the Java marketing agenda + +
+ + + + +
+
+
+
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 12:18 PM +
+ +
+ but again, this has nothing to do with objects, a module will do just fine for this purpose + +
+ + + + +
+
+
+
+
+
+
12:18
+
+ +
+ +
+ yup + +
+ + + + +
+
+
+
+ + + + + + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 12:19 PM +
+ +
+ the only case I can see for it is when the object is "live", meaning you acquire the object already in the state you want, but that's a big stretch + +
+ + + + +
+
+
+
+
+
+
12:19
+
+ +
+ +
+ why not just... configure the thing? + +
+ + + + +
+
+
+
+
+
+
12:19
+
+ +
+ +
+ was never clear either + +
+ + + + +
+
+
+
+
+
+
12:20
+
+ +
+ +
+ specially not in a Java like language where Classes may as well be modules with extra steps + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:20 PM +
+ +
+ yes and actually you can see some of this in how Python played out, because it was very oriented toward modules + +
+ + + + +
+
+
+
+
+
+
12:20
+
+ +
+ +
+ but then got a large influx of what I'll uncharitably call "java refugees" in the mid 00s + +
+ + + + +
+
+
+
+
+
+
12:21
+
+ +
+ +
+ and suddenly you started seeing a lot of python that looked like java + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 12:21 PM +
+ +
+ Reuse does feel like an idea important enough to be worth trying for a couple of decades. I'm glad we're past it now. At least for some people today, a library you can reuse registers as more liability than asset. Now you gotta wire it into your supply chain and watch out for vulnerabilities. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
Kartik Agaram
+
+ +Reuse does feel like an idea important enough to be worth trying for a couple of decades. I'm glad we're past it now. At least for some people today, a library you can reuse registers as more liability than asset. Now you gotta wire it into your supply chain and watch out for vulnerabilities. + +
+
+
+ bvisness + + + 28-May-22 12:22 PM +
+ +
+ It does feel like that's the trend, thankfully, but I suspect the dream of perfect reuse will never die out + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:22 PM +
+ +
+ I think the reuse concern is largely mercenary + +
+ + + + +
+
+
+
+
+
+
12:22
+
+ +
+ +
+ I mean it's mainly something businesses care about to reduce costs + +
+ + + + +
+
+
+
+
+
+
12:22
+
+ +
+ +
+ this is fine, keeping costs low is a reasonable concern + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 12:23 PM +
+ +
+ The key for me is to minimize zones of ownership. Reuse makes most sense when a vocabulary of components was coherently designed to compose well. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:23 PM +
+ +
+ but I don't think it's ultimately a deep concern about quality of code (even if it overlaps with quality concerns like single-point-of-truth) + +
+ + + + +
+
+
+
+
+
+
12:24
+
+ +
+ +
+ I want to distinguish between "reuse" and just "use by someone else" + +
+ + + + +
+
+
+
+
+
+
12:24
+
+ +
+ +
+ because I think they're conflated, but really only the second thing matters in most cases + +
+ + + + +
+
+
+
+
+
+
12:24
+
+ +
+ +
+ if I write the postgres database engine, what's important is that many people can use it (and not write their own) + +
+ + + + +
+
+
+
+
+
+
12:24
+
+ +
+ +
+ what's not important is that it can be used to make a substantially different database engine + +
+ + + + +
+
+
+
+
+
+
12:24
+
+ +
+ +
+ but that's the "just like screws" idea + +
+ + + + +
+
+
+
+
+
+
12:25
+
+ +
+ +
+ the same screws can make a table or a bookshelf etc. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 12:26 PM +
+ +
+ Do you think object-oriented design is worse at providing reuse than other approaches, or just completely unrelated? + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 12:26 PM +
+ +
+ one are where OOP matters for reuse is the idea of an interface that can be implemented in many different ways + +
+ + + + +
+
+
+
+
+
+
12:26
+
+ +
+ +
+ it sets a boundary between parts of the code + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 12:26 PM +
+ +
+ I think OOP tilted harder at that particular problem. Making it easier to build things that you can reuse with anything else. It failed, but that's ok. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:26 PM +
+ +
+ I would hesitate to attribute interfaces to any particular discipline + +
+ + + + +
+
+
+
+ + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
bvisness
+
+ +Do you think object-oriented design is worse at providing reuse than other approaches, or just completely unrelated? + +
+
+
+ demetrispanos + + + 28-May-22 12:27 PM +
+ +
+ I think it is in practice worse because it forces you to buy into the author's specific set of branded lego pieces that don't quite fit anyone else's + +
+ + + + +
+
+
+
+
+
+
12:27
+
+ +
+ +
+ in my experience the things that are easiest to glue together have extremely simple and unopinionated representations + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:28 PM +
+ +
+ but if you have to instantiate an object from some complex hierarchy merely to get started, you have a lot of friction + +
+ + + + +
+
+
+
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 12:28 PM +
+ +
+ It seems to me that easy reuse is in direct conflict with ideas of taxonomy and ownership and agency + + (edited) +
+ + + + +
+
+
+
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:28 PM +
+ +
+ the unix way is "almost everything is lines of text, and you have to parse them" + +
+ + + + +
+
+
+
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:28 PM +
+ +
+ it's annoying, but easy to glue together + + (edited) +
+ + + + +
+
+
+
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
bvisness
+
+ +Do you think object-oriented design is worse at providing reuse than other approaches, or just completely unrelated? + +
+
+
+ gingerBill + + + 28-May-22 12:28 PM +
+ +
+ So this depends. Most traditonal inheritance based OOP are worse than plain procedural, but something like Go's implicit interfaces (which some don't even call OOP) is a lot more reusable. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
gingerBill
+
+ +So this depends. Most traditonal inheritance based OOP are worse than plain procedural, but something like Go's implicit interfaces (which some don't even call OOP) is a lot more reusable. + +
+
+
+ gingerBill + + + 28-May-22 12:28 PM +
+ +
+ The big issue is that Go's interfaces require GC and have many performance issues. + +
+ + + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 12:29 PM +
+ +
+ as @skejeton was getting at in #fishbowl-audience, a table doesn't own a screw, a table leg doesn't own a screw, they're just all there + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:29 PM +
+ +
+ the C way is "almost everything is arrays of a few machine-type primitives" + +
+ + + + +
+
+
+
+
+
+
12:29
+
+ +
+ +
+ and that too has proven to be a very productive way to glue things together, as it is the basis of almost every practical FFI design + +
+ + + + +
+
+
+
+
+
+
12:29
+
+ +
+ +
+ the web way is "almost everything is JSON" + +
+ + + + +
+
+
+
+
+
+
12:29
+
+ +
+ +
+ and again, that is easy to glue together + +
+ + + + +
+
+
+
+
+
+
12:30
+
+ +
+ +
+ Java attempted "amost everything is XML" but it rightfully went up in flames + +
+ + + + +
+
+
+
+
+
+
12:30
+
+ +
+ +
+ because XML has many of the same problems vs JSON as Java OOP vs procedural + +
+ + + + +
+
+
+
+
+
+
12:31
+
+ +
+ +
+ JSON makes no pretense of modeling the real world, it's just a record + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 12:32 PM +
+ +
+ rich hickey goes into this on why systems level concerns are different from application level concerns, and the data exchange between "processes" or "entities" in a system should be very "loose" + +
+ + + + +
+
+
+
+
+
+
12:32
+
+ +
+ +
+ it's why unix has just strings, or the web has json everywhere + +
+ + + + +
+
+
+
+
+
+
12:33
+
+ +
+ +
+ this is also why stuff like dependency injection frameworks exist, their job is to set up the "wiring" between various components, which gets more and more complicated the more detailed the interface specification they have to communicate is + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 12:35 PM +
+ +
+ Complexity feels like something worth talking about head on. A lot of our discussion has had it implicitly in the background. The promise of many languages/tools/paradigms is "treat complexity as an externality. Infinite scale!" This never bears out, and lately I consider it a bad direction. Why is it so important to be able to scale up in complexity? + +Oh wait, where am I, this is Handmade Network. I'm preaching to the choir 😅 + +
+ + + + +
+
+
+
+ + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
Kartik Agaram
+
+ +Complexity feels like something worth talking about head on. A lot of our discussion has had it implicitly in the background. The promise of many languages/tools/paradigms is "treat complexity as an externality. Infinite scale!" This never bears out, and lately I consider it a bad direction. Why is it so important to be able to scale up in complexity? + +Oh wait, where am I, this is Handmade Network. I'm preaching to the choir 😅 + +
+
+
+ bvisness + + + 28-May-22 12:37 PM +
+ +
+ Well on that note, another thing that I had on my list was the idea that OOP allows you to scale up development and solve more complex problems. One of the links you posted during planning directly stated this exact idea. But...is there any merit to that idea at all? + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 12:38 PM +
+ +
+ Was that perhaps just an accident of all the other things Java provided out of the box? + +
+ + + + +
+
+
+
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 12:38 PM +
+ +
+ Namespacing does help. + +
+ + + + +
+
+
+
+ + + + + + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 12:39 PM +
+ +
+ I think a lot of these ideas do help. Perhaps it's a matter of setting expectations. "This is awesome, rock out with it!" vs "You're trying to do something really hard, this thing will help mitigate the pain." + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 12:40 PM +
+ +
+ I now see that my prep notes actually say "OOP allows us to write larger programs" and that is definitely true troll + + (edited) +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 12:41 PM +
+ +
+ breaking down systems into components definitely helps with scaling things up, this is done all the time in hardware land, but components are not objects + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:41 PM +
+ +
+ I think the steelman version of this argument goes like this +1. OOP encourages you to assemble your program from many small objects, one per file +2. since each object has a single responsibility, individual changes that happen in the future usually belong in only one file +3. so even if you have 10k class files, only one matters at any given time +4. so you can scale your classes across your people + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 12:42 PM +
+ +
+ that's among the weaker steelmans I've seen + +
+ + + + +
+
+ 😂 + 1 +
+
+
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:42 PM +
+ +
+ and this is mostly true for changes like "instead of saying Hello Newcomer, it should say Howdy Stranger when the player logs in" + +
+ + + + +
+
+ 💯 + 1 +
+
+
+
+
+
+ + + + + + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:42 PM +
+ +
+ you look up the PlayerGreeter.java + +
+ + + + +
+
+
+
+
+
+
12:42
+
+ +
+ +
+ you change the greeting + +
+ + + + +
+
+
+
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 12:42 PM +
+ +
+ I do often find myself needing to modify multiple classes/files in a single tiny commit. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 12:43 PM +
+ +
+ For a while I used to have my build script show me the average number of files modified in the last 10 commits. That did give an interesting sort of peripheral awareness. + +
+ + + + +
+
+ 🤔 + 1 +
+
+
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 12:44 PM +
+ +
+ one thing that's important to note is that OOP makes changing the architecture rather hard, i.e. since objects store their references to other objects, you have to jump around everywhere to change things + +
+ + + + +
+
+
+
+
+
+
12:44
+
+ +
+ +
+ if you try to avoid this by using some pattern where an "upper level" object sets everything up + +
+ + + + +
+
+
+
+
+
+
12:44
+
+ +
+ +
+ you end up with way too much argument passing to constructors + +
+ + + + +
+
+
+
+
+
+
12:44
+
+ +
+ +
+ which, in turn, leads to awful dependency injection frameworks + +
+ + + + +
+
+
+
+
+
+
12:45
+
+ +
+ +
+ in most component-based design systems for hardware, the connections between the components are a directly editable thing + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 12:45 PM +
+ +
+ 💯 But then doesn't everything? I define architecture as "that which is hard to change." + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 12:45 PM +
+ +
+ That feels like it's mostly caused by the inheritance / taxonomy / hierarchy kinds of design problems we were talking about before + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 12:46 PM +
+ +
+ even with composition it's an issue, because of how communication between objects occurs + +
+ + + + +
+
+
+
+
+
+
12:46
+
+ +
+ +
+ i.e. For A to send messages to B, it needs to remember B + + (edited) +
+ + + + +
+
+
+
+
+
+
12:46
+
+ +
+ +
+ somehow, one way or another + +
+ + + + +
+
+
+
+
+
+
12:46
+
+ +
+ +
+ whereas in actual component-based systems, that "memory" is stored externally + +
+ + + + +
+
+
+
+
+
+
12:46
+
+ +
+ +
+ importantly, A does not own B here + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 12:46 PM +
+ +
+ sure, I guess I could see how it's a problem with "agency" ideas too + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:47 PM +
+ +
+ perhaps another thing worth noting here is that OOP overlapped with many general-good-practice "discoveries" and I think inherited some of their reputation, e.g. avoiding unnecessary globals + +
+ + + + +
+
+
+
+
+
+
12:47
+
+ +
+ +
+ (which OOP then undoes by inventing singletons :P) + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 12:48 PM +
+ +
+ I suppose so, yeah + +
+ + + + +
+
+
+
+ + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
SirWhinesalot
+
+ +breaking down systems into components definitely helps with scaling things up, this is done all the time in hardware land, but components are not objects + +
+
+
+ bvisness + + + 28-May-22 12:49 PM +
+ +
+ Going back to this, I would agree that breaking down systems into more-independent modules is certainly very important to solving larger problems; avoiding unnecessary globals is another example of a useful design tactic for tackling complexity + + (edited) +
+ + + + +
+
+
+
+
+
+
12:49
+
+ +
+ +
+ Was it really all that bad before OOP languages became popular though? + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 12:49 PM +
+ +
+ All the fun there is in that word "unnecessary" 🙂 + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 12:49 PM +
+ +
+ That might be too big a question 😛 + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:50 PM +
+ +
+ well, OOP also largely coincided with the establishment of "programmer" as a known profession + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 12:50 PM +
+ +
+ Our programs did grow by several orders of magnitude in the period of the OO paradigm. I feel like it should take some of the credit/blame for that. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:50 PM +
+ +
+ indeed in the 80s it was common for people to conflate the "IT guy" with a programmer, and it was even riffed a bit in movies + +
+ + + + +
+
+
+
+
+
+
12:51
+
+ +
+ +
+ so I think it's hard to separate the professionalization of the field from the techniques that were popular at the time + +
+ + + + +
+
+
+
+
+
+
12:51
+
+ +
+ +
+ far fewer people were programming in the 80s + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 12:52 PM +
+ +
+ I suppose then that programming was just running into the very real problems of working with larger teams + + (edited) +
+ + + + +
+
+
+
+
+
+
12:52
+
+ +
+ +
+ "software engineering", to use Russ Cox's definition + + (edited) +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:52 PM +
+ +
+ yeah + +
+ + + + +
+
+
+
+ + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
bvisness
+
+ +I suppose then that programming was just running into the very real problems of working with larger teams + + (edited) +
+
+
+ Kartik Agaram + + + 28-May-22 12:53 PM +
+ +
+ Oh very interesting, hadn't seen this before: https://research.swtch.com/vgo-eng + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 12:53 PM +
+ +
+ yep I was just gonna share the full quote: +
Software engineering is what happens to programming +when you add time and other programmers.
+ +
+ + + + +
+
+
+
+
+
+
12:54
+
+ +
+ +
+ Is it fair to say that OOP languages offered some useful tools for "software engineering", but that those tools were misused? + + (edited) +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:55 PM +
+ +
+ I'd say Java/C++ offered the versions of various things that became popular (e.g. modularity was a general useful idea, and the way it came to the market was classes) + +
+ + + + +
+
+
+
+ + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
bvisness
+
+ +Is it fair to say that OOP languages offered some useful tools for "software engineering", but that those tools were misused? + + (edited) +
+
+
+ Kartik Agaram + + + 28-May-22 12:56 PM +
+ +
+ Yeah it feels like the nature of the world. You get some promises, you build something. You get some benefits, you get some problems you now have to live with. There's no going back. You can't enter a river twice. + +
+ + + + +
+
+
+
+
+
+
12:56
+
+ +
+ +
+ Even the bad parts, we had to explore them to understand why they're bad. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:56 PM +
+ +
+ it's worth trying to eliminate the "sturgeon contribution" (sturgeons law: 90% of everything is bad) + +
+ + + + +
+
+
+
+
+
+
12:57
+
+ +
+ +
+ a lot of bad stuff was done with OOP, but a lot of bad stuff would be done regardless + +
+ + + + +
+
+
+
+
+
+
12:57
+
+ +
+ +
+ so it's useful to think about what badness was imposed on top of the sturgeon fraction + +
+ + + + +
+
+
+
+
+
+
12:57
+
+ +
+ +
+ personally I think the "model the real world" thing is above-sturgeon badness + +
+ + + + +
+
+
+
+
+
+
12:58
+
+ +
+ +
+ it infected everything and everyone, it wasn't just the usual "most people do bad work" + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 12:58 PM +
+ +
+ you could argue that it's a sturgeon-multiplier + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:58 PM +
+ +
+ yes quite plausible + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 12:58 PM +
+ +
+ it makes the 90% even worse 😛 + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 12:58 PM +
+ +
+ I tend to think all the above-sturgeon badness came from social context. Mostly incentives. Hard to blame a tech paradigm for it. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 12:59 PM +
+ +
+ but the paradigm clearly invites some forms of badness + +
+ + + + +
+
+
+
+
+
+
12:59
+
+ +
+ +
+ and deserves blame for something it invites + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 01:00 PM +
+ +
+ so for example, the problems with modeling + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 01:00 PM +
+ +
+ I can't blame OOP for people applying it lazily or in a way that it doesn't invite, but I can absolutely blame it for people using it the way it advertises itself + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 01:01 PM +
+ +
+ you yourself did talk though about the level of marketing behind Java - so both factors are certainly in play + +
+ + + + +
+
+
+
+ + + + + + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 01:01 PM +
+ +
+ well ok but the thing that was marketed is not separable right? + +
+ + + + +
+
+
+
+
+
+
13:01
+
+ +
+ +
+ they didn't randomly choose something to promote, they chose that thing to promote + +
+ + + + +
+
+
+
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 01:01 PM +
+ +
+ going from "I have this problem, how do I solve it with a combination of data structures and algorithms" to "how do I model these real-world concepts as agents with data + behavior" was one of the greatest mistakes we did as an industry + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 01:02 PM +
+ +
+ As an example, a nameless org I worked at was big on Design Patterns. But that was mostly caused by promotion incentives that reward complex-seeming work. I hate Design Patterns, but have a hard time blaming it for the ills created in its name. + +
+ + + + +
+
+ z_OOF + 2 +
+
+
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 01:02 PM +
+ +
+ ok but Design Patterns didn't say "you should base promotions on complex patterns" + +
+ + + + +
+
+
+
+
+
+
13:02
+
+ +
+ +
+ whereas OOP does say "you should have your program model concepts in the real world" + + (edited) +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 01:03 PM +
+ +
+ they (Design Patterns) were meant as a tool of communication, something to help explain what a certain structure in the code (that occurs often) is doing, but they turned into "best practices" somehow + + (edited) +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 01:03 PM +
+ +
+ True. I think I just give it some leeway as an honest mistake.. + +
+ + + + +
+
+
+
+
+
+
13:04
+
+ +
+ +
+ Design Patterns were also an honest mistake. They thought the problem they were solving was how to work in complex domains. The problem they turned out to solve was how to smuggle complexity and over-engineering into anything. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 01:05 PM +
+ +
+ I think they started from a very true and valuable observation, which is that code-as-characters-in-files reuse is [NOT] important compared to design reuse + + (edited) +
+ + + + +
+
+
+
+
+
+
13:05
+
+ +
+ +
+ that one insight was enough to persuade me to keep trying to find value in the book for years + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 01:05 PM +
+ +
+ this is Design Patterns, you mean? + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 01:05 PM +
+ +
+ yeah + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 01:05 PM +
+ +
+ yeah that makes sense + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 01:06 PM +
+ +
+ if you already have a design of a solution you can reuse from the past, you're 80% done + +
+ + + + +
+
+
+
+
+
+
13:06
+
+ +
+ +
+ because most of programming is discovering a good-enough design + +
+ + + + +
+
+ 💯 + 1 +
+
+
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 01:06 PM +
+ +
+ Design Patterns are certainly useful. I.e. "I need to model sum types in this language that doesn't have them, how do I do it?" -> "Visitor Pattern, here's how you set it up" + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 01:06 PM +
+ +
+ right well that's the Norvig argument, that design patterns are actually just papering over language deficiencies + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 01:07 PM +
+ +
+ they are 🙂 + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 01:07 PM +
+ +
+ you don't need Command Pattern when you have first class functions + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 01:07 PM +
+ +
+ they're actually a great source of language design inspiration + +
+ + + + +
+
+
+
+
+
+
13:07
+
+ +
+ +
+ "how does your language avoid the need for this pattern" + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 01:08 PM +
+ +
+ yes and this would bring it back to the tried-and-true tradition of standardizing extant patterns of use + +
+ + + + +
+
+
+
+
+
+
13:08
+
+ +
+ +
+ just like the for-loop, or the mere method + +
+ + + + +
+
+
+
+
+
+
13:08
+
+ +
+ +
+ if you write an assembly program, you will at some point write what amounts to a for-loop + +
+ + + + +
+
+
+
+
+
+
13:08
+
+ +
+ +
+ so the language just makes that standard + +
+ + + + +
+
+
+
+
+
+
13:08
+
+ +
+ +
+ to the extent that can be done for design patterns I consider it useful + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 01:09 PM +
+ +
+ I think the problem was that "applying" design patterns somehow became a point of pride? which is silly? they're a shopping list of solutions to particular problems + +
+ + + + +
+
+
+
+
+
+
13:09
+
+ +
+ +
+ i.e. the more patterns in your code the better + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 01:09 PM +
+ +
+ yes, well ... this would be far afield but this is tied to bigtech interviewing/hiring practices in the late 90s + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 01:10 PM +
+ +
+ oh man + +
+ + + + +
+
+ 😄 + 1 +
+
+
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 01:10 PM +
+ +
+ in the same way universities need a thing to teach as a theory of programming, tech companies needed a thing they could quiz + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 01:10 PM +
+ +
+ as much as I would love to crack the coding interview right now, we are past the three-hour mark and I think it would be a good idea to step back and summarize what we've discussed today + +
+ + + + +
+
+
+
+
+
+
13:11
+
+ +
+ +
+ although that would be a great subject for continued discussion afterward + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ demetrispanos + + + 28-May-22 01:11 PM +
+ +
+ yes I agree it's too far a tangent + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 01:11 PM +
+ +
+ perhaps a future fishbowl, since it's not really OOP specific + +
+ + + + +
+
+
+
+
+
+
13:11
+
+ +
+ +
+ but also a problem + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 01:11 PM +
+ +
+ definitely + +
+ + + + +
+
+
+
+
+
+
13:12
+
+ +
+ +
+ So here's my summary of what we've covered: +- "OOP is when you associate behavior with data": This is present in OOP, but not really the heart of the issue. That is, just because you have methods doesn't necessarily mean you have anything more than simple procedural programming with some syntax sugar. +- "OOP models the real world": This is categorically not true or effective, no matter what language you use. The real world resists taxonomy, and doesn't have anything to do with the problems you are solving. +- "OOP is Java": Well, we didn't say it as such, but we did discuss many of the specific problems of Java, and the promises it failed to live up to, despite its takeover of industry. +- "OOP as a model of computation": This idea was appealing largely because of promises of independent components and easy reuse - but arguably OOP is worse at providing this than other programming paradigms (especially the Java flavor of OOP). +- "OOP tackles complexity": There are some good concepts, such as modularity and avoiding globals, that became popular along with OOP languages, but OOP itself makes things more complex. + + (edited) +
+ + + + +
+
+
+
+
+
+
13:13
+
+ +
+ +
+ Is this a fair representation or am I leaving things out? + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 01:13 PM +
+ +
+ I'd been writing a summary as well over the conversation, and it is much more instrumental, through the lens of "how to write better programs" + +- if you have lots of one kind of thing, give them a common template +- when building a program, take a moment to plan such schemas first +- as a schema proves valuable, rework it to be more timeless. This includes making it easy to change the memory layout, but much more. + +Some rules of thumb like these capture all that is valuable about OO, to my mind. And what programming languages can contribute here are late-binding capabilities that preserve optionality for the programmer. + +What they don't capture is the hardest problem of all: how you can preserve an executable, checkable model of the world that acts as a history of why your program is as it is. + +Tests are one way to do that. Formal models are another, though formal models can also be used for modeling solutions rather than contexts. Prose documents are a third. They have limitations, but they're better than nothing to a future code archeologist. + +A lot of the ills we see with OO dogma lie in the space between my rules of thumb. You have to wait until you understand a domain before you try to generalize. OO languages are particularly bad here, because you're forced to create classes literally on line 1. + +I think design as a general activity makes no sense. Good design comes from understanding a domain. It is by necessity domain-specific. + +And any design activity really has to have a certain level of humility. Pick a bounded problem. Interact with few peers (that themselves have humility in dependencies and goals). Keep things coherent rather than trying to optimize the whole ocean into paperclips. + + (edited) +
+ + + + +
+
+
+
+ + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
bvisness
+
+ +Is this a fair representation or am I leaving things out? + +
+
+
+ SirWhinesalot + + + 28-May-22 01:14 PM +
+ +
+ just that if we split interfaces/vtables from OO, and maybe the nice subject verb object syntax, there's nothing of use left + +
+ + + + +
+
+
+
+
+
+
13:16
+
+ +
+ +
+ I'm willing to leave interfaces/vtables as being "OO", as the one useful thing it has, because they are damn useful when you need them + +
+ + + + +
+
+ ❤️ + 1 +
+
+
+
+
+
+
+
+
13:17
+
+ +
+ +
+ but other people disagree that they're even "OO", since stuff like modules in SML have many similarities without the runtime dispatch for example, and there are many ways to do runtime dispatch that are not interface based + + (edited) +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 01:19 PM +
+ +
+ So in that case...I'd like to return to the original age-old question: "is OOP bad or what?" + +It sounds like the prevailing opinion here is that: +- Object-oriented programming is fundamentally an approach to modeling and design, not merely some nice syntax in your language +- Object-oriented design is fundamentally flawed, since the idea of solving problems by modeling the world is fundamentally flawed +- The flaws of object-oriented design also prevent OOP from being a useful model of computation, or from meaningfully tackling complexity + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 01:19 PM +
+ +
+ that's my view on the matter yes + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 01:19 PM +
+ +
+
A lot of the ills we see with OO dogma lie in the space between my rules of thumb. You have to wait until you understand a domain before you try to generalize. OO languages are particularly bad here, because you're forced to create classes literally on line 1. + +I think design as a general activity makes no sense. Good design comes from understanding a domain. It is by necessity domain-specific. +
And I appreciate these thoughts by @Kartik Agaram a lot.
+ +
+ + + + +
+
+
+
+
+
+
13:20
+
+ +
+ +
+ Not only does object-oriented design fail to model problems well, but the tools force you into bad designs immediately. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+
+ Avatar +
+ +
+
+ Avatar +
bvisness
+
+ +Not only does object-oriented design fail to model problems well, but the tools force you into bad designs immediately. + +
+
+
+ demetrispanos + + + 28-May-22 01:21 PM +
+ +
+ yes in particular "in what class does this activity belong?" is a useless question that has wasted an enormous amount of time + +
+ + + + +
+
+
+
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 01:20 PM +
+ +
+ btw, just to answer the question I posted when I did my design introduction + +
+ + + + +
+
+
+
+
+
+
13:21
+
+ +
+ +
+ What is the single responsibility of the Customer class? + + (edited) +
+ + + + +
+
+
+
+
+
+
13:21
+
+ +
+ +
+ it is to uniquely identify a customer, it's a primary key + +
+ + + + +
+
+
+
+
+
+
13:21
+
+ +
+ +
+ here's a Customer class in Odin + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 01:21 PM +
+ +
+
Customer :: distinct u64
+ +
+ + + + +
+
+
+
+ + + + + + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 01:22 PM +
+ +
+ I think I can also reasonably conclude that, while OOP languages and practices may contain some good ideas, those are mostly unrelated to the core of object-oriented design. + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 01:24 PM +
+ +
+ I think "ownership" should maybe go in another fishbowl as well, since it has some similar issues with rigid tree-like structures and assigning "agency" to bits of data + +
+ + + + +
+
+
+
+
+
+
13:24
+
+ +
+ +
+ ownership is quite central to OOP + +
+ + + + +
+
+
+
+
+
+
13:24
+
+ +
+ +
+ even in GC languages + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 01:24 PM +
+ +
+ because there's a distinction between an object that "contains" another object within itself, and an object that "knows" about another object + +
+ + + + +
+
+
+
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 01:25 PM +
+ +
+ in Rust there's a syntactical distinction, but in Java there isn't + +
+ + + + +
+
+
+
+
+
+
+ Avatar +
+ +
+
+ gingerBill + + + 28-May-22 01:24 PM +
+ +
+ Ownership semantics is surprisingly related to OOP from an ontological perspective + +
+ + + + +
+
+
+
+ + + + + + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 01:25 PM +
+ +
+ and there we have massive tangent #2 + +
+ + + + +
+
+
+
+ + + + + + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 01:25 PM +
+ +
+ But yeah I agree that it could be a valuable topic to fishbowl about someday. + +
+ + + + +
+
+
+
+
+
+
13:26
+
+ +
+ +
+ Thanks @Kartik Agaram for the summary thoughts - are there any other summary thoughts our other participants would like to provide before we close? + +
+ + + + +
+
+ ❤️ + 1 +
+
+
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 01:26 PM +
+ + + + + + +
+
+
+
+
+
+
13:26
+
+ +
+ +
+ so I'll shut up now 😛 + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 01:27 PM +
+ +
+ Thanks everyone for this introduction to the fishbowl format. I'm a huge convert, to the extent that I think we should stop having in-person conferences. + +
+ + + + +
+
+ 😂 + 3 +
+
+ AbnerHangry + 3 +
+
+
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 01:28 PM +
+ +
+ Thank you very much for participating! I am really glad we finally had the opportunity to discuss this topic thoroughly. + +
+ + + + +
+
+
+
+
+
+
13:29
+
+ +
+ +
+ Thank you all for helping me with my secret moderator agenda of being able to say "before you discuss OOP any further, read this conversation" 😈 + +
+ + + + +
+
+ brain + 6 +
+
+
+
+
+
+
+
+
13:30
+
+ +
+ +
+ I hope everyone found the conversation useful, that it helps you understand OOP better, and that it helps you understand how to write better programs. + +
+ + + + +
+
+
+
+
+
+
13:31
+
+ +
+ +
+ See you in a couple months for our next fishbowl! + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ Kartik Agaram + + + 28-May-22 01:31 PM +
+ +
+ Thank you @bvisness for organizing! + +
+ + + + +
+
+ coolben + 2 +
+
+
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ SirWhinesalot + + + 28-May-22 01:32 PM +
+ +
+ Indeed, thanks a lot @bvisness , and also thank you to all the participants + +
+ + + + +
+
+
+
+ + + +
+
+
+
+ Avatar +
+ +
+
+ bvisness + + + 28-May-22 01:36 PM +
+ + + + + + +
+
+
+
+ + +
diff --git a/src/templates/src/include/header.html b/src/templates/src/include/header.html index b124340..4d46c69 100644 --- a/src/templates/src/include/header.html +++ b/src/templates/src/include/header.html @@ -73,6 +73,7 @@ Media
{{ svg "chevron-down-thick" }}
diff --git a/src/templates/templates.go b/src/templates/templates.go index ea07108..91a556f 100644 --- a/src/templates/templates.go +++ b/src/templates/templates.go @@ -10,6 +10,7 @@ import ( "git.handmade.network/hmn/hmn/src/auth" "git.handmade.network/hmn/hmn/src/hmnurl" "git.handmade.network/hmn/hmn/src/logging" + "git.handmade.network/hmn/hmn/src/utils" "github.com/Masterminds/sprig" "github.com/google/uuid" "github.com/teacat/noire" @@ -26,10 +27,13 @@ const ( var templateFs embed.FS var Templates map[string]*template.Template +//go:embed src/fishbowls +var FishbowlFS embed.FS + func Init() { Templates = make(map[string]*template.Template) - files, _ := templateFs.ReadDir("src") + files := utils.Must1(templateFs.ReadDir("src")) for _, f := range files { if hasSuffix(f.Name(), ".html") { t := template.New(f.Name()) diff --git a/src/templates/types.go b/src/templates/types.go index 5b766d2..6a1591d 100644 --- a/src/templates/types.go +++ b/src/templates/types.go @@ -49,6 +49,7 @@ type Header struct { HMNHomepageUrl string ProjectIndexUrl string PodcastUrl string + FishbowlUrl string ForumsUrl string LibraryUrl string diff --git a/src/website/base_data.go b/src/website/base_data.go index 377e877..eb41b11 100644 --- a/src/website/base_data.go +++ b/src/website/base_data.go @@ -72,6 +72,7 @@ func getBaseData(c *RequestContext, title string, breadcrumbs []templates.Breadc HMNHomepageUrl: hmnurl.BuildHomepage(), ProjectIndexUrl: hmnurl.BuildProjectIndex(1), PodcastUrl: hmnurl.BuildPodcast(), + FishbowlUrl: hmnurl.BuildFishbowlIndex(), ForumsUrl: hmnurl.HMNProjectContext.BuildForum(nil, 1), LibraryUrl: hmnurl.BuildLibrary(), }, diff --git a/src/website/fishbowl.go b/src/website/fishbowl.go new file mode 100644 index 0000000..fa706e2 --- /dev/null +++ b/src/website/fishbowl.go @@ -0,0 +1,69 @@ +package website + +import ( + "errors" + "html/template" + "io" + "io/fs" + "net/http" + "path" + "strings" + + "git.handmade.network/hmn/hmn/src/oops" + "git.handmade.network/hmn/hmn/src/templates" + "git.handmade.network/hmn/hmn/src/utils" +) + +func FishbowlIndex(c *RequestContext) ResponseData { + var res ResponseData + err := res.WriteTemplate("fishbowl_index.html", getBaseData(c, "Fishbowls", nil), c.Perf) + if err != nil { + return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to render fishbowl index page")) + } + return res +} + +func Fishbowl(c *RequestContext) ResponseData { + // Only serve up valid fishbowls + if _, err := fs.Stat(fishbowlFS, c.PathParams["name"]); errors.Is(err, fs.ErrNotExist) { + return FourOhFour(c) + } + + // Ensure trailing slash (it matters for relative URLs in the HTML) + if !strings.HasSuffix(c.URL().Path, "/") { + return c.Redirect(c.URL().Path+"/", http.StatusFound) + } + + type FishbowlData struct { + templates.BaseData + Contents template.HTML + } + + indexFile := utils.Must1(fishbowlFS.Open(path.Join(c.PathParams["name"], "index.html"))) + + tmpl := FishbowlData{ + BaseData: getBaseData(c, "TODOOP", nil), + Contents: template.HTML(utils.Must1(io.ReadAll(indexFile))), + } + + var res ResponseData + err := res.WriteTemplate("fishbowl.html", tmpl, c.Perf) + if err != nil { + return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to render fishbowl index page")) + } + return res +} + +// This will skip the common path prefix for fishbowl files. +// We unfortunately need to do this because we want to use http.FileServer, +// but _that_ needs an http.FS, but _that_ needs an fs.FS, and embed.FS +// doesn't import fs.SubFS, which _would_ do what we want, so here we are. >:( +var fishbowlFS = utils.Must1(fs.Sub(templates.FishbowlFS, "src/fishbowls")) +var fishbowlHTTPFS = http.StripPrefix("/fishbowl", http.FileServer(http.FS(fishbowlFS))) + +func FishbowlFiles(c *RequestContext) ResponseData { + var res ResponseData + fishbowlHTTPFS.ServeHTTP(&res, c.Req) + AddCORSHeaders(c, &res) + return res +} diff --git a/src/website/routes.go b/src/website/routes.go index 089dc14..2b64e96 100644 --- a/src/website/routes.go +++ b/src/website/routes.go @@ -222,6 +222,10 @@ func NewWebsiteRoutes(longRequestContext context.Context, conn *pgxpool.Pool) ht hmnOnly.GET(hmnurl.RegexPodcastEpisode, PodcastEpisode) hmnOnly.GET(hmnurl.RegexPodcastRSS, PodcastRSS) + hmnOnly.GET(hmnurl.RegexFishbowlIndex, FishbowlIndex) + hmnOnly.GET(hmnurl.RegexFishbowl, Fishbowl) + hmnOnly.GET(hmnurl.RegexFishbowlFiles, FishbowlFiles) + hmnOnly.POST(hmnurl.RegexAPICheckUsername, csrfMiddleware(APICheckUsername)) hmnOnly.GET(hmnurl.RegexLibraryAny, LibraryNotPortedYet)