site

personal website, served at mordaunt.dev/site
Log | Files | Refs

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:
Acontent/posts/what-is-an-interface.md | 228+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mhugo.toml | 2+-
Mpublic/index.html | 4+++-
Mpublic/posts/index.html | 4++++
Mpublic/posts/index.xml | 9++++++++-
Apublic/posts/what-is-an-interface/index.html | 476+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mpublic/sitemap.xml | 39++++++++++++++++++++++++---------------
Mpublic/tags/go/index.html | 5+++++
Mpublic/tags/go/index.xml | 9++++++++-
Mpublic/tags/index.html | 24+++++++++++++++++++++++-
Mpublic/tags/index.xml | 20+++++++++++++++++---
Apublic/tags/interface/index.html | 237+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apublic/tags/interface/index.xml | 19+++++++++++++++++++
Apublic/tags/interface/page/1/index.html | 10++++++++++
Mpublic/tags/odin/index.html | 5+++++
Mpublic/tags/odin/index.xml | 9++++++++-
Apublic/tags/oop/index.html | 237+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apublic/tags/oop/index.xml | 19+++++++++++++++++++
Apublic/tags/oop/page/1/index.html | 10++++++++++
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>&lt;p&gt;&lt;strong&gt;Behavioral Polymorphism: The foundation of OOP.&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;The &lt;strong&gt;interface&lt;/strong&gt; is the foundation of OOP (Object Oriented Programming).&lt;/p&gt;&#xA;&lt;p&gt;It provides &lt;em&gt;behavioral polymorphism&lt;/em&gt;: constraining a type by its behaviours -&#xA;or more secifically, its method-set.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;A &amp;ldquo;method&amp;rdquo; (as termed in OOP langauges) is nothing more than a procedure who&amp;rsquo;s&#xA;first argument is a pointer to the object it is associated with. There is&#xA;nothing special about a method.&lt;/p&gt;&lt;/blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;Definitions&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;Poly&lt;/strong&gt;: many&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Mono&lt;/strong&gt;: singular&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Morphism&lt;/strong&gt;: shape&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Polymorphism&lt;/strong&gt;: having many shapes&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Monomorphism&lt;/strong&gt;: having one shape&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Polymorphic refers to the ability to represent many shapes.&lt;/p&gt;</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 &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> +<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&rsquo;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">-&gt;</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">-&gt;</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">&#34;core:bytes&#34;</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">&#34;core:io&#34;</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">&#34;core:os/os2&#34;</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">&#34;file&#34;</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">&amp;</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">&amp;</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&rsquo;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">-&gt;</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">-&gt;</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">-&gt;</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&rsquo;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>&lt;p&gt;&lt;strong&gt;Behavioral Polymorphism: The foundation of OOP.&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;The &lt;strong&gt;interface&lt;/strong&gt; is the foundation of OOP (Object Oriented Programming).&lt;/p&gt;&#xA;&lt;p&gt;It provides &lt;em&gt;behavioral polymorphism&lt;/em&gt;: constraining a type by its behaviours -&#xA;or more secifically, its method-set.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;A &amp;ldquo;method&amp;rdquo; (as termed in OOP langauges) is nothing more than a procedure who&amp;rsquo;s&#xA;first argument is a pointer to the object it is associated with. There is&#xA;nothing special about a method.&lt;/p&gt;&lt;/blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;Definitions&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;Poly&lt;/strong&gt;: many&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Mono&lt;/strong&gt;: singular&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Morphism&lt;/strong&gt;: shape&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Polymorphism&lt;/strong&gt;: having many shapes&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Monomorphism&lt;/strong&gt;: having one shape&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Polymorphic refers to the ability to represent many shapes.&lt;/p&gt;</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>&lt;p&gt;&lt;strong&gt;Behavioral Polymorphism: The foundation of OOP.&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;The &lt;strong&gt;interface&lt;/strong&gt; is the foundation of OOP (Object Oriented Programming).&lt;/p&gt;&#xA;&lt;p&gt;It provides &lt;em&gt;behavioral polymorphism&lt;/em&gt;: constraining a type by its behaviours -&#xA;or more secifically, its method-set.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;A &amp;ldquo;method&amp;rdquo; (as termed in OOP langauges) is nothing more than a procedure who&amp;rsquo;s&#xA;first argument is a pointer to the object it is associated with. There is&#xA;nothing special about a method.&lt;/p&gt;&lt;/blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;Definitions&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;Poly&lt;/strong&gt;: many&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Mono&lt;/strong&gt;: singular&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Morphism&lt;/strong&gt;: shape&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Polymorphism&lt;/strong&gt;: having many shapes&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Monomorphism&lt;/strong&gt;: having one shape&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Polymorphic refers to the ability to represent many shapes.&lt;/p&gt;</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>&lt;p&gt;&lt;strong&gt;Behavioral Polymorphism: The foundation of OOP.&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;The &lt;strong&gt;interface&lt;/strong&gt; is the foundation of OOP (Object Oriented Programming).&lt;/p&gt;&#xA;&lt;p&gt;It provides &lt;em&gt;behavioral polymorphism&lt;/em&gt;: constraining a type by its behaviours -&#xA;or more secifically, its method-set.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;A &amp;ldquo;method&amp;rdquo; (as termed in OOP langauges) is nothing more than a procedure who&amp;rsquo;s&#xA;first argument is a pointer to the object it is associated with. There is&#xA;nothing special about a method.&lt;/p&gt;&lt;/blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;Definitions&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;Poly&lt;/strong&gt;: many&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Mono&lt;/strong&gt;: singular&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Morphism&lt;/strong&gt;: shape&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Polymorphism&lt;/strong&gt;: having many shapes&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Monomorphism&lt;/strong&gt;: having one shape&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Polymorphic refers to the ability to represent many shapes.&lt;/p&gt;</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>&lt;p&gt;&lt;strong&gt;Behavioral Polymorphism: The foundation of OOP.&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;The &lt;strong&gt;interface&lt;/strong&gt; is the foundation of OOP (Object Oriented Programming).&lt;/p&gt;&#xA;&lt;p&gt;It provides &lt;em&gt;behavioral polymorphism&lt;/em&gt;: constraining a type by its behaviours -&#xA;or more secifically, its method-set.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;A &amp;ldquo;method&amp;rdquo; (as termed in OOP langauges) is nothing more than a procedure who&amp;rsquo;s&#xA;first argument is a pointer to the object it is associated with. There is&#xA;nothing special about a method.&lt;/p&gt;&lt;/blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;Definitions&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;Poly&lt;/strong&gt;: many&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Mono&lt;/strong&gt;: singular&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Morphism&lt;/strong&gt;: shape&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Polymorphism&lt;/strong&gt;: having many shapes&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Monomorphism&lt;/strong&gt;: having one shape&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Polymorphic refers to the ability to represent many shapes.&lt;/p&gt;</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>