commit c95359dd7cf61711b712144eec4e038f11571831
parent 7dddb043575c02c09fbf7c969a7b90ee9c1f7ae7
Author: Jack Mordaunt <jackmordaunt.dev@gmail.com>
Date: Fri, 1 Aug 2025 08:31:21 -0300
content/posts/what-is-an-interface.md
Signed-off-by: Jack Mordaunt <jackmordaunt.dev@gmail.com>
Diffstat:
19 files changed, 1342 insertions(+), 24 deletions(-)
diff --git a/content/posts/what-is-an-interface.md b/content/posts/what-is-an-interface.md
@@ -0,0 +1,228 @@
++++
+draft = false
+date = 2025-08-01T06:26:18-03:00
+title = "What is an Interface"
+description = "Behavioral Polymorphism: The foundation of OOP."
+slug = ""
+authors = []
+tags = ["OOP", "Go", "Odin", "Interface"]
+categories = []
+externalLink = ""
+series = []
++++
+
+**Behavioral Polymorphism: The foundation of OOP.**
+
+The **interface** is the foundation of OOP (Object Oriented Programming).
+
+It provides _behavioral polymorphism_: constraining a type by its behaviours -
+or more secifically, its method-set.
+
+> A "method" (as termed in OOP langauges) is nothing more than a procedure who's
+> first argument is a pointer to the object it is associated with. There is
+> nothing special about a method.
+
+**Definitions**
+
+- **Poly**: many
+- **Mono**: singular
+- **Morphism**: shape
+- **Polymorphism**: having many shapes
+- **Monomorphism**: having one shape
+
+Polymorphic refers to the ability to represent many shapes.
+
+**Anology: Power Sockets**
+
+You might have ten electrical appliances all completely different.
+Toaster, microwave, blender.
+The way they use the electricity are all different, but the power plug is the same.
+The power socket provides a common interface that allows polymorphism with respect to the appliances.
+As long as an appliance has a the correct plug, the power socket will accept it.
+Thus the power socket is an interface that enables behavioral polymorphism.
+
+Polymorphism in programing works the same way.
+
+> In dynamically-typed programming every value is polymorphic, and only the _use_ of the value will reveal whether the particular morphism is valid.
+> In statically-typed programming every value is monomorphic, and special types must be used to allow for polymorphism.
+
+**What is a shape anyway?**
+
+In programming a shape is some definable characteristic about a value.
+- At a low level: how are the fields represented in memory
+- At a high level: is it iterable, is it indexable, is it a reference, etc
+
+We abstract the low level up to the high level.
+
+OOP languages often build in language-level native support for interfaces since
+this kind of polymorphism is foundational to the OOP paradigm. In low level
+languages like C you will typically achieve polymorphism through data layout:
+using flexible structures and memory indirection.
+
+Interfaces allow for polymorphism in statically-typed languages.
+That is, they don't require generics in the type-system to implement.
+
+It is no coincidence that Java and Go started out statically-typed using interfaces.
+Lacking parametric polymorphism, those languages often awkwardly relied on behavioral polymorphism.
+
+## The Fat Pointer
+
+This section applies to _runtime_ interfaces, otherwise known as _dynamic dispatch_.
+
+At the low level, an interface is nothing more than a **fat pointer**: a structure
+containing a pair of pointers - one that points to the data, and the other that
+points to a function that operates on the data.
+
+This is all you need.
+
+**Odin Example: Stream**
+
+```odin
+Stream_Proc :: #type proc(stream_data: rawptr, mode: Stream_Mode, p: []byte, offset: i64, whence: Seek_From) -> (n: i64, err: Error)
+
+Stream :: struct {
+ procedure: Stream_Proc,
+ data: rawptr,
+}
+```
+
+This struct contains a pointer to a procedure and a pointer to the data.
+It can be used to represent any kind of streaming operation: reading, writing, flushing, closing, etc, on any type.
+
+Each specialized type (file, buffer, http body) simply needs to map itself to this shape and it can integrate with streaming logic.
+
+**Converting a Buffer to a Stream**
+
+```odin
+buffer_to_stream :: proc(b: ^Buffer) -> (s: io.Stream) {
+ s.data = b
+ s.procedure = _buffer_proc
+ return
+}
+```
+
+It simply builds the stream struct using a pointer to the buffer sets the correct procedure.
+
+To achieve behavioral polymorphism all you need is a common
+representation (the fat pointer) that all specialized types can conform to.
+
+**Usage Example: io.Reader**
+
+```odin
+package main
+
+import "core:bytes"
+import "core:io"
+import os "core:os/os2"
+
+main :: proc() {
+ // Assign both the file and buffer reader to this to show they are the same shape.
+ reader: io.Reader
+
+ // Scratch is just a buffer to read into.
+ scratch := make([dynamic]byte, 1024 * 1024)
+
+ // Open a file and make a reader for it.
+ file, _ := os.open("file")
+ reader = os.to_reader(file)
+
+ // This call is operating on the file.
+ io.read_full(reader, scratch[:])
+
+ // Allocate a byte buffer and make a reader for it.
+ buf: bytes.Buffer
+ bytes.buffer_init(&buf, make([dynamic]byte, 1024 * 1024)[:])
+ reader = bytes.buffer_to_stream(&buf)
+
+ // This call is operating on the buffer.
+ io.read_full(reader, scratch[:])
+}
+```
+
+In this example, the `io.Reader` is the interface.
+The `bytes.Buffer` and the `os.File` are the specialized types can map to it.
+`io.read_full` can therefore operate on any type that can map to an `io.Reader`.
+
+Behavioral polymorphism is achieved by matching shapes. No runtime or type system
+support needed.
+
+
+## The VTable
+
+**Virtual Table**
+
+The Odin core prefers to (but doesn't require) to use a VTable-of-one. A single
+procedure that can handle any possible operation of the interface.
+
+This keeps the shape a simple fat-pointer, making it easier to construct and
+more compact in memory.
+
+The traditional way (e.g., C++) assigns each method its own entry in the VTable.
+This means the pointer to the procedure becomes a pointer to a table of procedures.
+
+Each entry into the virtual table represents a single method.
+
+**Example: Multi-Method VTable**
+
+```odin
+FileInterface :: struct {
+ vtable: FileVTable,
+ data: rawptr,
+}
+
+FileVTable :: struct {
+ read: proc(data: rawptr, p: byte[]) -> (n: int, err: Error),
+ write: proc(data: rawptr, p: byte[]) -> (n: int, err: Error),
+ close: proc(data: rawptr) -> Error,
+}
+```
+
+As you can see, each additional method increases the memory required.
+
+There is no **logical** difference between the two representations, only structural.
+
+## Windows COM
+
+To see how far you can take behavioral polymorphism, look no further than Windows COM.
+
+COM is an API and ABI implemented entirely around VTables — to the exclusion of all else.
+
+You can call and implement a COM object in _any_ langauge, as long as the VTable
+representation and behaviour of the methods are correct.
+
+The point is not to teach COM, but to illustrate that interfaces are just VTables.
+Behavioral polymorphism is a simple low-level idea that is abstracted into OOP
+languages as a first class language feature.
+
+Windows COM also shows how flexible the humble VTable can be — it allows a
+polyglot object system. Fascinating, but probably not something to aspire to.
+
+## The Cost
+
+Interfaces are simple structures, but they are not free.
+
+- **Size**: at a minimum, two pointers.
+- **Growth**: VTable size grows with number of methods.
+- **Indirection**: Runtime method calls are indirect.
+
+In large dynamic arrays, interface overhead can add up:
+- **Memory cost**
+- **Cache pressure** due to pointer indirection
+- **Fragmented memory** for the actual data
+
+With a more sophisticated type system, interfaces can be monomorphised at
+compile-time (i.e., static dispatch).
+
+This eliminates runtime cost but increases compile-time complexity.
+
+## Conclusion
+
+Interfaces allow behavioral polymorpshim.
+
+The classic runtime interface is implemented as a simple fat-pointer shape.
+
+Concrete types only need to satisfy the shape of the interface and they can be used anywhere
+that interface is used.
+
+Interfaces are not scary, and not hard to implement at the low level. They are also not a
+substitute for parametric polymorphism as I'm sure many Go programmers are well aware.
diff --git a/hugo.toml b/hugo.toml
@@ -32,7 +32,7 @@ style = "github-dark"
description = "Coffee developer, software brewer."
keywords = "blog,developer,personal,software,robust,performance,sovereign"
avatarurl = "images/self.jpg"
- gravatar = "gravatar@sovereignlife.anonaddy.com"
+ # gravatar = "gravatar@sovereignlife.anonaddy.com"
faviconSVG = "/images/self-tiny-white.svg"
favicon_32 = "/images/self-tiny-white.png"
diff --git a/public/index.html b/public/index.html
@@ -149,8 +149,10 @@
<section class="container centered">
<div class="about">
+
+ <div class="avatar"><img src="/images/self.jpg" alt="avatar"></div>
+
- <div class="avatar"><img src="https://www.gravatar.com/avatar/05326692a6db70b042f6211d6e8fb84f?s=240&d=mp" alt="gravatar"></div>
diff --git a/public/posts/index.html b/public/posts/index.html
@@ -158,6 +158,10 @@
</header>
<ul><li>
+ <span class="date">August 1, 2025</span>
+ <a class="title" href="/posts/what-is-an-interface/">What is an Interface</a>
+</li>
+<li>
<span class="date">July 23, 2025</span>
<a class="title" href="/posts/why-people-hate-go/">Why People Love to Hate Go</a>
</li>
diff --git a/public/posts/index.xml b/public/posts/index.xml
@@ -6,9 +6,16 @@
<description>Recent content in Posts on Jack Mordaunt</description>
<generator>Hugo</generator>
<language>en</language>
- <lastBuildDate>Wed, 23 Jul 2025 14:16:55 -0300</lastBuildDate>
+ <lastBuildDate>Fri, 01 Aug 2025 06:26:18 -0300</lastBuildDate>
<atom:link href="http://jackmordaunt.com/posts/index.xml" rel="self" type="application/rss+xml" />
<item>
+ <title>What is an Interface</title>
+ <link>http://jackmordaunt.com/posts/what-is-an-interface/</link>
+ <pubDate>Fri, 01 Aug 2025 06:26:18 -0300</pubDate>
+ <guid>http://jackmordaunt.com/posts/what-is-an-interface/</guid>
+ <description><p><strong>Behavioral Polymorphism: The foundation of OOP.</strong></p>
<p>The <strong>interface</strong> is the foundation of OOP (Object Oriented Programming).</p>
<p>It provides <em>behavioral polymorphism</em>: constraining a type by its behaviours -
or more secifically, its method-set.</p>
<blockquote>
<p>A &ldquo;method&rdquo; (as termed in OOP langauges) is nothing more than a procedure who&rsquo;s
first argument is a pointer to the object it is associated with. There is
nothing special about a method.</p></blockquote>
<p><strong>Definitions</strong></p>
<ul>
<li><strong>Poly</strong>: many</li>
<li><strong>Mono</strong>: singular</li>
<li><strong>Morphism</strong>: shape</li>
<li><strong>Polymorphism</strong>: having many shapes</li>
<li><strong>Monomorphism</strong>: having one shape</li>
</ul>
<p>Polymorphic refers to the ability to represent many shapes.</p></description>
+ </item>
+ <item>
<title>Why People Love to Hate Go</title>
<link>http://jackmordaunt.com/posts/why-people-hate-go/</link>
<pubDate>Wed, 23 Jul 2025 14:16:55 -0300</pubDate>
diff --git a/public/posts/what-is-an-interface/index.html b/public/posts/what-is-an-interface/index.html
@@ -0,0 +1,476 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+ <title>
+ What is an Interface · Jack Mordaunt
+</title>
+ <meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<meta name="color-scheme" content="light dark">
+
+
+
+
+<meta name="author" content="Jack Mordaunt">
+<meta name="description" content="Behavioral Polymorphism: The foundation of OOP.">
+<meta name="keywords" content="blog,developer,personal,software,robust,performance,sovereign">
+
+
+
+ <meta name="twitter:card" content="summary">
+ <meta name="twitter:title" content="What is an Interface">
+ <meta name="twitter:description" content="Behavioral Polymorphism: The foundation of OOP.">
+
+<meta property="og:url" content="http://jackmordaunt.com/posts/what-is-an-interface/">
+ <meta property="og:site_name" content="Jack Mordaunt">
+ <meta property="og:title" content="What is an Interface">
+ <meta property="og:description" content="Behavioral Polymorphism: The foundation of OOP.">
+ <meta property="og:locale" content="en">
+ <meta property="og:type" content="article">
+ <meta property="article:section" content="posts">
+ <meta property="article:published_time" content="2025-08-01T06:26:18-03:00">
+ <meta property="article:modified_time" content="2025-08-01T06:26:18-03:00">
+ <meta property="article:tag" content="OOP">
+ <meta property="article:tag" content="Go">
+ <meta property="article:tag" content="Odin">
+ <meta property="article:tag" content="Interface">
+
+
+
+
+<link rel="canonical" href="http://jackmordaunt.com/posts/what-is-an-interface/">
+
+
+<link rel="preload" href="/fonts/fa-brands-400.woff2" as="font" type="font/woff2" crossorigin>
+<link rel="preload" href="/fonts/fa-regular-400.woff2" as="font" type="font/woff2" crossorigin>
+<link rel="preload" href="/fonts/fa-solid-900.woff2" as="font" type="font/woff2" crossorigin>
+
+
+
+
+ <link rel="stylesheet" href="/css/coder.min.6445a802b9389c9660e1b07b724dcf5718b1065ed2d71b4eeaf981cc7cc5fc46.css" integrity="sha256-ZEWoArk4nJZg4bB7ck3PVxixBl7S1xtO6vmBzHzF/EY=" crossorigin="anonymous" media="screen" />
+
+
+
+
+
+
+
+
+
+ <link rel="stylesheet" href="/css/coder-dark.min.a00e6364bacbc8266ad1cc81230774a1397198f8cfb7bcba29b7d6fcb54ce57f.css" integrity="sha256-oA5jZLrLyCZq0cyBIwd0oTlxmPjPt7y6KbfW/LVM5X8=" crossorigin="anonymous" media="screen" />
+
+
+
+
+
+
+
+ <link rel="stylesheet" href="/css/custom.min.931a9d02d6f7655cd0cd50317fac1204e00c54ffd0232085acc957b2db5e1283.css" integrity="sha256-kxqdAtb3ZVzQzVAxf6wSBOAMVP/QIyCFrMlXstteEoM=" crossorigin="anonymous" media="screen" />
+
+
+
+
+
+
+<link rel="icon" type="image/svg+xml" href="/images/self-tiny-white.svg" sizes="any">
+<link rel="icon" type="image/png" href="/images/self-tiny-white.png" sizes="32x32">
+<link rel="icon" type="image/png" href="/images/self-tiny-white.png" sizes="16x16">
+
+<link rel="apple-touch-icon" href="/images/apple-touch-icon.png">
+<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon.png">
+
+<link rel="manifest" href="/site.webmanifest">
+<link rel="mask-icon" href="/images/safari-pinned-tab.svg" color="#5bbad5">
+
+
+
+
+
+
+
+
+
+</head>
+
+
+
+
+
+
+<body class="preload-transitions colorscheme-auto">
+
+<div class="float-container">
+ <a id="dark-mode-toggle" class="colorscheme-toggle">
+ <i class="fa-solid fa-adjust fa-fw" aria-hidden="true"></i>
+ </a>
+</div>
+
+
+ <main class="wrapper">
+ <nav class="navigation">
+ <section class="container">
+
+ <a class="navigation-title" href="http://jackmordaunt.com/">
+ Jack Mordaunt
+ </a>
+
+
+ <input type="checkbox" id="menu-toggle" />
+ <label class="menu-button float-right" for="menu-toggle">
+ <i class="fa-solid fa-bars fa-fw" aria-hidden="true"></i>
+ </label>
+ <ul class="navigation-list">
+
+
+ <li class="navigation-item">
+ <a class="navigation-link " href="/posts/">Blog</a>
+ </li>
+
+ <li class="navigation-item">
+ <a class="navigation-link " href="/about/">About</a>
+ </li>
+
+ <li class="navigation-item">
+ <a class="navigation-link " href="/projects/">Projects</a>
+ </li>
+
+ <li class="navigation-item">
+ <a class="navigation-link " href="/contact/">Contact</a>
+ </li>
+
+ <li class="navigation-item">
+ <a class="navigation-link " href="/pay-with-bitcoin/">Pay</a>
+ </li>
+
+
+
+ </ul>
+
+ </section>
+</nav>
+
+
+ <div class="content">
+
+ <section class="container post">
+ <article>
+ <header>
+ <div class="post-title">
+ <h1 class="title">
+ <a class="title-link" href="http://jackmordaunt.com/posts/what-is-an-interface/">
+ What is an Interface
+ </a>
+ </h1>
+ </div>
+ <div class="post-meta">
+ <div class="date">
+ <span class="posted-on">
+ <i class="fa-solid fa-calendar" aria-hidden="true"></i>
+ <time datetime="2025-08-01T06:26:18-03:00">
+ August 1, 2025
+ </time>
+ </span>
+ <span class="reading-time">
+ <i class="fa-solid fa-clock" aria-hidden="true"></i>
+ 6-minute read
+ </span>
+ </div>
+
+
+ <div class="tags">
+ <i class="fa-solid fa-tag" aria-hidden="true"></i>
+ <span class="tag">
+ <a href="/tags/oop/">OOP</a>
+ </span>
+ <span class="separator">•</span>
+ <span class="tag">
+ <a href="/tags/go/">Go</a>
+ </span>
+ <span class="separator">•</span>
+ <span class="tag">
+ <a href="/tags/odin/">Odin</a>
+ </span>
+ <span class="separator">•</span>
+ <span class="tag">
+ <a href="/tags/interface/">Interface</a>
+ </span></div>
+
+ </div>
+ </header>
+
+ <div class="post-content">
+
+ <p><strong>Behavioral Polymorphism: The foundation of OOP.</strong></p>
+<p>The <strong>interface</strong> is the foundation of OOP (Object Oriented Programming).</p>
+<p>It provides <em>behavioral polymorphism</em>: constraining a type by its behaviours -
+or more secifically, its method-set.</p>
+<blockquote>
+<p>A “method” (as termed in OOP langauges) is nothing more than a procedure who’s
+first argument is a pointer to the object it is associated with. There is
+nothing special about a method.</p></blockquote>
+<p><strong>Definitions</strong></p>
+<ul>
+<li><strong>Poly</strong>: many</li>
+<li><strong>Mono</strong>: singular</li>
+<li><strong>Morphism</strong>: shape</li>
+<li><strong>Polymorphism</strong>: having many shapes</li>
+<li><strong>Monomorphism</strong>: having one shape</li>
+</ul>
+<p>Polymorphic refers to the ability to represent many shapes.</p>
+<p><strong>Anology: Power Sockets</strong></p>
+<p>You might have ten electrical appliances all completely different.
+Toaster, microwave, blender.
+The way they use the electricity are all different, but the power plug is the same.
+The power socket provides a common interface that allows polymorphism with respect to the appliances.
+As long as an appliance has a the correct plug, the power socket will accept it.
+Thus the power socket is an interface that enables behavioral polymorphism.</p>
+<p>Polymorphism in programing works the same way.</p>
+<blockquote>
+<p>In dynamically-typed programming every value is polymorphic, and only the <em>use</em> of the value will reveal whether the particular morphism is valid.
+In statically-typed programming every value is monomorphic, and special types must be used to allow for polymorphism.</p></blockquote>
+<p><strong>What is a shape anyway?</strong></p>
+<p>In programming a shape is some definable characteristic about a value.</p>
+<ul>
+<li>At a low level: how are the fields represented in memory</li>
+<li>At a high level: is it iterable, is it indexable, is it a reference, etc</li>
+</ul>
+<p>We abstract the low level up to the high level.</p>
+<p>OOP languages often build in language-level native support for interfaces since
+this kind of polymorphism is foundational to the OOP paradigm. In low level
+languages like C you will typically achieve polymorphism through data layout:
+using flexible structures and memory indirection.</p>
+<p>Interfaces allow for polymorphism in statically-typed languages.
+That is, they don’t require generics in the type-system to implement.</p>
+<p>It is no coincidence that Java and Go started out statically-typed using interfaces.
+Lacking parametric polymorphism, those languages often awkwardly relied on behavioral polymorphism.</p>
+<h2 id="the-fat-pointer">
+ The Fat Pointer
+ <a class="heading-link" href="#the-fat-pointer">
+ <i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"></i>
+ <span class="sr-only">Link to heading</span>
+ </a>
+</h2>
+<p>This section applies to <em>runtime</em> interfaces, otherwise known as <em>dynamic dispatch</em>.</p>
+<p>At the low level, an interface is nothing more than a <strong>fat pointer</strong>: a structure
+containing a pair of pointers - one that points to the data, and the other that
+points to a function that operates on the data.</p>
+<p>This is all you need.</p>
+<p><strong>Odin Example: Stream</strong></p>
+<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-odin" data-lang="odin"><span style="display:flex;"><span>Stream_Proc<span style="color:#6e7681"> </span><span style="color:#ff7b72;font-weight:bold">::</span><span style="color:#6e7681"> </span><span style="color:#d2a8ff;font-weight:bold">#type</span><span style="color:#6e7681"> </span><span style="color:#ff7b72">proc</span>(stream_data<span style="color:#ff7b72;font-weight:bold">:</span><span style="color:#6e7681"> </span><span style="color:#ff7b72">rawptr</span>,<span style="color:#6e7681"> </span>mode<span style="color:#ff7b72;font-weight:bold">:</span><span style="color:#6e7681"> </span>Stream_Mode,<span style="color:#6e7681"> </span>p<span style="color:#ff7b72;font-weight:bold">:</span><span style="color:#6e7681"> </span>[]<span style="color:#ff7b72">byte</span>,<span style="color:#6e7681"> </span>offset<span style="color:#ff7b72;font-weight:bold">:</span><span style="color:#6e7681"> </span><span style="color:#ff7b72">i64</span>,<span style="color:#6e7681"> </span>whence<span style="color:#ff7b72;font-weight:bold">:</span><span style="color:#6e7681"> </span>Seek_From)<span style="color:#6e7681"> </span><span style="color:#ff7b72;font-weight:bold">-></span><span style="color:#6e7681"> </span>(n<span style="color:#ff7b72;font-weight:bold">:</span><span style="color:#6e7681"> </span><span style="color:#ff7b72">i64</span>,<span style="color:#6e7681"> </span>err<span style="color:#ff7b72;font-weight:bold">:</span><span style="color:#6e7681"> </span>Error)<span style="color:#6e7681">
+</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">
+</span></span></span><span style="display:flex;"><span><span style="color:#6e7681"></span>Stream<span style="color:#6e7681"> </span><span style="color:#ff7b72;font-weight:bold">::</span><span style="color:#6e7681"> </span><span style="color:#ff7b72">struct</span><span style="color:#6e7681"> </span>{<span style="color:#6e7681">
+</span></span></span><span style="display:flex;"><span><span style="color:#6e7681"> </span>procedure<span style="color:#ff7b72;font-weight:bold">:</span><span style="color:#6e7681"> </span>Stream_Proc,<span style="color:#6e7681">
+</span></span></span><span style="display:flex;"><span><span style="color:#6e7681"> </span>data<span style="color:#ff7b72;font-weight:bold">:</span><span style="color:#6e7681"> </span><span style="color:#ff7b72">rawptr</span>,<span style="color:#6e7681">
+</span></span></span><span style="display:flex;"><span><span style="color:#6e7681"></span>}<span style="color:#6e7681">
+</span></span></span></code></pre></div><p>This struct contains a pointer to a procedure and a pointer to the data.
+It can be used to represent any kind of streaming operation: reading, writing, flushing, closing, etc, on any type.</p>
+<p>Each specialized type (file, buffer, http body) simply needs to map itself to this shape and it can integrate with streaming logic.</p>
+<p><strong>Converting a Buffer to a Stream</strong></p>
+<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-odin" data-lang="odin"><span style="display:flex;"><span>buffer_to_stream<span style="color:#6e7681"> </span><span style="color:#ff7b72;font-weight:bold">::</span><span style="color:#6e7681"> </span><span style="color:#ff7b72">proc</span>(b<span style="color:#ff7b72;font-weight:bold">:</span><span style="color:#6e7681"> </span><span style="color:#ff7b72;font-weight:bold">^</span>Buffer)<span style="color:#6e7681"> </span><span style="color:#ff7b72;font-weight:bold">-></span><span style="color:#6e7681"> </span>(s<span style="color:#ff7b72;font-weight:bold">:</span><span style="color:#6e7681"> </span>io.Stream)<span style="color:#6e7681"> </span>{<span style="color:#6e7681">
+</span></span></span><span style="display:flex;"><span><span style="color:#6e7681"> </span>s.data<span style="color:#6e7681"> </span><span style="color:#ff7b72;font-weight:bold">=</span><span style="color:#6e7681"> </span>b<span style="color:#6e7681">
+</span></span></span><span style="display:flex;"><span><span style="color:#6e7681"> </span>s.procedure<span style="color:#6e7681"> </span><span style="color:#ff7b72;font-weight:bold">=</span><span style="color:#6e7681"> </span>_buffer_proc<span style="color:#6e7681">
+</span></span></span><span style="display:flex;"><span><span style="color:#6e7681"> </span><span style="color:#ff7b72">return</span><span style="color:#6e7681">
+</span></span></span><span style="display:flex;"><span><span style="color:#6e7681"></span>}<span style="color:#6e7681">
+</span></span></span></code></pre></div><p>It simply builds the stream struct using a pointer to the buffer sets the correct procedure.</p>
+<p>To achieve behavioral polymorphism all you need is a common
+representation (the fat pointer) that all specialized types can conform to.</p>
+<p><strong>Usage Example: io.Reader</strong></p>
+<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-odin" data-lang="odin"><span style="display:flex;"><span><span style="color:#ff7b72">package</span><span style="color:#6e7681"> </span>main<span style="color:#6e7681">
+</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">
+</span></span></span><span style="display:flex;"><span><span style="color:#6e7681"></span><span style="color:#ff7b72">import</span><span style="color:#6e7681"> </span><span style="color:#a5d6ff">"core:bytes"</span><span style="color:#6e7681">
+</span></span></span><span style="display:flex;"><span><span style="color:#6e7681"></span><span style="color:#ff7b72">import</span><span style="color:#6e7681"> </span><span style="color:#a5d6ff">"core:io"</span><span style="color:#6e7681">
+</span></span></span><span style="display:flex;"><span><span style="color:#6e7681"></span><span style="color:#ff7b72">import</span><span style="color:#6e7681"> </span>os<span style="color:#6e7681"> </span><span style="color:#a5d6ff">"core:os/os2"</span><span style="color:#6e7681">
+</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">
+</span></span></span><span style="display:flex;"><span><span style="color:#6e7681"></span>main<span style="color:#6e7681"> </span><span style="color:#ff7b72;font-weight:bold">::</span><span style="color:#6e7681"> </span><span style="color:#ff7b72">proc</span>()<span style="color:#6e7681"> </span>{<span style="color:#6e7681">
+</span></span></span><span style="display:flex;"><span><span style="color:#6e7681"> </span><span style="color:#8b949e;font-style:italic">// Assign both the file and buffer reader to this to show they are the same shape.
+</span></span></span><span style="display:flex;"><span><span style="color:#8b949e;font-style:italic"></span><span style="color:#6e7681"> </span>reader<span style="color:#ff7b72;font-weight:bold">:</span><span style="color:#6e7681"> </span>io.Reader<span style="color:#6e7681">
+</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">
+</span></span></span><span style="display:flex;"><span><span style="color:#6e7681"> </span><span style="color:#8b949e;font-style:italic">// Scratch is just a buffer to read into.
+</span></span></span><span style="display:flex;"><span><span style="color:#8b949e;font-style:italic"></span><span style="color:#6e7681"> </span>scratch<span style="color:#6e7681"> </span><span style="color:#ff7b72;font-weight:bold">:=</span><span style="color:#6e7681"> </span><span style="color:#ff7b72">make</span>([<span style="color:#ff7b72">dynamic</span>]<span style="color:#ff7b72">byte</span>,<span style="color:#6e7681"> </span>1024<span style="color:#6e7681"> </span><span style="color:#ff7b72;font-weight:bold">*</span><span style="color:#6e7681"> </span>1024)<span style="color:#6e7681">
+</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">
+</span></span></span><span style="display:flex;"><span><span style="color:#6e7681"> </span><span style="color:#8b949e;font-style:italic">// Open a file and make a reader for it.
+</span></span></span><span style="display:flex;"><span><span style="color:#8b949e;font-style:italic"></span><span style="color:#6e7681"> </span>file,<span style="color:#6e7681"> </span>_<span style="color:#6e7681"> </span><span style="color:#ff7b72;font-weight:bold">:=</span><span style="color:#6e7681"> </span>os.open(<span style="color:#a5d6ff">"file"</span>)<span style="color:#6e7681">
+</span></span></span><span style="display:flex;"><span><span style="color:#6e7681"> </span>reader<span style="color:#6e7681"> </span><span style="color:#ff7b72;font-weight:bold">=</span><span style="color:#6e7681"> </span>os.to_reader(file)<span style="color:#6e7681">
+</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">
+</span></span></span><span style="display:flex;"><span><span style="color:#6e7681"> </span><span style="color:#8b949e;font-style:italic">// This call is operating on the file.
+</span></span></span><span style="display:flex;"><span><span style="color:#8b949e;font-style:italic"></span><span style="color:#6e7681"> </span>io.read_full(reader,<span style="color:#6e7681"> </span>scratch[<span style="color:#ff7b72;font-weight:bold">:</span>])<span style="color:#6e7681">
+</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">
+</span></span></span><span style="display:flex;"><span><span style="color:#6e7681"> </span><span style="color:#8b949e;font-style:italic">// Allocate a byte buffer and make a reader for it.
+</span></span></span><span style="display:flex;"><span><span style="color:#8b949e;font-style:italic"></span><span style="color:#6e7681"> </span>buf<span style="color:#ff7b72;font-weight:bold">:</span><span style="color:#6e7681"> </span>bytes.Buffer<span style="color:#6e7681">
+</span></span></span><span style="display:flex;"><span><span style="color:#6e7681"> </span>bytes.buffer_init(<span style="color:#ff7b72;font-weight:bold">&</span>buf,<span style="color:#6e7681"> </span><span style="color:#ff7b72">make</span>([<span style="color:#ff7b72">dynamic</span>]<span style="color:#ff7b72">byte</span>,<span style="color:#6e7681"> </span>1024<span style="color:#6e7681"> </span><span style="color:#ff7b72;font-weight:bold">*</span><span style="color:#6e7681"> </span>1024)[<span style="color:#ff7b72;font-weight:bold">:</span>])<span style="color:#6e7681">
+</span></span></span><span style="display:flex;"><span><span style="color:#6e7681"> </span>reader<span style="color:#6e7681"> </span><span style="color:#ff7b72;font-weight:bold">=</span><span style="color:#6e7681"> </span>bytes.buffer_to_stream(<span style="color:#ff7b72;font-weight:bold">&</span>buf)<span style="color:#6e7681">
+</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">
+</span></span></span><span style="display:flex;"><span><span style="color:#6e7681"> </span><span style="color:#8b949e;font-style:italic">// This call is operating on the buffer.
+</span></span></span><span style="display:flex;"><span><span style="color:#8b949e;font-style:italic"></span><span style="color:#6e7681"> </span>io.read_full(reader,<span style="color:#6e7681"> </span>scratch[<span style="color:#ff7b72;font-weight:bold">:</span>])<span style="color:#6e7681">
+</span></span></span><span style="display:flex;"><span><span style="color:#6e7681"></span>}<span style="color:#6e7681">
+</span></span></span></code></pre></div><p>In this example, the <code>io.Reader</code> is the interface.
+The <code>bytes.Buffer</code> and the <code>os.File</code> are the specialized types can map to it.
+<code>io.read_full</code> can therefore operate on any type that can map to an <code>io.Reader</code>.</p>
+<p>Behavioral polymorphism is achieved by matching shapes. No runtime or type system
+support needed.</p>
+<h2 id="the-vtable">
+ The VTable
+ <a class="heading-link" href="#the-vtable">
+ <i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"></i>
+ <span class="sr-only">Link to heading</span>
+ </a>
+</h2>
+<p><strong>Virtual Table</strong></p>
+<p>The Odin core prefers to (but doesn’t require) to use a VTable-of-one. A single
+procedure that can handle any possible operation of the interface.</p>
+<p>This keeps the shape a simple fat-pointer, making it easier to construct and
+more compact in memory.</p>
+<p>The traditional way (e.g., C++) assigns each method its own entry in the VTable.
+This means the pointer to the procedure becomes a pointer to a table of procedures.</p>
+<p>Each entry into the virtual table represents a single method.</p>
+<p><strong>Example: Multi-Method VTable</strong></p>
+<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-odin" data-lang="odin"><span style="display:flex;"><span>FileInterface<span style="color:#6e7681"> </span><span style="color:#ff7b72;font-weight:bold">::</span><span style="color:#6e7681"> </span><span style="color:#ff7b72">struct</span><span style="color:#6e7681"> </span>{<span style="color:#6e7681">
+</span></span></span><span style="display:flex;"><span><span style="color:#6e7681"> </span>vtable<span style="color:#ff7b72;font-weight:bold">:</span><span style="color:#6e7681"> </span>FileVTable,<span style="color:#6e7681">
+</span></span></span><span style="display:flex;"><span><span style="color:#6e7681"> </span>data<span style="color:#ff7b72;font-weight:bold">:</span><span style="color:#6e7681"> </span><span style="color:#ff7b72">rawptr</span>,<span style="color:#6e7681">
+</span></span></span><span style="display:flex;"><span><span style="color:#6e7681"></span>}<span style="color:#6e7681">
+</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">
+</span></span></span><span style="display:flex;"><span><span style="color:#6e7681"></span>FileVTable<span style="color:#6e7681"> </span><span style="color:#ff7b72;font-weight:bold">::</span><span style="color:#6e7681"> </span><span style="color:#ff7b72">struct</span><span style="color:#6e7681"> </span>{<span style="color:#6e7681">
+</span></span></span><span style="display:flex;"><span><span style="color:#6e7681"> </span>read<span style="color:#ff7b72;font-weight:bold">:</span><span style="color:#6e7681"> </span><span style="color:#ff7b72">proc</span>(data<span style="color:#ff7b72;font-weight:bold">:</span><span style="color:#6e7681"> </span><span style="color:#ff7b72">rawptr</span>,<span style="color:#6e7681"> </span>p<span style="color:#ff7b72;font-weight:bold">:</span><span style="color:#6e7681"> </span><span style="color:#ff7b72">byte</span>[])<span style="color:#6e7681"> </span><span style="color:#ff7b72;font-weight:bold">-></span><span style="color:#6e7681"> </span>(n<span style="color:#ff7b72;font-weight:bold">:</span><span style="color:#6e7681"> </span><span style="color:#ff7b72">int</span>,<span style="color:#6e7681"> </span>err<span style="color:#ff7b72;font-weight:bold">:</span><span style="color:#6e7681"> </span>Error),<span style="color:#6e7681">
+</span></span></span><span style="display:flex;"><span><span style="color:#6e7681"> </span>write<span style="color:#ff7b72;font-weight:bold">:</span><span style="color:#6e7681"> </span><span style="color:#ff7b72">proc</span>(data<span style="color:#ff7b72;font-weight:bold">:</span><span style="color:#6e7681"> </span><span style="color:#ff7b72">rawptr</span>,<span style="color:#6e7681"> </span>p<span style="color:#ff7b72;font-weight:bold">:</span><span style="color:#6e7681"> </span><span style="color:#ff7b72">byte</span>[])<span style="color:#6e7681"> </span><span style="color:#ff7b72;font-weight:bold">-></span><span style="color:#6e7681"> </span>(n<span style="color:#ff7b72;font-weight:bold">:</span><span style="color:#6e7681"> </span><span style="color:#ff7b72">int</span>,<span style="color:#6e7681"> </span>err<span style="color:#ff7b72;font-weight:bold">:</span><span style="color:#6e7681"> </span>Error),<span style="color:#6e7681">
+</span></span></span><span style="display:flex;"><span><span style="color:#6e7681"> </span>close<span style="color:#ff7b72;font-weight:bold">:</span><span style="color:#6e7681"> </span><span style="color:#ff7b72">proc</span>(data<span style="color:#ff7b72;font-weight:bold">:</span><span style="color:#6e7681"> </span><span style="color:#ff7b72">rawptr</span>)<span style="color:#6e7681"> </span><span style="color:#ff7b72;font-weight:bold">-></span><span style="color:#6e7681"> </span>Error,<span style="color:#6e7681">
+</span></span></span><span style="display:flex;"><span><span style="color:#6e7681"></span>}<span style="color:#6e7681">
+</span></span></span></code></pre></div><p>As you can see, each additional method increases the memory required.</p>
+<p>There is no <strong>logical</strong> difference between the two representations, only structural.</p>
+<h2 id="windows-com">
+ Windows COM
+ <a class="heading-link" href="#windows-com">
+ <i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"></i>
+ <span class="sr-only">Link to heading</span>
+ </a>
+</h2>
+<p>To see how far you can take behavioral polymorphism, look no further than Windows COM.</p>
+<p>COM is an API and ABI implemented entirely around VTables — to the exclusion of all else.</p>
+<p>You can call and implement a COM object in <em>any</em> langauge, as long as the VTable
+representation and behaviour of the methods are correct.</p>
+<p>The point is not to teach COM, but to illustrate that interfaces are just VTables.
+Behavioral polymorphism is a simple low-level idea that is abstracted into OOP
+languages as a first class language feature.</p>
+<p>Windows COM also shows how flexible the humble VTable can be — it allows a
+polyglot object system. Fascinating, but probably not something to aspire to.</p>
+<h2 id="the-cost">
+ The Cost
+ <a class="heading-link" href="#the-cost">
+ <i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"></i>
+ <span class="sr-only">Link to heading</span>
+ </a>
+</h2>
+<p>Interfaces are simple structures, but they are not free.</p>
+<ul>
+<li><strong>Size</strong>: at a minimum, two pointers.</li>
+<li><strong>Growth</strong>: VTable size grows with number of methods.</li>
+<li><strong>Indirection</strong>: Runtime method calls are indirect.</li>
+</ul>
+<p>In large dynamic arrays, interface overhead can add up:</p>
+<ul>
+<li><strong>Memory cost</strong></li>
+<li><strong>Cache pressure</strong> due to pointer indirection</li>
+<li><strong>Fragmented memory</strong> for the actual data</li>
+</ul>
+<p>With a more sophisticated type system, interfaces can be monomorphised at
+compile-time (i.e., static dispatch).</p>
+<p>This eliminates runtime cost but increases compile-time complexity.</p>
+<h2 id="conclusion">
+ Conclusion
+ <a class="heading-link" href="#conclusion">
+ <i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"></i>
+ <span class="sr-only">Link to heading</span>
+ </a>
+</h2>
+<p>Interfaces allow behavioral polymorpshim.</p>
+<p>The classic runtime interface is implemented as a simple fat-pointer shape.</p>
+<p>Concrete types only need to satisfy the shape of the interface and they can be used anywhere
+that interface is used.</p>
+<p>Interfaces are not scary, and not hard to implement at the low level. They are also not a
+substitute for parametric polymorphism as I’m sure many Go programmers are well aware.</p>
+
+ </div>
+
+
+ <footer>
+
+
+
+
+
+
+
+
+
+
+ </footer>
+ </article>
+
+
+ </section>
+
+ </div>
+
+ <footer class="footer">
+ <section class="container">
+ ©
+
+ 2025
+ Jack Mordaunt
+ ·
+
+ Powered by <a href="https://gohugo.io/" target="_blank" rel="noopener">Hugo</a> & <a href="https://github.com/luizdepra/hugo-coder/" target="_blank" rel="noopener">Coder</a>.
+
+ </section>
+</footer>
+
+ </main>
+
+
+
+
+
+ <script src="/js/coder.min.6ae284be93d2d19dad1f02b0039508d9aab3180a12a06dcc71b0b0ef7825a317.js" integrity="sha256-auKEvpPS0Z2tHwKwA5UI2aqzGAoSoG3McbCw73gloxc="></script>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+</body>
+</html>
diff --git a/public/sitemap.xml b/public/sitemap.xml
@@ -2,34 +2,43 @@
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:xhtml="http://www.w3.org/1999/xhtml">
<url>
- <loc>http://jackmordaunt.com/authors/</loc>
- <lastmod>2025-07-23T14:16:55-03:00</lastmod>
+ <loc>http://jackmordaunt.com/tags/go/</loc>
+ <lastmod>2025-08-01T06:26:18-03:00</lastmod>
</url><url>
- <loc>http://jackmordaunt.com/categories/</loc>
- <lastmod>2025-07-23T14:16:55-03:00</lastmod>
+ <loc>http://jackmordaunt.com/tags/interface/</loc>
+ <lastmod>2025-08-01T06:26:18-03:00</lastmod>
</url><url>
- <loc>http://jackmordaunt.com/categories/development/</loc>
- <lastmod>2025-07-23T14:16:55-03:00</lastmod>
+ <loc>http://jackmordaunt.com/</loc>
+ <lastmod>2025-08-01T06:26:18-03:00</lastmod>
</url><url>
- <loc>http://jackmordaunt.com/tags/go/</loc>
- <lastmod>2025-07-23T14:16:55-03:00</lastmod>
+ <loc>http://jackmordaunt.com/tags/odin/</loc>
+ <lastmod>2025-08-01T06:26:18-03:00</lastmod>
</url><url>
- <loc>http://jackmordaunt.com/</loc>
- <lastmod>2025-07-23T14:16:55-03:00</lastmod>
+ <loc>http://jackmordaunt.com/tags/oop/</loc>
+ <lastmod>2025-08-01T06:26:18-03:00</lastmod>
</url><url>
- <loc>http://jackmordaunt.com/authors/jack-mordaunt/</loc>
+ <loc>http://jackmordaunt.com/posts/</loc>
+ <lastmod>2025-08-01T06:26:18-03:00</lastmod>
+ </url><url>
+ <loc>http://jackmordaunt.com/tags/</loc>
+ <lastmod>2025-08-01T06:26:18-03:00</lastmod>
+ </url><url>
+ <loc>http://jackmordaunt.com/posts/what-is-an-interface/</loc>
+ <lastmod>2025-08-01T06:26:18-03:00</lastmod>
+ </url><url>
+ <loc>http://jackmordaunt.com/authors/</loc>
<lastmod>2025-07-23T14:16:55-03:00</lastmod>
</url><url>
- <loc>http://jackmordaunt.com/tags/odin/</loc>
+ <loc>http://jackmordaunt.com/categories/</loc>
<lastmod>2025-07-23T14:16:55-03:00</lastmod>
</url><url>
- <loc>http://jackmordaunt.com/categories/opinion/</loc>
+ <loc>http://jackmordaunt.com/categories/development/</loc>
<lastmod>2025-07-23T14:16:55-03:00</lastmod>
</url><url>
- <loc>http://jackmordaunt.com/posts/</loc>
+ <loc>http://jackmordaunt.com/authors/jack-mordaunt/</loc>
<lastmod>2025-07-23T14:16:55-03:00</lastmod>
</url><url>
- <loc>http://jackmordaunt.com/tags/</loc>
+ <loc>http://jackmordaunt.com/categories/opinion/</loc>
<lastmod>2025-07-23T14:16:55-03:00</lastmod>
</url><url>
<loc>http://jackmordaunt.com/posts/why-people-hate-go/</loc>
diff --git a/public/tags/go/index.html b/public/tags/go/index.html
@@ -156,6 +156,11 @@
<ul>
<li>
+ <span class="date">August 1, 2025</span>
+ <a class="title" href="/posts/what-is-an-interface/">What is an Interface</a>
+ </li>
+
+ <li>
<span class="date">July 23, 2025</span>
<a class="title" href="/posts/why-people-hate-go/">Why People Love to Hate Go</a>
</li>
diff --git a/public/tags/go/index.xml b/public/tags/go/index.xml
@@ -6,9 +6,16 @@
<description>Recent content in Go on Jack Mordaunt</description>
<generator>Hugo</generator>
<language>en</language>
- <lastBuildDate>Wed, 23 Jul 2025 14:16:55 -0300</lastBuildDate>
+ <lastBuildDate>Fri, 01 Aug 2025 06:26:18 -0300</lastBuildDate>
<atom:link href="http://jackmordaunt.com/tags/go/index.xml" rel="self" type="application/rss+xml" />
<item>
+ <title>What is an Interface</title>
+ <link>http://jackmordaunt.com/posts/what-is-an-interface/</link>
+ <pubDate>Fri, 01 Aug 2025 06:26:18 -0300</pubDate>
+ <guid>http://jackmordaunt.com/posts/what-is-an-interface/</guid>
+ <description><p><strong>Behavioral Polymorphism: The foundation of OOP.</strong></p>
<p>The <strong>interface</strong> is the foundation of OOP (Object Oriented Programming).</p>
<p>It provides <em>behavioral polymorphism</em>: constraining a type by its behaviours -
or more secifically, its method-set.</p>
<blockquote>
<p>A &ldquo;method&rdquo; (as termed in OOP langauges) is nothing more than a procedure who&rsquo;s
first argument is a pointer to the object it is associated with. There is
nothing special about a method.</p></blockquote>
<p><strong>Definitions</strong></p>
<ul>
<li><strong>Poly</strong>: many</li>
<li><strong>Mono</strong>: singular</li>
<li><strong>Morphism</strong>: shape</li>
<li><strong>Polymorphism</strong>: having many shapes</li>
<li><strong>Monomorphism</strong>: having one shape</li>
</ul>
<p>Polymorphic refers to the ability to represent many shapes.</p></description>
+ </item>
+ <item>
<title>Why People Love to Hate Go</title>
<link>http://jackmordaunt.com/posts/why-people-hate-go/</link>
<pubDate>Wed, 23 Jul 2025 14:16:55 -0300</pubDate>
diff --git a/public/tags/index.html b/public/tags/index.html
@@ -184,7 +184,7 @@
<li>
<span class="taxonomy-element">
<a href="http://jackmordaunt.com/tags/go/">Go</a>
- <sup>4</sup>
+ <sup>5</sup>
</span>
</li>
@@ -205,6 +205,17 @@
<li>
<span class="taxonomy-element">
+ <a href="http://jackmordaunt.com/tags/interface/">Interface</a>
+ <sup>1</sup>
+ </span>
+ </li>
+
+
+
+
+
+ <li>
+ <span class="taxonomy-element">
<a href="http://jackmordaunt.com/tags/native/">Native</a>
<sup>2</sup>
</span>
@@ -228,6 +239,17 @@
<li>
<span class="taxonomy-element">
<a href="http://jackmordaunt.com/tags/odin/">Odin</a>
+ <sup>2</sup>
+ </span>
+ </li>
+
+
+
+
+
+ <li>
+ <span class="taxonomy-element">
+ <a href="http://jackmordaunt.com/tags/oop/">OOP</a>
<sup>1</sup>
</span>
</li>
diff --git a/public/tags/index.xml b/public/tags/index.xml
@@ -6,23 +6,37 @@
<description>Recent content in Tags on Jack Mordaunt</description>
<generator>Hugo</generator>
<language>en</language>
- <lastBuildDate>Wed, 23 Jul 2025 14:16:55 -0300</lastBuildDate>
+ <lastBuildDate>Fri, 01 Aug 2025 06:26:18 -0300</lastBuildDate>
<atom:link href="http://jackmordaunt.com/tags/index.xml" rel="self" type="application/rss+xml" />
<item>
<title>Go</title>
<link>http://jackmordaunt.com/tags/go/</link>
- <pubDate>Wed, 23 Jul 2025 14:16:55 -0300</pubDate>
+ <pubDate>Fri, 01 Aug 2025 06:26:18 -0300</pubDate>
<guid>http://jackmordaunt.com/tags/go/</guid>
<description></description>
</item>
<item>
+ <title>Interface</title>
+ <link>http://jackmordaunt.com/tags/interface/</link>
+ <pubDate>Fri, 01 Aug 2025 06:26:18 -0300</pubDate>
+ <guid>http://jackmordaunt.com/tags/interface/</guid>
+ <description></description>
+ </item>
+ <item>
<title>Odin</title>
<link>http://jackmordaunt.com/tags/odin/</link>
- <pubDate>Wed, 23 Jul 2025 14:16:55 -0300</pubDate>
+ <pubDate>Fri, 01 Aug 2025 06:26:18 -0300</pubDate>
<guid>http://jackmordaunt.com/tags/odin/</guid>
<description></description>
</item>
<item>
+ <title>OOP</title>
+ <link>http://jackmordaunt.com/tags/oop/</link>
+ <pubDate>Fri, 01 Aug 2025 06:26:18 -0300</pubDate>
+ <guid>http://jackmordaunt.com/tags/oop/</guid>
+ <description></description>
+ </item>
+ <item>
<title>Gio</title>
<link>http://jackmordaunt.com/tags/gio/</link>
<pubDate>Thu, 17 Jul 2025 11:21:04 -0300</pubDate>
diff --git a/public/tags/interface/index.html b/public/tags/interface/index.html
@@ -0,0 +1,237 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+ <title>Tag: Interface · Jack Mordaunt</title>
+ <meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<meta name="color-scheme" content="light dark">
+
+
+
+
+<meta name="author" content="Jack Mordaunt">
+<meta name="description" content="Coffee developer, software brewer.">
+<meta name="keywords" content="blog,developer,personal,software,robust,performance,sovereign">
+
+
+
+ <meta name="twitter:card" content="summary">
+ <meta name="twitter:title" content="Interface">
+ <meta name="twitter:description" content="Coffee developer, software brewer.">
+
+<meta property="og:url" content="http://jackmordaunt.com/tags/interface/">
+ <meta property="og:site_name" content="Jack Mordaunt">
+ <meta property="og:title" content="Interface">
+ <meta property="og:description" content="Coffee developer, software brewer.">
+ <meta property="og:locale" content="en">
+ <meta property="og:type" content="website">
+
+
+
+
+<link rel="canonical" href="http://jackmordaunt.com/tags/interface/">
+
+
+<link rel="preload" href="/fonts/fa-brands-400.woff2" as="font" type="font/woff2" crossorigin>
+<link rel="preload" href="/fonts/fa-regular-400.woff2" as="font" type="font/woff2" crossorigin>
+<link rel="preload" href="/fonts/fa-solid-900.woff2" as="font" type="font/woff2" crossorigin>
+
+
+
+
+ <link rel="stylesheet" href="/css/coder.min.6445a802b9389c9660e1b07b724dcf5718b1065ed2d71b4eeaf981cc7cc5fc46.css" integrity="sha256-ZEWoArk4nJZg4bB7ck3PVxixBl7S1xtO6vmBzHzF/EY=" crossorigin="anonymous" media="screen" />
+
+
+
+
+
+
+
+
+
+ <link rel="stylesheet" href="/css/coder-dark.min.a00e6364bacbc8266ad1cc81230774a1397198f8cfb7bcba29b7d6fcb54ce57f.css" integrity="sha256-oA5jZLrLyCZq0cyBIwd0oTlxmPjPt7y6KbfW/LVM5X8=" crossorigin="anonymous" media="screen" />
+
+
+
+
+
+
+
+ <link rel="stylesheet" href="/css/custom.min.931a9d02d6f7655cd0cd50317fac1204e00c54ffd0232085acc957b2db5e1283.css" integrity="sha256-kxqdAtb3ZVzQzVAxf6wSBOAMVP/QIyCFrMlXstteEoM=" crossorigin="anonymous" media="screen" />
+
+
+
+
+
+
+<link rel="icon" type="image/svg+xml" href="/images/self-tiny-white.svg" sizes="any">
+<link rel="icon" type="image/png" href="/images/self-tiny-white.png" sizes="32x32">
+<link rel="icon" type="image/png" href="/images/self-tiny-white.png" sizes="16x16">
+
+<link rel="apple-touch-icon" href="/images/apple-touch-icon.png">
+<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon.png">
+
+<link rel="manifest" href="/site.webmanifest">
+<link rel="mask-icon" href="/images/safari-pinned-tab.svg" color="#5bbad5">
+
+
+<link rel="alternate" type="application/rss+xml" href="/tags/interface/index.xml" title="Jack Mordaunt" />
+
+
+
+
+
+
+
+</head>
+
+
+
+
+
+
+<body class="preload-transitions colorscheme-auto">
+
+<div class="float-container">
+ <a id="dark-mode-toggle" class="colorscheme-toggle">
+ <i class="fa-solid fa-adjust fa-fw" aria-hidden="true"></i>
+ </a>
+</div>
+
+
+ <main class="wrapper">
+ <nav class="navigation">
+ <section class="container">
+
+ <a class="navigation-title" href="http://jackmordaunt.com/">
+ Jack Mordaunt
+ </a>
+
+
+ <input type="checkbox" id="menu-toggle" />
+ <label class="menu-button float-right" for="menu-toggle">
+ <i class="fa-solid fa-bars fa-fw" aria-hidden="true"></i>
+ </label>
+ <ul class="navigation-list">
+
+
+ <li class="navigation-item">
+ <a class="navigation-link " href="/posts/">Blog</a>
+ </li>
+
+ <li class="navigation-item">
+ <a class="navigation-link " href="/about/">About</a>
+ </li>
+
+ <li class="navigation-item">
+ <a class="navigation-link " href="/projects/">Projects</a>
+ </li>
+
+ <li class="navigation-item">
+ <a class="navigation-link " href="/contact/">Contact</a>
+ </li>
+
+ <li class="navigation-item">
+ <a class="navigation-link " href="/pay-with-bitcoin/">Pay</a>
+ </li>
+
+
+
+ </ul>
+
+ </section>
+</nav>
+
+
+ <div class="content">
+
+ <section class="container list">
+ <header>
+ <h1 class="title">
+ <a class="title-link" href="http://jackmordaunt.com/tags/interface/">Tag: Interface</a>
+ </h1>
+ </header>
+
+ <ul>
+
+ <li>
+ <span class="date">August 1, 2025</span>
+ <a class="title" href="/posts/what-is-an-interface/">What is an Interface</a>
+ </li>
+
+ </ul>
+
+
+
+
+
+
+
+</section>
+
+
+ </div>
+
+ <footer class="footer">
+ <section class="container">
+ ©
+
+ 2025
+ Jack Mordaunt
+ ·
+
+ Powered by <a href="https://gohugo.io/" target="_blank" rel="noopener">Hugo</a> & <a href="https://github.com/luizdepra/hugo-coder/" target="_blank" rel="noopener">Coder</a>.
+
+ </section>
+</footer>
+
+ </main>
+
+
+
+
+
+ <script src="/js/coder.min.6ae284be93d2d19dad1f02b0039508d9aab3180a12a06dcc71b0b0ef7825a317.js" integrity="sha256-auKEvpPS0Z2tHwKwA5UI2aqzGAoSoG3McbCw73gloxc="></script>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+</body>
+</html>
diff --git a/public/tags/interface/index.xml b/public/tags/interface/index.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
+ <channel>
+ <title>Interface on Jack Mordaunt</title>
+ <link>http://jackmordaunt.com/tags/interface/</link>
+ <description>Recent content in Interface on Jack Mordaunt</description>
+ <generator>Hugo</generator>
+ <language>en</language>
+ <lastBuildDate>Fri, 01 Aug 2025 06:26:18 -0300</lastBuildDate>
+ <atom:link href="http://jackmordaunt.com/tags/interface/index.xml" rel="self" type="application/rss+xml" />
+ <item>
+ <title>What is an Interface</title>
+ <link>http://jackmordaunt.com/posts/what-is-an-interface/</link>
+ <pubDate>Fri, 01 Aug 2025 06:26:18 -0300</pubDate>
+ <guid>http://jackmordaunt.com/posts/what-is-an-interface/</guid>
+ <description><p><strong>Behavioral Polymorphism: The foundation of OOP.</strong></p>
<p>The <strong>interface</strong> is the foundation of OOP (Object Oriented Programming).</p>
<p>It provides <em>behavioral polymorphism</em>: constraining a type by its behaviours -
or more secifically, its method-set.</p>
<blockquote>
<p>A &ldquo;method&rdquo; (as termed in OOP langauges) is nothing more than a procedure who&rsquo;s
first argument is a pointer to the object it is associated with. There is
nothing special about a method.</p></blockquote>
<p><strong>Definitions</strong></p>
<ul>
<li><strong>Poly</strong>: many</li>
<li><strong>Mono</strong>: singular</li>
<li><strong>Morphism</strong>: shape</li>
<li><strong>Polymorphism</strong>: having many shapes</li>
<li><strong>Monomorphism</strong>: having one shape</li>
</ul>
<p>Polymorphic refers to the ability to represent many shapes.</p></description>
+ </item>
+ </channel>
+</rss>
diff --git a/public/tags/interface/page/1/index.html b/public/tags/interface/page/1/index.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <title>http://jackmordaunt.com/tags/interface/</title>
+ <link rel="canonical" href="http://jackmordaunt.com/tags/interface/">
+ <meta name="robots" content="noindex">
+ <meta charset="utf-8">
+ <meta http-equiv="refresh" content="0; url=http://jackmordaunt.com/tags/interface/">
+ </head>
+</html>
diff --git a/public/tags/odin/index.html b/public/tags/odin/index.html
@@ -156,6 +156,11 @@
<ul>
<li>
+ <span class="date">August 1, 2025</span>
+ <a class="title" href="/posts/what-is-an-interface/">What is an Interface</a>
+ </li>
+
+ <li>
<span class="date">July 23, 2025</span>
<a class="title" href="/posts/why-people-hate-go/">Why People Love to Hate Go</a>
</li>
diff --git a/public/tags/odin/index.xml b/public/tags/odin/index.xml
@@ -6,9 +6,16 @@
<description>Recent content in Odin on Jack Mordaunt</description>
<generator>Hugo</generator>
<language>en</language>
- <lastBuildDate>Wed, 23 Jul 2025 14:16:55 -0300</lastBuildDate>
+ <lastBuildDate>Fri, 01 Aug 2025 06:26:18 -0300</lastBuildDate>
<atom:link href="http://jackmordaunt.com/tags/odin/index.xml" rel="self" type="application/rss+xml" />
<item>
+ <title>What is an Interface</title>
+ <link>http://jackmordaunt.com/posts/what-is-an-interface/</link>
+ <pubDate>Fri, 01 Aug 2025 06:26:18 -0300</pubDate>
+ <guid>http://jackmordaunt.com/posts/what-is-an-interface/</guid>
+ <description><p><strong>Behavioral Polymorphism: The foundation of OOP.</strong></p>
<p>The <strong>interface</strong> is the foundation of OOP (Object Oriented Programming).</p>
<p>It provides <em>behavioral polymorphism</em>: constraining a type by its behaviours -
or more secifically, its method-set.</p>
<blockquote>
<p>A &ldquo;method&rdquo; (as termed in OOP langauges) is nothing more than a procedure who&rsquo;s
first argument is a pointer to the object it is associated with. There is
nothing special about a method.</p></blockquote>
<p><strong>Definitions</strong></p>
<ul>
<li><strong>Poly</strong>: many</li>
<li><strong>Mono</strong>: singular</li>
<li><strong>Morphism</strong>: shape</li>
<li><strong>Polymorphism</strong>: having many shapes</li>
<li><strong>Monomorphism</strong>: having one shape</li>
</ul>
<p>Polymorphic refers to the ability to represent many shapes.</p></description>
+ </item>
+ <item>
<title>Why People Love to Hate Go</title>
<link>http://jackmordaunt.com/posts/why-people-hate-go/</link>
<pubDate>Wed, 23 Jul 2025 14:16:55 -0300</pubDate>
diff --git a/public/tags/oop/index.html b/public/tags/oop/index.html
@@ -0,0 +1,237 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+ <title>Tag: OOP · Jack Mordaunt</title>
+ <meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<meta name="color-scheme" content="light dark">
+
+
+
+
+<meta name="author" content="Jack Mordaunt">
+<meta name="description" content="Coffee developer, software brewer.">
+<meta name="keywords" content="blog,developer,personal,software,robust,performance,sovereign">
+
+
+
+ <meta name="twitter:card" content="summary">
+ <meta name="twitter:title" content="OOP">
+ <meta name="twitter:description" content="Coffee developer, software brewer.">
+
+<meta property="og:url" content="http://jackmordaunt.com/tags/oop/">
+ <meta property="og:site_name" content="Jack Mordaunt">
+ <meta property="og:title" content="OOP">
+ <meta property="og:description" content="Coffee developer, software brewer.">
+ <meta property="og:locale" content="en">
+ <meta property="og:type" content="website">
+
+
+
+
+<link rel="canonical" href="http://jackmordaunt.com/tags/oop/">
+
+
+<link rel="preload" href="/fonts/fa-brands-400.woff2" as="font" type="font/woff2" crossorigin>
+<link rel="preload" href="/fonts/fa-regular-400.woff2" as="font" type="font/woff2" crossorigin>
+<link rel="preload" href="/fonts/fa-solid-900.woff2" as="font" type="font/woff2" crossorigin>
+
+
+
+
+ <link rel="stylesheet" href="/css/coder.min.6445a802b9389c9660e1b07b724dcf5718b1065ed2d71b4eeaf981cc7cc5fc46.css" integrity="sha256-ZEWoArk4nJZg4bB7ck3PVxixBl7S1xtO6vmBzHzF/EY=" crossorigin="anonymous" media="screen" />
+
+
+
+
+
+
+
+
+
+ <link rel="stylesheet" href="/css/coder-dark.min.a00e6364bacbc8266ad1cc81230774a1397198f8cfb7bcba29b7d6fcb54ce57f.css" integrity="sha256-oA5jZLrLyCZq0cyBIwd0oTlxmPjPt7y6KbfW/LVM5X8=" crossorigin="anonymous" media="screen" />
+
+
+
+
+
+
+
+ <link rel="stylesheet" href="/css/custom.min.931a9d02d6f7655cd0cd50317fac1204e00c54ffd0232085acc957b2db5e1283.css" integrity="sha256-kxqdAtb3ZVzQzVAxf6wSBOAMVP/QIyCFrMlXstteEoM=" crossorigin="anonymous" media="screen" />
+
+
+
+
+
+
+<link rel="icon" type="image/svg+xml" href="/images/self-tiny-white.svg" sizes="any">
+<link rel="icon" type="image/png" href="/images/self-tiny-white.png" sizes="32x32">
+<link rel="icon" type="image/png" href="/images/self-tiny-white.png" sizes="16x16">
+
+<link rel="apple-touch-icon" href="/images/apple-touch-icon.png">
+<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon.png">
+
+<link rel="manifest" href="/site.webmanifest">
+<link rel="mask-icon" href="/images/safari-pinned-tab.svg" color="#5bbad5">
+
+
+<link rel="alternate" type="application/rss+xml" href="/tags/oop/index.xml" title="Jack Mordaunt" />
+
+
+
+
+
+
+
+</head>
+
+
+
+
+
+
+<body class="preload-transitions colorscheme-auto">
+
+<div class="float-container">
+ <a id="dark-mode-toggle" class="colorscheme-toggle">
+ <i class="fa-solid fa-adjust fa-fw" aria-hidden="true"></i>
+ </a>
+</div>
+
+
+ <main class="wrapper">
+ <nav class="navigation">
+ <section class="container">
+
+ <a class="navigation-title" href="http://jackmordaunt.com/">
+ Jack Mordaunt
+ </a>
+
+
+ <input type="checkbox" id="menu-toggle" />
+ <label class="menu-button float-right" for="menu-toggle">
+ <i class="fa-solid fa-bars fa-fw" aria-hidden="true"></i>
+ </label>
+ <ul class="navigation-list">
+
+
+ <li class="navigation-item">
+ <a class="navigation-link " href="/posts/">Blog</a>
+ </li>
+
+ <li class="navigation-item">
+ <a class="navigation-link " href="/about/">About</a>
+ </li>
+
+ <li class="navigation-item">
+ <a class="navigation-link " href="/projects/">Projects</a>
+ </li>
+
+ <li class="navigation-item">
+ <a class="navigation-link " href="/contact/">Contact</a>
+ </li>
+
+ <li class="navigation-item">
+ <a class="navigation-link " href="/pay-with-bitcoin/">Pay</a>
+ </li>
+
+
+
+ </ul>
+
+ </section>
+</nav>
+
+
+ <div class="content">
+
+ <section class="container list">
+ <header>
+ <h1 class="title">
+ <a class="title-link" href="http://jackmordaunt.com/tags/oop/">Tag: OOP</a>
+ </h1>
+ </header>
+
+ <ul>
+
+ <li>
+ <span class="date">August 1, 2025</span>
+ <a class="title" href="/posts/what-is-an-interface/">What is an Interface</a>
+ </li>
+
+ </ul>
+
+
+
+
+
+
+
+</section>
+
+
+ </div>
+
+ <footer class="footer">
+ <section class="container">
+ ©
+
+ 2025
+ Jack Mordaunt
+ ·
+
+ Powered by <a href="https://gohugo.io/" target="_blank" rel="noopener">Hugo</a> & <a href="https://github.com/luizdepra/hugo-coder/" target="_blank" rel="noopener">Coder</a>.
+
+ </section>
+</footer>
+
+ </main>
+
+
+
+
+
+ <script src="/js/coder.min.6ae284be93d2d19dad1f02b0039508d9aab3180a12a06dcc71b0b0ef7825a317.js" integrity="sha256-auKEvpPS0Z2tHwKwA5UI2aqzGAoSoG3McbCw73gloxc="></script>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+</body>
+</html>
diff --git a/public/tags/oop/index.xml b/public/tags/oop/index.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
+ <channel>
+ <title>OOP on Jack Mordaunt</title>
+ <link>http://jackmordaunt.com/tags/oop/</link>
+ <description>Recent content in OOP on Jack Mordaunt</description>
+ <generator>Hugo</generator>
+ <language>en</language>
+ <lastBuildDate>Fri, 01 Aug 2025 06:26:18 -0300</lastBuildDate>
+ <atom:link href="http://jackmordaunt.com/tags/oop/index.xml" rel="self" type="application/rss+xml" />
+ <item>
+ <title>What is an Interface</title>
+ <link>http://jackmordaunt.com/posts/what-is-an-interface/</link>
+ <pubDate>Fri, 01 Aug 2025 06:26:18 -0300</pubDate>
+ <guid>http://jackmordaunt.com/posts/what-is-an-interface/</guid>
+ <description><p><strong>Behavioral Polymorphism: The foundation of OOP.</strong></p>
<p>The <strong>interface</strong> is the foundation of OOP (Object Oriented Programming).</p>
<p>It provides <em>behavioral polymorphism</em>: constraining a type by its behaviours -
or more secifically, its method-set.</p>
<blockquote>
<p>A &ldquo;method&rdquo; (as termed in OOP langauges) is nothing more than a procedure who&rsquo;s
first argument is a pointer to the object it is associated with. There is
nothing special about a method.</p></blockquote>
<p><strong>Definitions</strong></p>
<ul>
<li><strong>Poly</strong>: many</li>
<li><strong>Mono</strong>: singular</li>
<li><strong>Morphism</strong>: shape</li>
<li><strong>Polymorphism</strong>: having many shapes</li>
<li><strong>Monomorphism</strong>: having one shape</li>
</ul>
<p>Polymorphic refers to the ability to represent many shapes.</p></description>
+ </item>
+ </channel>
+</rss>
diff --git a/public/tags/oop/page/1/index.html b/public/tags/oop/page/1/index.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <title>http://jackmordaunt.com/tags/oop/</title>
+ <link rel="canonical" href="http://jackmordaunt.com/tags/oop/">
+ <meta name="robots" content="noindex">
+ <meta charset="utf-8">
+ <meta http-equiv="refresh" content="0; url=http://jackmordaunt.com/tags/oop/">
+ </head>
+</html>