<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title></title>
    <link rel="self" type="application/atom+xml" href="https://burakemir.ch/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://burakemir.ch"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2025-12-16T00:00:00+00:00</updated>
    <id>https://burakemir.ch/atom.xml</id>
    <entry xml:lang="en">
        <title>Building a Wasm Runner with Cloud Hypervisor</title>
        <published>2025-12-16T00:00:00+00:00</published>
        <updated>2025-12-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://burakemir.ch/post/building-wasm-runner/"/>
        <id>https://burakemir.ch/post/building-wasm-runner/</id>
        
        <content type="html" xml:base="https://burakemir.ch/post/building-wasm-runner/">&lt;p&gt;In this post, I will demonstrate how to run WebAssembly (Wasm) inside a MicroVM. I&#x27;ll provide context first, then focus on a few selected implementation details.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;wasm-for-extensibility&quot;&gt;Wasm for Extensibility&lt;&#x2F;h2&gt;
&lt;p&gt;Architecture defines what parts of a system are stable and what parts are dynamic. System extensions are a prime example of dynamic components, but they raise significant security and observability concerns—especially when the code is untrusted.&lt;&#x2F;p&gt;
&lt;p&gt;Consider this scenario:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;I need to run user-provided code.&lt;&#x2F;li&gt;
&lt;li&gt;I do not trust this code.&lt;&#x2F;li&gt;
&lt;li&gt;The system must load, execute, and potentially unload the code at runtime without build dependencies.&lt;&#x2F;li&gt;
&lt;li&gt;It must be efficient.&lt;&#x2F;li&gt;
&lt;li&gt;It must support user-friendly debugging.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This mirrors the challenges faced by cloud providers and security-conscious platform engineers.&lt;&#x2F;p&gt;
&lt;p&gt;WebAssembly (Wasm) is an excellent fit for this because:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Many languages compile to Wasm.&lt;&#x2F;li&gt;
&lt;li&gt;Wasm is designed for a specific execution environment (the runtime).&lt;&#x2F;li&gt;
&lt;li&gt;The runtime is extensible.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The Wasm runtime allows running user code that interacts with the &quot;outside&quot; through a well-defined interface. Note that &quot;runtime&quot; here is synonymous with &quot;execution environment&quot; or &quot;virtual machine&quot; (like the JVM).&lt;&#x2F;p&gt;
&lt;p&gt;In summary, Wasm allows us to run code while the runtime manages the API and isolation. Problem solved? Not quite.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sandboxing-the-sandbox&quot;&gt;Sandboxing the Sandbox&lt;&#x2F;h2&gt;
&lt;p&gt;The isolation provided by a Wasm runtime reduces the privileges of user code (sandboxing), but risks remain:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The Wasm runtime itself may have vulnerabilities.&lt;&#x2F;li&gt;
&lt;li&gt;The API exposed to user code might inadvertently allow unsafe access to the operating system.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Wasm acts as a security boundary, but mistakes are possible. Two levels of isolation provide significantly better security.&lt;&#x2F;p&gt;
&lt;p&gt;In this post, we will set up a &quot;MicroVM&quot; to execute Wasm payloads. We will build a minimal Function-as-a-Service (FaaS) runtime from scratch using Rust, &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cloud-hypervisor&#x2F;cloud-hypervisor&quot;&gt;Cloud Hypervisor&lt;&#x2F;a&gt;, and Wasmtime. This setup will boot a Linux kernel, load a WebAssembly module over a virtual socket, and execute it.&lt;&#x2F;p&gt;
&lt;p&gt;If you are familiar with Microsoft&#x27;s &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;hyperlight-dev&#x2F;hyperlight-wasm&quot;&gt;Hyperlight-Wasm&lt;&#x2F;a&gt;, this approach is similar but focuses on the fundamentals.&lt;&#x2F;p&gt;
&lt;p&gt;To follow along, you need a Linux machine with KVM enabled and the ability to configure and build a Linux kernel. If you are using a cloud VPS, ensure nested virtualization is enabled.&lt;&#x2F;p&gt;
&lt;p&gt;Unlike many minimal tutorials that use static linking (musl), we will use a dynamically linked C runtime. This allows us to use the standard system unwinder (glibc), providing full panic stack traces inside the VM—crucial for debugging failing user code.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-architecture&quot;&gt;The Architecture&lt;&#x2F;h3&gt;
&lt;p&gt;Cloud Hypervisor is a virtual machine monitor (VMM) written in Rust, descending from the CrosVM and Firecracker family. It simulates hardware abstractions rather than executing high-level language instructions.&lt;&#x2F;p&gt;
&lt;p&gt;We will simulate a machine that boots a minimal Linux kernel, which then executes the Wasm runtime as its &lt;em&gt;only&lt;&#x2F;em&gt; process.&lt;&#x2F;p&gt;
&lt;p&gt;We will use &quot;Direct Kernel Boot&quot; with the following components:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The Hypervisor:&lt;&#x2F;strong&gt; Cloud Hypervisor (built in Rust, runs on top of KVM).&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;The Guest Kernel:&lt;&#x2F;strong&gt; A minimal Linux kernel (&lt;code&gt;vmlinux&lt;&#x2F;code&gt;).&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;The Guest OS:&lt;&#x2F;strong&gt; A custom Initramfs containing our Rust binary and necessary shared libraries (&lt;code&gt;libc.so&lt;&#x2F;code&gt;, &lt;code&gt;libgcc&lt;&#x2F;code&gt;, etc.).&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;The Payload:&lt;&#x2F;strong&gt; A Wasm module that performs pure computation.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;The Transport:&lt;&#x2F;strong&gt; VirtIO-VSOCK, providing a direct pipe between host and guest.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;step-1-the-minimal-kernel&quot;&gt;Step 1: The Minimal Kernel&lt;&#x2F;h3&gt;
&lt;p&gt;Cloud Hypervisor works best with a kernel tuned for PVH booting (skipping legacy BIOS&#x2F;UEFI).&lt;&#x2F;p&gt;
&lt;p&gt;Follow instructions on &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cloud-hypervisor&#x2F;cloud-hypervisor?tab=readme-ov-file#building-your-kernel&quot;&gt;Cloud Hypervisor docs&lt;&#x2F;a&gt; or
build the kernel your own way using &lt;code&gt;make menuconfig&lt;&#x2F;code&gt;. Ensure the following are set to &lt;strong&gt;Yes&lt;&#x2F;strong&gt; (not Module):&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;CONFIG_PVH=y&lt;&#x2F;code&gt;: For fast booting.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;CONFIG_VIRTIO_PCI=y&lt;&#x2F;code&gt;: To see virtual hardware.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;CONFIG_VIRTIO_VSOCKETS=y&lt;&#x2F;code&gt;: For communication.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;CONFIG_BLK_DEV_INITRD=y&lt;&#x2F;code&gt;: To load the custom binary.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;step-2-the-wasm-payload&quot;&gt;Step 2: The Wasm Payload&lt;&#x2F;h3&gt;
&lt;p&gt;We need code to run. We’ll compile this Rust function to &lt;code&gt;wasm32-unknown-unknown&lt;&#x2F;code&gt; to keep it &quot;pure&quot;—no system calls, just math and memory.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;wasm_payload&#x2F;src&#x2F;lib.rs&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#383838;color:#e6e1dc;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;&#x2F;&#x2F; A 1MB static buffer inside the Wasm linear memory
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6d9cbe;&quot;&gt;BUF_SIZE&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;usize &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;1024 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;1024&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;static &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;mut &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6d9cbe;&quot;&gt;BUFFER&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6d9cbe;&quot;&gt;BUF_SIZE&lt;&#x2F;span&gt;&lt;span&gt;] &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6d9cbe;&quot;&gt;BUF_SIZE&lt;&#x2F;span&gt;&lt;span&gt;];
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;#[unsafe(no_mangle)]
&lt;&#x2F;span&gt;&lt;span&gt;#[allow(static_mut_refs)]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;pub extern &lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;C&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;get_buffer_ptr&lt;&#x2F;span&gt;&lt;span&gt;() -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;*mut &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;u8 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;unsafe &lt;&#x2F;span&gt;&lt;span&gt;{ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6d9cbe;&quot;&gt;BUFFER&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;as_mut_ptr&lt;&#x2F;span&gt;&lt;span&gt;() }
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;#[unsafe(no_mangle)]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;pub extern &lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;C&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;process_data&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#fd971f;&quot;&gt;len&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;usize &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; slice &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= unsafe &lt;&#x2F;span&gt;&lt;span&gt;{ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;amp;mut &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6d9cbe;&quot;&gt;BUFFER&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;..&lt;&#x2F;span&gt;&lt;span&gt;len] };
&lt;&#x2F;span&gt;&lt;span&gt;    
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;&#x2F;&#x2F; Example: Reverse the bytes
&lt;&#x2F;span&gt;&lt;span&gt;    slice.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;reverse&lt;&#x2F;span&gt;&lt;span&gt;();
&lt;&#x2F;span&gt;&lt;span&gt;    
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;&#x2F;&#x2F; Return the length processed
&lt;&#x2F;span&gt;&lt;span&gt;    len
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Compile it:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#383838;color:#e6e1dc;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span&gt;cargo build&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#fd971f;&quot;&gt; --target&lt;&#x2F;span&gt;&lt;span&gt; wasm32-unknown-unknown&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#fd971f;&quot;&gt; --release
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you have not compiled to Wasm before, you may want to run &lt;code&gt;rustup target add wasm32-unknown-unknown&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;step-3-the-guest-init-the-micro-os&quot;&gt;Step 3: The Guest &quot;Init&quot; (The Micro-OS)&lt;&#x2F;h3&gt;
&lt;p&gt;We will write a Rust program that acts as the entire guest operating system (init process). It boots, listens on a socket, runs Wasm, and shuts down. Interaction happens via system calls, mediated by the C runtime library.&lt;&#x2F;p&gt;
&lt;p&gt;We use a Dual-Socket design:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Port 1000 (Control):&lt;&#x2F;strong&gt; Metadata, Wasm binary uploads, status signals.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Port 1001 (Data):&lt;&#x2F;strong&gt; Raw data stream.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This allows streaming data directly from the socket into the Wasm memory buffer. Zero-copy isn&#x27;t possible here because we must copy data into the Wasm module instance&#x27;s memory to maintain isolation.&lt;&#x2F;p&gt;
&lt;p&gt;The following demo code implements this, using tokio (1, &quot;full&quot; features), tokio-vsock (0.3) and Wasmtime (24.0) API calls.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;guest_init&#x2F;src&#x2F;main.rs&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#383838;color:#e6e1dc;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;use &lt;&#x2F;span&gt;&lt;span&gt;tokio::io::{AsyncReadExt, AsyncWriteExt};
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;use &lt;&#x2F;span&gt;&lt;span&gt;tokio_vsock::VsockListener;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;use &lt;&#x2F;span&gt;&lt;span&gt;wasmtime::&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6d9cbe;&quot;&gt;CMD_PORT&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;u32 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;1000&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6d9cbe;&quot;&gt;DATA_PORT&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;u32 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;1001&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;#[tokio::main]
&lt;&#x2F;span&gt;&lt;span&gt;async &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;main&lt;&#x2F;span&gt;&lt;span&gt;() {
&lt;&#x2F;span&gt;&lt;span&gt;    println!(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;[Guest] Booting Dual-Socket Runner...&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;&#x2F;&#x2F; 1. Setup Wasm Engine
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; config &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;Config::new();
&lt;&#x2F;span&gt;&lt;span&gt;    config.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;async_support&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6e9cbe;&quot;&gt;true&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; engine &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;Engine::new(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;config).&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;unwrap&lt;&#x2F;span&gt;&lt;span&gt;();
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; linker &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;Linker::new(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;engine);
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; store &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;Store::new(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;engine, ());
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;&#x2F;&#x2F; 2. Start Listeners
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; cmd_listener &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= 
&lt;&#x2F;span&gt;&lt;span&gt;        VsockListener::bind(&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6d9cbe;&quot;&gt;MAX&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6d9cbe;&quot;&gt;CMD_PORT&lt;&#x2F;span&gt;&lt;span&gt;).&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;expect&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;Bind CMD failed&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; data_listener &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= 
&lt;&#x2F;span&gt;&lt;span&gt;        VsockListener::bind(&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6d9cbe;&quot;&gt;MAX&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6d9cbe;&quot;&gt;DATA_PORT&lt;&#x2F;span&gt;&lt;span&gt;).&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;expect&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;Bind DATA failed&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;    
&lt;&#x2F;span&gt;&lt;span&gt;    println!(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;[Guest] Waiting for Host to connect...&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;&#x2F;&#x2F; 3. Accept Connections (Sequential for simplicity)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;&#x2F;&#x2F; Host must connect to CMD first, then DATA.
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; cmd_stream, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;_&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; cmd_listener.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;accept&lt;&#x2F;span&gt;&lt;span&gt;().await.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;unwrap&lt;&#x2F;span&gt;&lt;span&gt;();
&lt;&#x2F;span&gt;&lt;span&gt;    println!(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;[Guest] CMD connected.&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;    
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; data_stream, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;_&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; data_listener.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;accept&lt;&#x2F;span&gt;&lt;span&gt;().await.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;unwrap&lt;&#x2F;span&gt;&lt;span&gt;();
&lt;&#x2F;span&gt;&lt;span&gt;    println!(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;[Guest] DATA connected.&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;&#x2F;&#x2F; 4. Receive Wasm Binary (over CMD channel for reliability)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; size_buf &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;];
&lt;&#x2F;span&gt;&lt;span&gt;    cmd_stream.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;read_exact&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;amp;mut&lt;&#x2F;span&gt;&lt;span&gt; size_buf).await.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;unwrap&lt;&#x2F;span&gt;&lt;span&gt;();
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; wasm_len &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;::from_be_bytes(size_buf) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;as &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    println!(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;[Guest] Downloading Wasm module (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6d9cbe;&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt; bytes)...&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, wasm_len);
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; wasm_binary &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;vec![&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;; wasm_len];
&lt;&#x2F;span&gt;&lt;span&gt;    cmd_stream.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;read_exact&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;amp;mut&lt;&#x2F;span&gt;&lt;span&gt; wasm_binary).await.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;unwrap&lt;&#x2F;span&gt;&lt;span&gt;();
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;&#x2F;&#x2F; 5. Instantiate
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; module &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;Module::new(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;engine, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;wasm_binary).&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;unwrap&lt;&#x2F;span&gt;&lt;span&gt;();
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; instance &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; linker.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;instantiate_async&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;amp;mut&lt;&#x2F;span&gt;&lt;span&gt; store, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;module).await.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;unwrap&lt;&#x2F;span&gt;&lt;span&gt;();
&lt;&#x2F;span&gt;&lt;span&gt;    
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; memory &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; instance.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;get_memory&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;amp;mut&lt;&#x2F;span&gt;&lt;span&gt; store, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;memory&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;expect&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;No memory exported&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; get_ptr &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; instance.get_typed_func::&amp;lt;(), &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;i32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;amp;mut&lt;&#x2F;span&gt;&lt;span&gt; store, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;get_buffer_ptr&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;unwrap&lt;&#x2F;span&gt;&lt;span&gt;();
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; process_func &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; instance.get_typed_func::&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;i32&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;i32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;amp;mut&lt;&#x2F;span&gt;&lt;span&gt; store, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;process_data&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;unwrap&lt;&#x2F;span&gt;&lt;span&gt;();
&lt;&#x2F;span&gt;&lt;span&gt;    
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; wasm_ptr &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; get_ptr.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;call_async&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;amp;mut&lt;&#x2F;span&gt;&lt;span&gt; store, ()).await.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;unwrap&lt;&#x2F;span&gt;&lt;span&gt;() &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;as &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    println!(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;[Guest] Wasm Ready. Entering Processing Loop.&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;_ =&lt;&#x2F;span&gt;&lt;span&gt; cmd_stream.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;write_all&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;b&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;READY&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;).await; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;&#x2F;&#x2F; Signal Host
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;&#x2F;&#x2F; 6. Processing Loop
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;loop &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;&#x2F;&#x2F; A. Wait for Command: &amp;quot;Process X bytes&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; job_header &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;];
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; cmd_stream.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;read_exact&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;amp;mut&lt;&#x2F;span&gt;&lt;span&gt; job_header).await.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;is_err&lt;&#x2F;span&gt;&lt;span&gt;() { &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;break&lt;&#x2F;span&gt;&lt;span&gt;; }
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; data_len &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;::from_be_bytes(job_header) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;as &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;        eprintln!(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;Expecting Payload len &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6d9cbe;&quot;&gt;{data_len}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;!&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;&#x2F;&#x2F; B. READ DIRECTLY TO WASM MEMORY
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;&#x2F;&#x2F; We get a mutable slice of Wasm memory.
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; mem_data &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; memory.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;data_mut&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;amp;mut&lt;&#x2F;span&gt;&lt;span&gt; store);
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;&#x2F;&#x2F; Safety check bounds
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; wasm_ptr &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; data_len &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; mem_data.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;len&lt;&#x2F;span&gt;&lt;span&gt;() {
&lt;&#x2F;span&gt;&lt;span&gt;            eprintln!(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;Payload too big for Wasm buffer!&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;break&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; wasm_slice &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &amp;amp;mut&lt;&#x2F;span&gt;&lt;span&gt; mem_data[wasm_ptr &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;..&lt;&#x2F;span&gt;&lt;span&gt; wasm_ptr &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; data_len];
&lt;&#x2F;span&gt;&lt;span&gt;        
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;&#x2F;&#x2F; This is the key step: Kernel copies socket buffer -&amp;gt; Wasm Memory directly.
&lt;&#x2F;span&gt;&lt;span&gt;        data_stream.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;read_exact&lt;&#x2F;span&gt;&lt;span&gt;(wasm_slice).await.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;unwrap&lt;&#x2F;span&gt;&lt;span&gt;();
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;        eprintln!(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;Read data!!&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;&#x2F;&#x2F; C. EXECUTE
&lt;&#x2F;span&gt;&lt;span&gt;        process_func.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;call_async&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;amp;mut&lt;&#x2F;span&gt;&lt;span&gt; store, data_len &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;as &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;i32&lt;&#x2F;span&gt;&lt;span&gt;).await.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;unwrap&lt;&#x2F;span&gt;&lt;span&gt;();
&lt;&#x2F;span&gt;&lt;span&gt;        eprintln!(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;Made call!!&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;&#x2F;&#x2F; D. WRITE DIRECTLY FROM WASM MEMORY
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; mem_data &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; memory.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;data&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;store); &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;&#x2F;&#x2F; Re-borrow immutable
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; result_slice &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;mem_data[wasm_ptr &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;..&lt;&#x2F;span&gt;&lt;span&gt; wasm_ptr &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; data_len];
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;        eprintln!(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;Writing result!!&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;        data_stream.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;write_all&lt;&#x2F;span&gt;&lt;span&gt;(result_slice).await.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;unwrap&lt;&#x2F;span&gt;&lt;span&gt;();
&lt;&#x2F;span&gt;&lt;span&gt;        
&lt;&#x2F;span&gt;&lt;span&gt;        eprintln!(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;Writing done!!&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;&#x2F;&#x2F; E. Ack
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;_ =&lt;&#x2F;span&gt;&lt;span&gt; cmd_stream.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;write_all&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;b&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;DONE&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;).await;
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;building-the-image&quot;&gt;Building the Image&lt;&#x2F;h3&gt;
&lt;p&gt;We gather all files for the guest filesystem. Apart from the guest init binary, we need some files to support dynamic linking of the C runtime library.&lt;&#x2F;p&gt;
&lt;p&gt;Many tutorials suggest compiling with &lt;code&gt;x86_64-unknown-linux-musl&lt;&#x2F;code&gt; to get a single static binary. While this is small (5MB), it breaks the ability to get stack traces because the musl unwinder often conflicts with JIT compilers like Wasmtime.&lt;&#x2F;p&gt;
&lt;p&gt;Instead, we compile normally which on Linux will link dynamically against glibc. We then bundle the shared libraries and ship them into the VM.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#383838;color:#e6e1dc;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span&gt;cargo build&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#fd971f;&quot;&gt; --release 
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We use a script to automatically find the required &lt;code&gt;.so&lt;&#x2F;code&gt; files (&lt;code&gt;libc.so.6&lt;&#x2F;code&gt;, &lt;code&gt;libgcc_s.so.1&lt;&#x2F;code&gt;, etc.) and package them into the initramfs.
Please note that my cargo outputs binaries into &lt;code&gt;&#x2F;tmp&lt;&#x2F;code&gt;, you may need to adjust the paths to the binary.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;package_vm.sh&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#383838;color:#e6e1dc;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;font-style:italic;color:#7c7865;&quot;&gt;#!&#x2F;bin&#x2F;bash
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;set &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#fd971f;&quot;&gt;-e
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d0d0ff;&quot;&gt;APP_NAME&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;guest_init&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d0d0ff;&quot;&gt;BIN_PATH&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;&#x2F;tmp&#x2F;target&#x2F;release&#x2F;$&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d0d0ff;&quot;&gt;APP_NAME&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d0d0ff;&quot;&gt;BUILD_DIR&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;.&#x2F;build_output&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#7c7865;&quot;&gt;# 1. Clean and Create Staging Area
&lt;&#x2F;span&gt;&lt;span&gt;rm&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#fd971f;&quot;&gt; -rf &lt;&#x2F;span&gt;&lt;span&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d0d0ff;&quot;&gt;BUILD_DIR
&lt;&#x2F;span&gt;&lt;span&gt;mkdir&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#fd971f;&quot;&gt; -p &lt;&#x2F;span&gt;&lt;span&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d0d0ff;&quot;&gt;BUILD_DIR&lt;&#x2F;span&gt;&lt;span&gt;&#x2F;lib64
&lt;&#x2F;span&gt;&lt;span&gt;mkdir&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#fd971f;&quot;&gt; -p &lt;&#x2F;span&gt;&lt;span&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d0d0ff;&quot;&gt;BUILD_DIR&lt;&#x2F;span&gt;&lt;span&gt;&#x2F;lib&#x2F;x86_64-linux-gnu
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#7c7865;&quot;&gt;# 2. Copy the Main Binary to &#x2F;init
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;echo &lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;Copying binary...&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;cp $&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d0d0ff;&quot;&gt;BIN_PATH &lt;&#x2F;span&gt;&lt;span&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d0d0ff;&quot;&gt;BUILD_DIR&lt;&#x2F;span&gt;&lt;span&gt;&#x2F;init
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#7c7865;&quot;&gt;# 3. Find and Copy Shared Libraries
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;echo &lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;Resolving dependencies...&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#7c7865;&quot;&gt;# Get list of dependencies using ldd
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#7c7865;&quot;&gt;# Output format is usually: &amp;quot;libname.so =&amp;gt; &#x2F;path&#x2F;to&#x2F;libname.so (address)&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d0d0ff;&quot;&gt;DEPENDENCIES&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;$(ldd $&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d0d0ff;&quot;&gt;BIN_PATH &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;awk &amp;#39;{if ($3 != &amp;quot;&amp;quot;) print $3; else print $1}&amp;#39;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; DEP &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d0d0ff;&quot;&gt;DEPENDENCIES&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;; do
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#7c7865;&quot;&gt;# Skip virtual dynamically linked things like linux-vdso.so.1
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;[[ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;$&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d0d0ff;&quot;&gt;DEP&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;== *&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;vdso&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;]]&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;; then
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;continue
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;fi
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#7c7865;&quot;&gt;# Check if file exists
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;[ &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#fd971f;&quot;&gt;-f &lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;$&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d0d0ff;&quot;&gt;DEP&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;; then
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;echo &lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;  Bundling: $&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d0d0ff;&quot;&gt;DEP&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#7c7865;&quot;&gt;# We need to copy it to the SAME path structure relative to root
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#7c7865;&quot;&gt;# e.g., &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libc.so.6 
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#7c7865;&quot;&gt;#        --&amp;gt; build_output&#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libc.so.6
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d0d0ff;&quot;&gt;DIRname&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;$(dirname &lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;$&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d0d0ff;&quot;&gt;DEP&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;        mkdir&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#fd971f;&quot;&gt; -p &lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;$&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d0d0ff;&quot;&gt;BUILD_DIR&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d0d0ff;&quot;&gt;DIRname&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;        cp &lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;$&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d0d0ff;&quot;&gt;DEP&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot; &amp;quot;$&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d0d0ff;&quot;&gt;BUILD_DIR&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d0d0ff;&quot;&gt;DEP&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;else
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;echo &lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;  Warning: Could not find $&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d0d0ff;&quot;&gt;DEP&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;fi
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;done
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#7c7865;&quot;&gt;# 4. Handle the Dynamic Linker explicitly
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#7c7865;&quot;&gt;# ldd output often shows the loader as a full path, but we need to ensure
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#7c7865;&quot;&gt;# the interpreter path hardcoded in the binary exists.
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d0d0ff;&quot;&gt;INTERPRETER&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;$(readelf&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#fd971f;&quot;&gt; -l &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d0d0ff;&quot;&gt;BIN_PATH &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;\
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;grep &lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;interpreter&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;awk&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#fd971f;&quot;&gt; -F&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&amp;#39;: &amp;#39; &amp;#39;{print $2}&amp;#39; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;tr&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#fd971f;&quot;&gt; -d &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&amp;#39;]&amp;#39;)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;echo &lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;  Bundling Interpreter: $&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d0d0ff;&quot;&gt;INTERPRETER&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;[ &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#fd971f;&quot;&gt;-f &lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;$&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d0d0ff;&quot;&gt;INTERPRETER&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;; then
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d0d0ff;&quot;&gt;DIRname&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;$(dirname &lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;$&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d0d0ff;&quot;&gt;INTERPRETER&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    mkdir&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#fd971f;&quot;&gt; -p &lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;$&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d0d0ff;&quot;&gt;BUILD_DIR&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d0d0ff;&quot;&gt;DIRname&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    cp &lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;$&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d0d0ff;&quot;&gt;INTERPRETER&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot; &amp;quot;$&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d0d0ff;&quot;&gt;BUILD_DIR&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d0d0ff;&quot;&gt;INTERPRETER&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;fi
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#7c7865;&quot;&gt;# 5. Create CPIO
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;echo &lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;Creating initramfs.cpio...&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;cd &lt;&#x2F;span&gt;&lt;span&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d0d0ff;&quot;&gt;BUILD_DIR
&lt;&#x2F;span&gt;&lt;span&gt;find .&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#fd971f;&quot;&gt; -print0 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span&gt;cpio&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#fd971f;&quot;&gt; --null -ov --format&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;newc &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; ..&#x2F;initramfs.cpio
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;cd&lt;&#x2F;span&gt;&lt;span&gt; ..
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;echo &lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;Done! Dynamic initramfs ready.&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This increases the image size to ~25MB, but in return, if our Rust code panics or Wasmtime crashes, we get a full, readable stack trace in the console.&lt;&#x2F;p&gt;
&lt;p&gt;At this point, we have neatly packaged up everything we need into a CPIO archive that we will use with Cloud Hypervisor&#x27;s direct kernel boot method in a bit.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;step-4-the-host-driver&quot;&gt;Step 4: The Host Driver&lt;&#x2F;h3&gt;
&lt;p&gt;We implement the host driver in Rust to orchestrate the VM. It connects to the Cloud Hypervisor via the Unix domain socket &lt;code&gt;&#x2F;tmp&#x2F;ch_vsock.sock&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;The &quot;Connect String&quot; Mechanism&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Cloud Hypervisor uses a Unix domain socket on the host to expose the VSOCK capability. It acts as a bridge. However, unlike a direct socket connection where you just connect and talk, Cloud Hypervisor acts as a multiplexer.&lt;&#x2F;p&gt;
&lt;p&gt;When we connect to the Unix socket, we are talking to the Hypervisor, not the guest yet. We must tell the Hypervisor which &lt;em&gt;guest port&lt;&#x2F;em&gt; we want to reach. We do this by sending a text command:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;CONNECT &amp;lt;PORT&amp;gt;\n&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If the connection is successful, Cloud Hypervisor will respond with:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;OK &amp;lt;PORT&amp;gt;\n&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Only &lt;em&gt;after&lt;&#x2F;em&gt; receiving this acknowledgement can we start sending raw binary data intended for the guest. If we skip this, our data will be interpreted as commands by the Hypervisor, causing errors.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;host_runner&#x2F;src&#x2F;main.rs&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#383838;color:#e6e1dc;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;use &lt;&#x2F;span&gt;&lt;span&gt;tokio::io::{AsyncReadExt, AsyncWriteExt};
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;use &lt;&#x2F;span&gt;&lt;span&gt;tokio::net::UnixStream;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;use &lt;&#x2F;span&gt;&lt;span&gt;std::time::Duration;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6d9cbe;&quot;&gt;SOCKET_PATH&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;str &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;&#x2F;tmp&#x2F;ch_vsock.sock&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6d9cbe;&quot;&gt;CMD_PORT&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;u32 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;1000&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6d9cbe;&quot;&gt;DATA_PORT&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;u32 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;1001&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;#[tokio::main]
&lt;&#x2F;span&gt;&lt;span&gt;async &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;main&lt;&#x2F;span&gt;&lt;span&gt;() -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;Result&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;(), &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;Box&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;    println!(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;[Host] Connecting to Guest via &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6d9cbe;&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;...&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6d9cbe;&quot;&gt;SOCKET_PATH&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;&#x2F;&#x2F; 1. Connect to Guest (Retry loop until Guest is up)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; cmd_stream &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;connect_via_unix&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6d9cbe;&quot;&gt;SOCKET_PATH&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6d9cbe;&quot;&gt;CMD_PORT&lt;&#x2F;span&gt;&lt;span&gt;).await&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; data_stream &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;connect_via_unix&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6d9cbe;&quot;&gt;SOCKET_PATH&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6d9cbe;&quot;&gt;DATA_PORT&lt;&#x2F;span&gt;&lt;span&gt;).await&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;&#x2F;&#x2F; 2. Read Wasm Binary
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; wasm_path &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;target&#x2F;wasm32-unknown-unknown&#x2F;release&#x2F;payload.wasm&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; wasm_binary &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;std::fs::read(wasm_path).&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;expect&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;Failed to read Wasm file&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; wasm_len &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; wasm_binary.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;len&lt;&#x2F;span&gt;&lt;span&gt;() &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;as &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;&#x2F;&#x2F; 3. Send Wasm Binary
&lt;&#x2F;span&gt;&lt;span&gt;    println!(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;[Host] Sending Wasm binary...&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;    cmd_stream.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;write_all&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;wasm_len.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;to_be_bytes&lt;&#x2F;span&gt;&lt;span&gt;()).await&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    cmd_stream.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;write_all&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;wasm_binary).await&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;&#x2F;&#x2F; 4. Wait for Ready Signal from Guest
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; buf &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;]; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;&#x2F;&#x2F; &amp;quot;READY&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    cmd_stream.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;read_exact&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;amp;mut&lt;&#x2F;span&gt;&lt;span&gt; buf).await&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    assert_eq!(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;buf, &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;b&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;READY&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;    println!(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;[Host] Guest is READY.&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;&#x2F;&#x2F; 5. Send Data Job
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; payload &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;b&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;Hello MicroVM!&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; payload_len &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; payload.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;len&lt;&#x2F;span&gt;&lt;span&gt;() &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;as &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    cmd_stream.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;write_all&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;payload_len.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;to_be_bytes&lt;&#x2F;span&gt;&lt;span&gt;()).await&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    data_stream.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;write_all&lt;&#x2F;span&gt;&lt;span&gt;(payload).await&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;&#x2F;&#x2F; 6. Receive Result
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; result_buf &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;vec![&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;; payload_len &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;as &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;];
&lt;&#x2F;span&gt;&lt;span&gt;    data_stream.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;read_exact&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;amp;mut&lt;&#x2F;span&gt;&lt;span&gt; result_buf).await&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    println!(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;[Host] Result: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6d9cbe;&quot;&gt;{:?}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;String&lt;&#x2F;span&gt;&lt;span&gt;::from_utf8_lossy(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;result_buf));
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;Ok&lt;&#x2F;span&gt;&lt;span&gt;(())
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;async &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;connect_via_unix&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#fd971f;&quot;&gt;path&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#fd971f;&quot;&gt;port&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;) 
&lt;&#x2F;span&gt;&lt;span&gt;        -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;Result&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;UnixStream, &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;Box&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;loop &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;match &lt;&#x2F;span&gt;&lt;span&gt;UnixStream::connect(path).await {
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;Ok&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; stream) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;&#x2F;&#x2F; Handshake for Cloud Hypervisor
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; msg &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;format!(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;CONNECT &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6d9cbe;&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#519f50;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, port);
&lt;&#x2F;span&gt;&lt;span&gt;                stream.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;write_all&lt;&#x2F;span&gt;&lt;span&gt;(msg.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;as_bytes&lt;&#x2F;span&gt;&lt;span&gt;()).await&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;                
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;&#x2F;&#x2F; Read Response: &amp;quot;OK &amp;lt;port&amp;gt;\n&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; resp &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;String&lt;&#x2F;span&gt;&lt;span&gt;::new();
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;loop &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;                    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; b &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;];
&lt;&#x2F;span&gt;&lt;span&gt;                    stream.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;read_exact&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;amp;mut&lt;&#x2F;span&gt;&lt;span&gt; b).await&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;                    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; c &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; b[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;] &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;as &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;char&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;                    resp.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;push&lt;&#x2F;span&gt;&lt;span&gt;(c);
&lt;&#x2F;span&gt;&lt;span&gt;                    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; c &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;== &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#519f50;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&amp;#39; &lt;&#x2F;span&gt;&lt;span&gt;{ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;break&lt;&#x2F;span&gt;&lt;span&gt;; }
&lt;&#x2F;span&gt;&lt;span&gt;                }
&lt;&#x2F;span&gt;&lt;span&gt;                
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;if !&lt;&#x2F;span&gt;&lt;span&gt;resp.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;starts_with&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;OK&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;) {
&lt;&#x2F;span&gt;&lt;span&gt;                     &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;Err&lt;&#x2F;span&gt;&lt;span&gt;(format!(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;Handshake failed: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6d9cbe;&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, resp.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;trim&lt;&#x2F;span&gt;&lt;span&gt;()).&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;into&lt;&#x2F;span&gt;&lt;span&gt;());
&lt;&#x2F;span&gt;&lt;span&gt;                }
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;Ok&lt;&#x2F;span&gt;&lt;span&gt;(stream);
&lt;&#x2F;span&gt;&lt;span&gt;            },
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;Err&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;_&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;&#x2F;&#x2F; Wait for Cloud Hypervisor to create the socket
&lt;&#x2F;span&gt;&lt;span&gt;                tokio::time::sleep(Duration::from_millis(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;500&lt;&#x2F;span&gt;&lt;span&gt;)).await;
&lt;&#x2F;span&gt;&lt;span&gt;            }
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;step-5-launch&quot;&gt;Step 5: Launch!&lt;&#x2F;h3&gt;
&lt;p&gt;We invoke Cloud Hypervisor, pointing it to our kernel, our CPIO (initramfs), and enabling the VSOCK device.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#383838;color:#e6e1dc;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span&gt;sudo .&#x2F;cloud-hypervisor \
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#fd971f;&quot;&gt;    --kernel&lt;&#x2F;span&gt;&lt;span&gt; .&#x2F;vmlinux \
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#fd971f;&quot;&gt;    --cmdline &lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;console=hvc0 quiet&amp;quot; &lt;&#x2F;span&gt;&lt;span&gt;\
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#fd971f;&quot;&gt;    --initramfs&lt;&#x2F;span&gt;&lt;span&gt; .&#x2F;initramfs.cpio \
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#fd971f;&quot;&gt;    --vsock&lt;&#x2F;span&gt;&lt;span&gt; cid=3,socket=&#x2F;tmp&#x2F;ch_vsock.sock
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In a separate terminal, run the Host Runner:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#383838;color:#e6e1dc;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span&gt;cargo run&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#fd971f;&quot;&gt; --release --bin&lt;&#x2F;span&gt;&lt;span&gt; host_runner
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h3&gt;
&lt;p&gt;We just built a secure, isolated runtime where:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Isolation:&lt;&#x2F;strong&gt; The code runs in a VM, not a container. The kernel enforces the boundary.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Observability:&lt;&#x2F;strong&gt; By shipping glibc, we have full debugging capabilities inside the guest.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Speed:&lt;&#x2F;strong&gt; By stripping the OS to the bare essentials and using VSOCK, overhead is minimal.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;There is a lot more here that can be done, like using virtiofs to expose selected files on the
host to the guest, tuning the kernel to optimize boot time, or system programming interface,
all the way to implementing hypercalls.&lt;&#x2F;p&gt;
&lt;p&gt;This architecture is the foundation of modern high-density serverless platforms. You now have the blueprint to build your own.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Indexed Reverse Polish Notation, an Alternative to AST</title>
        <published>2025-12-12T00:00:00+00:00</published>
        <updated>2025-12-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://burakemir.ch/post/indexed-rpn/"/>
        <id>https://burakemir.ch/post/indexed-rpn/</id>
        
        <content type="html" xml:base="https://burakemir.ch/post/indexed-rpn/">&lt;p&gt;&quot;Why study compiler construction? Because knowing how a programming language is specified
and implemented makes you a better programmer.&quot; I still remember these words,
pronounced as matter-of-fact introduction to an undergrad course of compilers.&lt;&#x2F;p&gt;
&lt;p&gt;Compiler engineers have come up with many useful programming techniques and representations.&lt;&#x2F;p&gt;
&lt;p&gt;Today, I want to write about one such technique, an alternative to Abstract Syntax Trees (ASTs).
Inspired by the parse tree representation in the &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;carbon-language&#x2F;carbon-lang&quot;&gt;Carbon compiler&lt;&#x2F;a&gt;,
this post explains a way to represent parsed source code using a variation of Reverse Polish Notation (RPN),
in a contiguous array.&lt;&#x2F;p&gt;
&lt;p&gt;We call this &lt;strong&gt;Indexed RPN&lt;&#x2F;strong&gt;. Ordering program parts in a linear sequence very naturally leads to
machine interpretation, which is well-known for calculators but maybe a little less well-known
when there are scoped definitions and control flow structures.&lt;&#x2F;p&gt;
&lt;p&gt;This is by no means a new way of doing things, but with modern machines having plenty of memory,
there may have been less pressure to reach for techniques that memory-friendly.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;1-from-arithmetic-to-indices&quot;&gt;1. From Arithmetic to Indices&lt;&#x2F;h2&gt;
&lt;p&gt;Let’s start with an arithmetic expression example: We want to represent (3 + 4) * 5.&lt;&#x2F;p&gt;
&lt;p&gt;In a standard AST, this is a tree of pointers. In a standard stack-machine RPN, this looks like 3 4 + 5 *.
Now we want something slightly different, because we want to operate on tree structure.
For example, if we deal with this expression in a compiler that translates and optimizes.
We want to be able to refer to specific sub-expressions later.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-administrative-normal-form-perspective&quot;&gt;The &quot;Administrative Normal Form&quot; Perspective&lt;&#x2F;h3&gt;
&lt;p&gt;Before we look at the memory layout, let&#x27;s imagine breaking up this expression by &lt;em&gt;naming&lt;&#x2F;em&gt; subexpression.
If we had local definitions in our language this would give us Administrative Normal Form (ANF).
In ANF, we give a name to every intermediate result:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#383838;color:#e6e1dc;&quot;&gt;&lt;code&gt;&lt;span&gt;&#x2F;&#x2F; Source: (3 + 4) * 5
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;val t0 = 3 
&lt;&#x2F;span&gt;&lt;span&gt;val t1 = 4
&lt;&#x2F;span&gt;&lt;span&gt;val t2 = add(t0, t1)
&lt;&#x2F;span&gt;&lt;span&gt;val t3 = 5
&lt;&#x2F;span&gt;&lt;span&gt;val t4 = mul(t2, t3)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The expression now takes a lot more to write, but for a compiler it is much more structured.
The arguments of the operations are always names, which makes the data flow and also the
order in which arguments get evaluated fully explicit. Here, &lt;code&gt;t2&lt;&#x2F;code&gt; depends entirely on &lt;code&gt;t0&lt;&#x2F;code&gt; and &lt;code&gt;t1&lt;&#x2F;code&gt;,
and &lt;code&gt;t0&lt;&#x2F;code&gt; is evaluated before &lt;code&gt;t1&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-in-memory-representation&quot;&gt;The In-Memory Representation&lt;&#x2F;h3&gt;
&lt;p&gt;We don&#x27;t want local definitions just yet, the above is just to motivate flattening of a tree structure.
If we store the instructions in a contiguous array (e.g., a vector or Vec), the &lt;strong&gt;index&lt;&#x2F;strong&gt; of the node becomes its name.&lt;&#x2F;p&gt;
&lt;p&gt;The internal names are merely indices into the sequence of nodes.&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=&quot;text-align: left&quot;&gt;Index (ID)&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: left&quot;&gt;Node Kind&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: left&quot;&gt;Operands &#x2F; Data&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;0&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;IntLiteral&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;3&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;1&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;IntLiteral&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;4&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;2&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;BinaryOp&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;Add(lhs: 0, rhs: 1)&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;3&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;IntLiteral&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;5&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;4&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;BinaryOp&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;Mul(lhs: 2, rhs: 3)&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;This is similar to Reverse Polish Notation (RPN), but there is a difference. In standard RPN, there is an implicit stack from which &lt;code&gt;Add&lt;&#x2F;code&gt; consumes items blindly. In &lt;strong&gt;Indexed RPN&lt;&#x2F;strong&gt;, &lt;code&gt;Add&lt;&#x2F;code&gt; explicitly refers to indices 0 and 1. This provides a stable reference to every sub-expression, allowing us to traverse the code and locate nodes without necessarily having to build up a stack.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;2-dealing-with-let-and-scope&quot;&gt;2. Dealing with &quot;Let&quot; and Scope&lt;&#x2F;h2&gt;
&lt;p&gt;Let us make the language more realistic by adding local let-declarations and scoping.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#383838;color:#e6e1dc;&quot;&gt;&lt;code&gt;&lt;span&gt;&#x2F;&#x2F; Source
&lt;&#x2F;span&gt;&lt;span&gt;let a = 10;
&lt;&#x2F;span&gt;&lt;span&gt;let b = a + 5;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Here we face a problem: Source variables (a, b) are different from our internal indices (0, 1, 2...). We need a node that bridges this gap — an &lt;strong&gt;&quot;Introducer&quot;&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-bind-node&quot;&gt;The Bind Node&lt;&#x2F;h3&gt;
&lt;p&gt;We introduce a Bind node. This node represents the action of bringing a name into existence in the current scope.
Depending on the language you are working with, a binding may have semantic significance. For example, if references to the binding are objects of the language like Rust or C++ references.&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=&quot;text-align: left&quot;&gt;Index&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: left&quot;&gt;Node Kind&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: left&quot;&gt;Operands&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: left&quot;&gt;Meaning&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;0&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;IntLiteral&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;10&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;The raw value 10.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;1&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;Bind&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;name: &quot;a&quot;, val: 0&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;Introducer&lt;&#x2F;strong&gt;: &quot;a&quot; exists, bound to Index 0.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;2&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;NameRef&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;ref: 1&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;A reference back to the introducer node.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;3&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;IntLiteral&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;5&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;The raw value 5.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;4&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;BinaryOp&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;Add(2, 3)&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Adds the NameRef and the Literal.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;5&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;Bind&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;name: &quot;b&quot;, val: 4&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;Introducer&lt;&#x2F;strong&gt;: &quot;b&quot; exists, bound to Index 4.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h3 id=&quot;the-stack-returns-for-compilation&quot;&gt;The Stack Returns (For Compilation)&lt;&#x2F;h3&gt;
&lt;p&gt;In order to deal with this data, we traverse it but we will also want to build up a stack. You might ask: &lt;em&gt;If we flattened the tree, why do we need a stack?&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;While the &lt;strong&gt;storage&lt;&#x2F;strong&gt; is flat, the &lt;strong&gt;compilation process&lt;&#x2F;strong&gt; requires a stack to handle scopes. Because let declarations can be nested, we cannot simply scan linearly and remember everything forever. We need to handle when names go &lt;em&gt;out&lt;&#x2F;em&gt; of scope (shadowing).&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s add &lt;code&gt;BlockStart&lt;&#x2F;code&gt; and &lt;code&gt;BlockEnd&lt;&#x2F;code&gt; nodes that indicate nested blocks.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#383838;color:#e6e1dc;&quot;&gt;&lt;code&gt;&lt;span&gt;&#x2F;&#x2F; Source Code
&lt;&#x2F;span&gt;&lt;span&gt;let x = 10;       &#x2F;&#x2F; Outer &amp;#39;x&amp;#39;
&lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    let x = 20;   &#x2F;&#x2F; Inner &amp;#39;x&amp;#39; (shadows outer)
&lt;&#x2F;span&gt;&lt;span&gt;    print(x);     &#x2F;&#x2F; Should print 20
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;print(x);         &#x2F;&#x2F; Should print 10
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;the-resolve-names-algorithm&quot;&gt;The resolve_names Algorithm&lt;&#x2F;h3&gt;
&lt;p&gt;I am too lazy for full code examples, just the idea.&lt;&#x2F;p&gt;
&lt;p&gt;We use a SymbolTableStack during the resolution pass.
We iterate through the array once. We maintain a stack of scopes, where each scope maps a string name to an integer index.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;Python&quot; style=&quot;background-color:#383838;color:#e6e1dc;&quot; class=&quot;language-Python &quot;&gt;&lt;code class=&quot;language-Python&quot; data-lang=&quot;Python&quot;&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;function resolve_names(nodes):
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;# A stack of scopes. Each scope is a Map: String -&amp;gt; Index
&lt;&#x2F;span&gt;&lt;span&gt;    scope_stack &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;[ new Map() ]
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span&gt;i, node &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;enumerate&lt;&#x2F;span&gt;&lt;span&gt;(nodes):
&lt;&#x2F;span&gt;&lt;span&gt;        
&lt;&#x2F;span&gt;&lt;span&gt;        match node.kind:
&lt;&#x2F;span&gt;&lt;span&gt;            case BlockStart:
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;# Push a new, empty scope onto the stack
&lt;&#x2F;span&gt;&lt;span&gt;                scope_stack.push( new Map() )
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;            case BlockEnd:
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;# Pop the top scope. Inner variables are forgotten.
&lt;&#x2F;span&gt;&lt;span&gt;                scope_stack.pop()
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;            case Bind(name, value_index):
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;# Register the variable in the CURRENT (top) scope.
&lt;&#x2F;span&gt;&lt;span&gt;                current_scope &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;scope_stack.top()
&lt;&#x2F;span&gt;&lt;span&gt;                current_scope.set(name, i)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;            case NameRef(name):
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;# Look for the name, starting from the top scope down.
&lt;&#x2F;span&gt;&lt;span&gt;                target_index &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;find_in_stack(scope_stack, name)
&lt;&#x2F;span&gt;&lt;span&gt;                
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;# PATCH THE NODE:
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;# The node no longer holds &amp;quot;x&amp;quot;. It holds the index (e.g., 4).
&lt;&#x2F;span&gt;&lt;span&gt;                node.resolved_index &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;target_index
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;After this pass, the stack is discarded. The IR is now &quot;wired.&quot; Every variable usage points directly to the instruction that created it.&lt;&#x2F;p&gt;
&lt;p&gt;When representing source as AST, we would use an algebraic data type. One could use mutable data structures there, or build up a symbol table.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;3-breaking-the-line-control-flow&quot;&gt;3. Breaking the Line: Control Flow&lt;&#x2F;h2&gt;
&lt;p&gt;So far, execution has been linear: Index 0, then 1, then 2. But branching constructs like if, else, and while break this line.&lt;&#x2F;p&gt;
&lt;p&gt;In a tree-based AST, an If node has children pointers to &quot;Then&quot; and &quot;Else&quot; blocks. In our flat array, we may prefer to have in the same contiguous vector, instead of blocks
floating in separate memory. So we introduce &lt;strong&gt;Jump&lt;&#x2F;strong&gt; nodes.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-linear-layout&quot;&gt;The Linear Layout&lt;&#x2F;h3&gt;
&lt;p&gt;Consider this source:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#383838;color:#e6e1dc;&quot;&gt;&lt;code&gt;&lt;span&gt;if (a) { print(1); } else { print(2); }
&lt;&#x2F;span&gt;&lt;span&gt;print(3);
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Here is the Indexed RPN layout. Note the use of &lt;code&gt;BrFalse&lt;&#x2F;code&gt; (Branch if False) and &lt;code&gt;Jmp&lt;&#x2F;code&gt; (Unconditional Jump).&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=&quot;text-align: left&quot;&gt;Index&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: left&quot;&gt;Node Kind&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: left&quot;&gt;Data&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: left&quot;&gt;Explanation&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;0&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;NameRef&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;&quot;a&quot;&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Load variable &lt;code&gt;a&lt;&#x2F;code&gt;.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;1&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;BrFalse&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;target: 5&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;If &lt;code&gt;a&lt;&#x2F;code&gt; is false, jump to Index 5 (Else).&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;2&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;Int&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;1&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Start of &quot;Then&quot; block.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;3&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;Print&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;2&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;4&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;Jmp&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;target: 7&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Jump over the &quot;Else&quot; block.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;5&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;Int&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;2&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Start of &quot;Else&quot; block (Target of node 1).&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;6&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;Print&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;5&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;7&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;Int&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;3&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;Merge Point.&lt;&#x2F;strong&gt; Execution continues here.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;8&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;Print&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;7&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h3 id=&quot;building-it-backpatching&quot;&gt;Building It: Backpatching&lt;&#x2F;h3&gt;
&lt;p&gt;When we emit the BrFalse instruction at index 1, we haven&#x27;t written the Else block yet, so we don&#x27;t know the target index.&lt;&#x2F;p&gt;
&lt;p&gt;It is quite straightforward to deal with that:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Emit BrFalse with a placeholder target. Save the index.&lt;&#x2F;li&gt;
&lt;li&gt;Emit the &quot;Then&quot; block.&lt;&#x2F;li&gt;
&lt;li&gt;Emit Jmp with a placeholder target. Save the index.&lt;&#x2F;li&gt;
&lt;li&gt;Mark the current index as the start of &quot;Else&quot;. &lt;strong&gt;Backpatch&lt;&#x2F;strong&gt; (update) the BrFalse at index 1.&lt;&#x2F;li&gt;
&lt;li&gt;Emit the &quot;Else&quot; block.&lt;&#x2F;li&gt;
&lt;li&gt;Mark the current index as the end. &lt;strong&gt;Backpatch&lt;&#x2F;strong&gt; the Jmp at index 4.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;This effectively flattens the logic of the program into a shape that mirrors how hardware executes instructions: predictable, linear memory access with explicit jumps.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;4-towards-interpretation-and-code-gen&quot;&gt;4. Towards Interpretation and Code Gen&lt;&#x2F;h2&gt;
&lt;p&gt;We have successfully flattened our source code. We have resolved variable names into absolute indices and lowered high-level control flow into jumps. Now comes the reward.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-interpreter-the-big-switch&quot;&gt;The Interpreter: The &quot;Big Switch&quot;&lt;&#x2F;h3&gt;
&lt;p&gt;Because our code is a flat array, we can come up with a Virtual Machine (VM) that looks exactly like a hardware CPU: it has an Instruction Pointer (ip) and a big loop.
As a reminder — I will never get tired of repeating this — the difference between a virtual machine and abstract machine is that a virtual machine
has &lt;em&gt;instructions&lt;&#x2F;em&gt;, whereas an abstract machine has &lt;em&gt;transitions&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;A translation to a low-level format and a virtual machine plays the role of an interpreter, which provides an implementation of our language. We &lt;em&gt;can&lt;&#x2F;em&gt; also use it to
specify the &lt;em&gt;operational semantics&lt;&#x2F;em&gt;, roughly: however you implement this language,
it should produce the same result as the reference interpreter. For &quot;real&quot; languages, often specification comes as an afterthought but there
are plenty of situations where one really would like to know how a piece of source code is supposed to behave. For example, to find out
if the &quot;real&quot; implementation is correct. Somehow, educated people who really should know better can parrot statements like &quot;undefined behavior is all about compiler optimizations&quot;
and completely ignore that &quot;undefined behavior&quot; is first and foremost a gap in the specification.&lt;&#x2F;p&gt;
&lt;p&gt;Back to our interpreter: we can do something really simple: since we used ANF, (where every node index represents a runtime value), we don&#x27;t even need a runtime stack for intermediate calculations. We can simply map the nodes array to a parallel values array. A real implementation would not do this, but if we use an interpreter solely to specify behavior, this is sufficient, and we can defer optimizations.
Note that since we have already resolved names to indices, instructions like &lt;code&gt;Bind&lt;&#x2F;code&gt; or &lt;code&gt;BlockStart&lt;&#x2F;code&gt; are effectively metadata. The interpreter can simply skip them.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;Python&quot; style=&quot;background-color:#383838;color:#e6e1dc;&quot; class=&quot;language-Python &quot;&gt;&lt;code class=&quot;language-Python&quot; data-lang=&quot;Python&quot;&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;function run_vm(nodes):
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;# Holds the runtime result of every node.
&lt;&#x2F;span&gt;&lt;span&gt;    values &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;new Array(&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#fd971f;&quot;&gt;size&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;len&lt;&#x2F;span&gt;&lt;span&gt;(nodes))
&lt;&#x2F;span&gt;&lt;span&gt;    ip &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;0
&lt;&#x2F;span&gt;&lt;span&gt;    
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;while &lt;&#x2F;span&gt;&lt;span&gt;ip &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;len&lt;&#x2F;span&gt;&lt;span&gt;(nodes):
&lt;&#x2F;span&gt;&lt;span&gt;        node &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;nodes[ip]
&lt;&#x2F;span&gt;&lt;span&gt;        
&lt;&#x2F;span&gt;&lt;span&gt;        match node.kind:
&lt;&#x2F;span&gt;&lt;span&gt;            case IntLiteral:
&lt;&#x2F;span&gt;&lt;span&gt;                values[ip] &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;node.raw_value
&lt;&#x2F;span&gt;&lt;span&gt;                ip &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;+= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;1
&lt;&#x2F;span&gt;&lt;span&gt;                
&lt;&#x2F;span&gt;&lt;span&gt;            case Add:
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;# Direct access by index! No stack popping needed.
&lt;&#x2F;span&gt;&lt;span&gt;                lhs_val &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;values[node.lhs_index]
&lt;&#x2F;span&gt;&lt;span&gt;                rhs_val &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;values[node.rhs_index]
&lt;&#x2F;span&gt;&lt;span&gt;                values[ip] &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;lhs_val &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;rhs_val
&lt;&#x2F;span&gt;&lt;span&gt;                ip &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;+= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;1
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;            case BrFalse:
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span&gt;values[node.cond_index] &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;== &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6e9cbe;&quot;&gt;False&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;                    ip &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;node.target_index &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;# JUMP
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;else&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;                    ip &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;+= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;1 
&lt;&#x2F;span&gt;&lt;span&gt;            
&lt;&#x2F;span&gt;&lt;span&gt;            case Jmp:
&lt;&#x2F;span&gt;&lt;span&gt;                ip &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;node.target_index &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;# Unconditional JUMP
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;            case &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d0d0ff;&quot;&gt;_&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;                 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;# Skip metadata nodes (Bind, BlockStart, etc.)
&lt;&#x2F;span&gt;&lt;span&gt;                 ip &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;+= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;1
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;the-code-generator&quot;&gt;The Code Generator&lt;&#x2F;h3&gt;
&lt;p&gt;We could also do a source-to-source translation and generate C code. The Indexed RPN shines again, because the complexity of the source language is reduced quite a bit.
Since instructions are topologically sorted and dependencies are explicit, generating C can be as simple as a single for loop where every node becomes a temporary variable t{i}.&lt;&#x2F;p&gt;
&lt;p&gt;This is maybe not a great way to specify what a language means, but a clear implementation advantage of translating to an existing language is that one can build
on top of an existing whole compiler, with optimizations, native code generation backends. How exactly the semantics and runtime aspects of the source language
and the target language are connected is of course a design choice and can be wildly different.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;Python&quot; style=&quot;background-color:#383838;color:#e6e1dc;&quot; class=&quot;language-Python &quot;&gt;&lt;code class=&quot;language-Python&quot; data-lang=&quot;Python&quot;&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;function generate_c_code(nodes):
&lt;&#x2F;span&gt;&lt;span&gt;    output &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;StringBuilder()
&lt;&#x2F;span&gt;&lt;span&gt;    output.append(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;int main() {&lt;&#x2F;span&gt;&lt;span style=&quot;color:#519f50;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span&gt;i, node &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;enumerate&lt;&#x2F;span&gt;&lt;span&gt;(nodes):
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;# 1. Create a label for every instruction so Jumps can find it
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;#    e.g., &amp;quot;L_0:&amp;quot;, &amp;quot;L_1:&amp;quot;, etc.
&lt;&#x2F;span&gt;&lt;span&gt;        output.append(&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;L_&lt;&#x2F;span&gt;&lt;span&gt;{i}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;: ;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#519f50;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;        
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;# 2. Create a variable name for this node&amp;#39;s result
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;#    e.g., &amp;quot;t_0&amp;quot;, &amp;quot;t_1&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;        var_name &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;t_&lt;&#x2F;span&gt;&lt;span&gt;{i}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;        
&lt;&#x2F;span&gt;&lt;span&gt;        match node.kind:
&lt;&#x2F;span&gt;&lt;span&gt;            case IntLiteral:
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;# int t_0 = 10;
&lt;&#x2F;span&gt;&lt;span&gt;                output.append(&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;    int &lt;&#x2F;span&gt;&lt;span&gt;{var_name}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt; = &lt;&#x2F;span&gt;&lt;span&gt;{node.value}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#519f50;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;                
&lt;&#x2F;span&gt;&lt;span&gt;            case Add:
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;# int t_2 = t_0 + t_1;
&lt;&#x2F;span&gt;&lt;span&gt;                lhs &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;t_&lt;&#x2F;span&gt;&lt;span&gt;{node.lhs_index}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;                rhs &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;t_&lt;&#x2F;span&gt;&lt;span&gt;{node.rhs_index}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;                output.append(&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;    int &lt;&#x2F;span&gt;&lt;span&gt;{var_name}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt; = &lt;&#x2F;span&gt;&lt;span&gt;{lhs}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt; + &lt;&#x2F;span&gt;&lt;span&gt;{rhs}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#519f50;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;            
&lt;&#x2F;span&gt;&lt;span&gt;            case Print:
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;# printf(&amp;quot;%d\n&amp;quot;, t_5);
&lt;&#x2F;span&gt;&lt;span&gt;                arg &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;t_&lt;&#x2F;span&gt;&lt;span&gt;{node.arg_index}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;                output.append(&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;    printf(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#519f50;&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;%d&lt;&#x2F;span&gt;&lt;span style=&quot;color:#519f50;&quot;&gt;\\&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;n&lt;&#x2F;span&gt;&lt;span style=&quot;color:#519f50;&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;{arg}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;);&lt;&#x2F;span&gt;&lt;span style=&quot;color:#519f50;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;            
&lt;&#x2F;span&gt;&lt;span&gt;            case BrFalse:
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;# if (!t_1) goto L_5;
&lt;&#x2F;span&gt;&lt;span&gt;                cond &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;t_&lt;&#x2F;span&gt;&lt;span&gt;{node.cond_index}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;                target &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;L_&lt;&#x2F;span&gt;&lt;span&gt;{node.target_index}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;                output.append(&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;    if (!&lt;&#x2F;span&gt;&lt;span&gt;{cond}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;) goto &lt;&#x2F;span&gt;&lt;span&gt;{target}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#519f50;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;            
&lt;&#x2F;span&gt;&lt;span&gt;            case Jmp:
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;# goto L_7;
&lt;&#x2F;span&gt;&lt;span&gt;                target &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;L_&lt;&#x2F;span&gt;&lt;span&gt;{node.target_index}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;                output.append(&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;    goto &lt;&#x2F;span&gt;&lt;span&gt;{target}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#519f50;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    output.append(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;    return 0;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#519f50;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span&gt;output.toString()
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h3&gt;
&lt;p&gt;People will always build more languages, especially domain-specific ones.
A realistic work-in-progress language that uses indexed RPN is &lt;a href=&quot;http:&#x2F;&#x2F;github.com&#x2F;carbon-language&#x2F;carbon-lang&#x2F;&quot;&gt;Carbon&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;By moving from a tree to an &lt;strong&gt;Indexed RPN&lt;&#x2F;strong&gt;, we replace heap allocations with a single contiguous vector. What was recursive tree-walking of AST can in many cases become index lookups.
So there should be a lot less memory-traffic, and when programs get large, memory traffic can have a significant impact on performance.&lt;&#x2F;p&gt;
&lt;p&gt;If you are like me and build toy programming language implementations for fun, consider trying this out and see how it works for you!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>From Operations to Effects: A Journey Through M-Sets</title>
        <published>2025-09-25T00:00:00+00:00</published>
        <updated>2025-09-25T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://burakemir.ch/post/from-operations-to-effects/"/>
        <id>https://burakemir.ch/post/from-operations-to-effects/</id>
        
        <content type="html" xml:base="https://burakemir.ch/post/from-operations-to-effects/">&lt;p&gt;This continues a meditation on effects. My last post on the various meanings of effects in the discourse on programming languages (PL)
did very little to show how type and effect discipline may be relevant to memory safety in programming languages.
Moreover, I encountered a statement I found easy to agree to &quot;before we talk about effects, we need to understand their semantics&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;This is an interesting challenge in itself. How do we define precisely what a program that performs I&#x2F;O actually &lt;em&gt;means&lt;&#x2F;em&gt;?
When your code says &lt;code&gt;IO::get&lt;&#x2F;code&gt;, how should we describe what is really happening? We can formally answer this by modeling
programs as sequences of operations. This journey will take us from a simple log of operations to the powerful idea of M-sets,
and finally draw a bridge to a possible type and effect systems approach.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;the-i-o-logbook-scroll&quot;&gt;The I&#x2F;O Logbook 📜&lt;&#x2F;h2&gt;
&lt;p&gt;Let&#x27;s start with a simple I&#x2F;O model. Imagine we only have two operations: reading an integer from an input stream and writing one to an output stream. We can define this set of operations, $OpIO$, as:&lt;&#x2F;p&gt;
&lt;p&gt;$$OpIO := \{ \mathtt{get} \} ∪ \{ \mathtt{put}_i \ | \ i \in \mathbb{N} \}$$&lt;&#x2F;p&gt;
&lt;p&gt;Instead of executing these operations immediately, let&#x27;s first think of a program as simply generating a &lt;strong&gt;log&lt;&#x2F;strong&gt; or a &lt;strong&gt;sequence&lt;&#x2F;strong&gt; of these operations. We can represent this sequence as $OpSeq$, which is the set of all possible finite sequences of $OpIO$ operations (in the
language of mathematics, this is the free monoid $OpIO^*$).&lt;&#x2F;p&gt;
&lt;p&gt;Under this model, the meaning of a program statement is defined by how it transforms this sequence. It&#x27;s a function from $OpSeq$ to $OpSeq$.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;let x = get&lt;&#x2F;code&gt; is a function that appends $ \mathtt{get} $ to the sequence.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;put 42&lt;&#x2F;code&gt; is a function that appends $ \mathtt{put}_{42} $ to the sequence.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;A program that reads an integer and then prints 42 simply produce the sequence $[\mathtt{get}, \mathtt{put}_{42}]$. OK,
that is maybe not breath-taking, but it is a start. This describes the &quot;runtime effects&quot; of a program (that word again), but
how can we see this as a declarative meaning of our program?&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h3 id=&quot;enter-the-m-set-the-interpreter-performing-arts&quot;&gt;Enter the M-Set: The Interpreter 🎭&lt;&#x2F;h3&gt;
&lt;p&gt;So, we have a sequence of operations. Now what? This is where &lt;strong&gt;M-sets&lt;&#x2F;strong&gt; come in.&lt;&#x2F;p&gt;
&lt;p&gt;An M-set (specifically an $OpSeq$-set in our case) is a mathematical structure that gives &lt;strong&gt;meaning&lt;&#x2F;strong&gt; to our sequence. You can think of it as a configurable &lt;strong&gt;interpreter&lt;&#x2F;strong&gt; for our log. The formal definition involves a &lt;em&gt;right action&lt;&#x2F;em&gt;, which specifies what will happen for every possible operation (get, put 42, etc.).&lt;&#x2F;p&gt;
&lt;p&gt;The beauty is that we can now assert that we &lt;strong&gt;parameterized&lt;&#x2F;strong&gt; our program&#x27;s meaning (the sequence) by an M-set. We can plug in
different M-sets to change the program&#x27;s behavior without changing the program itself:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Console M-set:&lt;&#x2F;strong&gt; A handler that interprets &lt;code&gt;get&lt;&#x2F;code&gt; by reading from the keyboard and &lt;code&gt;put i&lt;&#x2F;code&gt; by printing to the console.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;File M-set:&lt;&#x2F;strong&gt; A handler that interprets the operations by reading from and writing to a file.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Testing M-set:&lt;&#x2F;strong&gt; A handler that interprets &lt;code&gt;get&lt;&#x2F;code&gt; by returning a fixed value (e.g., 0) and &lt;code&gt;put i&lt;&#x2F;code&gt; by adding the integer to a test buffer.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The M-set is the semantic domain that brings our abstract sequence to life.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h3 id=&quot;beyond-i-o-the-case-of-memory-brain&quot;&gt;Beyond I&#x2F;O: The Case of Memory 🧠&lt;&#x2F;h3&gt;
&lt;p&gt;Why stop with I&#x2F;O? We can apply the exact same idea to memory management. Let&#x27;s define a new set of memory operations:&lt;&#x2F;p&gt;
&lt;p&gt;$$ OpMem := \{ \mathtt{alloc} \} ∪ \{ \mathtt{free\ n}\ |\ n \in \mathbb{N} \} $$&lt;&#x2F;p&gt;
&lt;p&gt;Here, $\mathtt{alloc}$ represents allocating a new memory location, and $\mathtt{free}\ n$ represents deallocating location $n$.
Just like before, a program&#x27;s interaction with memory can be modeled as a sequence $MemSeq = OpMem^*$. The M-set for this system
would be a model of a heap that defines the semantics of allocating and freeing memory.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h3 id=&quot;the-leap-to-type-and-effect-systems-sparkles&quot;&gt;The Leap to Type and Effect Systems ✨&lt;&#x2F;h3&gt;
&lt;p&gt;In many cases, tracking the &lt;em&gt;exact&lt;&#x2F;em&gt; sequence of operations is overkill. We often don&#x27;t need to know the entire history; we just want a &lt;strong&gt;summary&lt;&#x2F;strong&gt; of what a function might do. This is the leap from concrete sequences to abstract &lt;strong&gt;effects&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The operations we&#x27;ve been discussing — get, put, alloc, free — can be called (runtime) &lt;strong&gt;effects&lt;&#x2F;strong&gt;. A &lt;strong&gt;type and effect system&lt;&#x2F;strong&gt; is a
static analysis tool, built into a compiler, that tracks the set of effects a piece of code might trigger.&lt;&#x2F;p&gt;
&lt;p&gt;Instead of a concrete sequence like [&quot;alloc&quot;, &quot;free 0&quot;], the effect system provides an &lt;strong&gt;approximation&lt;&#x2F;strong&gt;. It tells us that a function has the potential to perform the effects {alloc, free}. These effects become part of the function&#x27;s type, giving developers a clear contract about what the function can do.&lt;&#x2F;p&gt;
&lt;p&gt;Furthermore, effects can be parameterized. A function type might look like this:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#383838;color:#e6e1dc;&quot;&gt;&lt;code&gt;&lt;span&gt;fn update(x: &amp;amp;mut T) -&amp;gt; () effect { free(x[*]) }
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This signature tells us that the update function &lt;em&gt;may&lt;&#x2F;em&gt; free the memory associated with its parameter x. This brings us to a crucial point: effects are an &lt;strong&gt;approximation&lt;&#x2F;strong&gt;. The &lt;code&gt;free(x[*])&lt;&#x2F;code&gt; effect means the function &lt;em&gt;may&lt;&#x2F;em&gt; release memory associated with elements &lt;code&gt;x[i]&lt;&#x2F;code&gt;, not
that it &lt;em&gt;will&lt;&#x2F;em&gt; on every execution path. This conservative approach is essential for guaranteeing safety.&lt;&#x2F;p&gt;
&lt;p&gt;And so, we&#x27;ve traveled from a concrete sequence of operations, to a semantic interpreter (the M-set), all the way to an abstract
summary of behavior used in modern type and effect systems to help us write safer, more predictable code. Lots of open
questions here how information expressed in this language of effects (the annotations on the types) could be used for
checking - we cannot talk about runtime values, only refer to them indirectly through expressions that talk about
some set of locations. Unrestricted aliasing may make it impossible to decide whether two expressions refer to an overlapping set
of memory locations. It does seem like a step towards something interesting.&lt;&#x2F;p&gt;
&lt;p&gt;We started with a modest goal: have an answer to the question on the semantics of effects. It looks like we got there:
effects (effect annotations) are may-approximations of runtime effects.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Three meanings of Effects</title>
        <published>2025-09-19T00:00:00+00:00</published>
        <updated>2025-09-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://burakemir.ch/post/three-meanings-of-effects/"/>
        <id>https://burakemir.ch/post/three-meanings-of-effects/</id>
        
        <content type="html" xml:base="https://burakemir.ch/post/three-meanings-of-effects/">&lt;p&gt;In the programming languages discourse, the word &quot;effect&quot; is used with different meanings.&lt;&#x2F;p&gt;
&lt;p&gt;This can lead to confusion. In research, it is difficult to avoid jargon, but it
comes at the price of making it more difficult to make sense of interconnected meanings
programming language concepts.&lt;&#x2F;p&gt;
&lt;p&gt;Effects - in more than one sense - are interesting today. The software industry is gearing up
to move its system programming artifacts from a dark swamp of legacy
into the flushing green meadows of &lt;em&gt;memory safety&lt;&#x2F;em&gt;.
I argue between the lines of &lt;a href=&quot;&#x2F;post&#x2F;memory-safety-the-missing-def&quot;&gt;Memory Safety - the missing definition&lt;&#x2F;a&gt;,
programming language design is the source and cause of all memory safety problems.
Maybe effects can help turn it into a solution.&lt;&#x2F;p&gt;
&lt;p&gt;In the following, I will establish a baseline and then enumerate the three specialized meanings for &quot;effects&quot;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Type and Effect Systems&lt;&#x2F;li&gt;
&lt;li&gt;Notions-of-Computation Effects&lt;&#x2F;li&gt;
&lt;li&gt;Effect Handlers (Algebraic Effects)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I am not aware of others meanings. The TL;DR is that type and effect systems come from a
very different tradition than computational effects and effect handlers.&lt;&#x2F;p&gt;
&lt;p&gt;This is not merely a terminology discussion, but an analytical effort fishing deep in semantics and
pragmatics territory. Before we take the plunge, we have to establish a baseline, though.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;side-effects&quot;&gt;Side Effects&lt;&#x2F;h2&gt;
&lt;p&gt;Imperative programming is about manipulation of state (memory, IO, ...) through a sequence of commands.
Choosing this way to program has consequences on our ability to define a &lt;em&gt;static semantics&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;By static semantics, we mean a type system that determines which programs we consider valid.
This enable us to reason about properties of programs without having to run them.&lt;&#x2F;p&gt;
&lt;p&gt;Imperative programs are composed of &quot;functions&quot; (really: procedures).
We may assign a type to a function to describe inputs and output. This type does not contain
any information about the state manipulation. If we imagine a function as a
transformation process with a &quot;main&quot; direction going from input to output, the interactions
that are not part of the output have been called &lt;strong&gt;side effects&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;These functions are not mathematical functions, even if mathematics is what led to computers
and &quot;computation&quot;. Thinking about this may tempt us to go on a philosophical tangent on &lt;a href=&quot;https:&#x2F;&#x2F;bq9.blogspot.com&#x2F;2020&#x2F;07&#x2F;language-logic-and-modeling.html&quot;&gt;epistemology&lt;&#x2F;a&gt;
and the &lt;a href=&quot;https:&#x2F;&#x2F;philpapers.org&#x2F;rec&#x2F;PICTMO-8&quot;&gt;Mangle of Practice&lt;&#x2F;a&gt;, but this is for another
time and another post.&lt;&#x2F;p&gt;
&lt;p&gt;One often encounters &quot;pure&quot; as an adjective for functions that do not have side-effects.
This is as if side effects taint the purity of mathematics, and indeed formal reasoning
becomes harder in languages with side effects (evaluation order matters). Is it possible
to define a static semantics that retains essential information?&lt;&#x2F;p&gt;
&lt;p&gt;Type systems are the most widespread and effective way to get static semantics. They are
a special form of static analysis that is built into the programming language design.
So why not add effects to type system and track more information that way?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;type-and-effect-system&quot;&gt;Type and Effect System&lt;&#x2F;h2&gt;
&lt;p&gt;A type and effect system is just that: the enrichment of types with annotations.&lt;&#x2F;p&gt;
&lt;p&gt;The first effect system was about memory access: Lucassen, Gifford &lt;a href=&quot;https:&#x2F;&#x2F;dl.acm.org&#x2F;doi&#x2F;pdf&#x2F;10.1145&#x2F;319838.319848&quot;&gt;&quot;Integrating Imperative and Functional Programming&quot;&lt;&#x2F;a&gt; (1986)
wrote about tracking reads, writes and allocation of memory:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;In the language presented in this paper, information about interference and referential
transparency is inferred from three orthogonal properties:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;the ability to allocate and initialize memory locations whose value may be changed,&lt;&#x2F;li&gt;
&lt;li&gt;the ability to read the contents of memory locations whose value may be changed (i.e. to observe side-effects), and&lt;&#x2F;li&gt;
&lt;li&gt;the ability to unite new values to existing memory locations (i.e. to cause side-effects).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;In general it is undecidable whether an expression will
allocate, read or write memory locations whose value may
be changed. Effect checking is &lt;em&gt;conservative&lt;&#x2F;em&gt;, and
classifies an expression as having each of the three
properties unless the opposite can be shown.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;They discuss the role of effect polymorphism in &lt;a href=&quot;https:&#x2F;&#x2F;dl.acm.org&#x2F;doi&#x2F;pdf&#x2F;10.1145&#x2F;73560.73564&quot;&gt;&quot;Polymorphic Effect Systems&quot;&lt;&#x2F;a&gt; (1988)
(updated: thanks Colin Gordon for pointing me to the earlier paper).&lt;&#x2F;p&gt;
&lt;p&gt;Nielson and Nielson give a wonderful, timeless description in &lt;a href=&quot;https:&#x2F;&#x2F;web.cs.ucla.edu&#x2F;~palsberg&#x2F;tba&#x2F;papers&#x2F;nielson-nielson-csd99.pdf&quot;&gt;&quot;Type and Effect Systems&quot;&lt;&#x2F;a&gt;, from 1999.
The wikipedia page &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Effect_system&quot;&gt;&quot;Effect system&quot;&lt;&#x2F;a&gt; is very congruent with that.
This is a good place to remark that in industry it is at present entirely normal that decades pass before ideas
from research get taken up.&lt;&#x2F;p&gt;
&lt;p&gt;Time for a brief example: imagine we have a toy imperative programming language with a built-in &lt;code&gt;print&lt;&#x2F;code&gt;
command. We can define a &lt;code&gt;print&lt;&#x2F;code&gt; effect and tag function types. Thus we gained the ability to
distinguish between functions that print and functions that don&#x27;t print. This would give us ways
to enforce a &lt;em&gt;type discipline&lt;&#x2F;em&gt; where certain operations can take functions that are not permitted
to print anything. We can immediately see that we then also need to think about propagating effect
information (effect-polymorphism).&lt;&#x2F;p&gt;
&lt;p&gt;Our mere decision to be tracking effects in the type system leads to more questions: which effects should
we track? And what should we check? Marino and Millstein write about a type and effect checking
framework &lt;a href=&quot;https:&#x2F;&#x2F;web.cs.ucla.edu&#x2F;~todd&#x2F;research&#x2F;tldi09.pdf&quot;&gt;&quot;A Generic Type-and-Effect System&quot;&lt;&#x2F;a&gt; that
we are pretty free to choose, as long as rules for checking and adjusting satisfy
certain monotonicity properties.&lt;&#x2F;p&gt;
&lt;p&gt;So it is very easy to state that something is (or should be) an effect. Whether that is valuable
has to be demonstrated by the rules that make use of the effect information. The proof of the
pudding is in the eating!&lt;&#x2F;p&gt;
&lt;p&gt;Modern programming languages give programmers various ways to &quot;extend the language&quot;: user-defined data types
and operations (bundled as classes in OOP), only providing built-in operations (primitives) for
IO, memory allocation. A challenge in type and effect systems outside of minimal research languages
is how these facilities for user-defined constructs should be combined with effects. In
particular, &lt;em&gt;abstraction&lt;&#x2F;em&gt; depends on the ability to hide information.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;notions-of-computation&quot;&gt;Notions of Computation&lt;&#x2F;h2&gt;
&lt;p&gt;We now shift our perspective completely and embrace the functional programming view.
Away with side effects - unless we can capture them in a mathematical framework.&lt;&#x2F;p&gt;
&lt;p&gt;Researchers who study programming languages (PL) have a need to describe
PL concepts and semantics formally. Many mathematical and logical
characterizations have entered the discourse on programming, for example
&quot;boolean&quot;, &quot;set&quot;, &quot;map&quot; for data types. The meaning of programs as a whole, and
programming languages as notation for programs has been approached from a
mathematics angle.&lt;&#x2F;p&gt;
&lt;p&gt;A particular mathematical field that stands out in PL semantics is category theory. Don&#x27;t run away yet!
It is a language for making precise statements about structure-preserving
transformations. The goal is to learn about the structures by studying these transformations.&lt;&#x2F;p&gt;
&lt;p&gt;In PL theory, one constantly needs to talk about structures (concepts) that exist across
different PLs, or can be expressed in many different ways. And thus, product types,
sum types (co-product), co- and contravariance and functors found their way into PL discourse.
Not only semantics, but also as actual ways to define data structures (algebraic data types).
The connection to category theory is often lost in the process, but that has not
led to significant problems so far.&lt;&#x2F;p&gt;
&lt;p&gt;The $\lambda$-calculus has been used as a vehicle for PL research.  Its basic unit
computation step (substitution) lends itself so well for compositionality and formal reasoning.
This has given rise to functional programming.&lt;&#x2F;p&gt;
&lt;p&gt;When researchers assign &lt;em&gt;meaning&lt;&#x2F;em&gt; to programs through mathematical structures (denotational semantics), the
idea is that these are widely understood, or understandable. In this vein, a $\lambda$-term would ultimately
correspond to a mathematical function of some kind. But not always a mathematical function from the
domain of argument types to the domain of the result type.&lt;&#x2F;p&gt;
&lt;p&gt;In his 1989 LICS paper &quot;Computational lambda-calculus and monads&quot;, Eugenio Moggi
challenged the idea that semantics of $\lambda$-terms should correspond to
simple mathematical functions. He pointed out the existence of various firmly
established &lt;em&gt;notions of computation&lt;&#x2F;em&gt; which are all better explained by something else,
and this would pave the way to reason about program equivalence logically.&lt;&#x2F;p&gt;
&lt;p&gt;We will not explain monads here, but just the particular &quot;notions of computation&quot; view.
It turns out to not be that difficult. In the context of programming, monads are
about program composition.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;types-and-algebra&quot;&gt;Types and Algebra&lt;&#x2F;h3&gt;
&lt;p&gt;Today (!) all programmers understand the concept of a generic type. For instance,
we can make sense of the phrase &quot;a type $List[T]$ is a list whose elements are of type $T$&quot;.
Let&#x27;s call $List$ a type constructor.&lt;&#x2F;p&gt;
&lt;p&gt;A type constructor with a single argument $F[T]$ could be considered an operation that takes
a type and returns a type. Other operations that constructing types are $\times$ for product
types and $+$ for sum types, and 1 for unit (a type that holds no information), and 0 for
a type that has no members. Types built from $\times$, $+$, 1 and 0 can be called algebraic
types because they look like terms we use in high school algebra.&lt;&#x2F;p&gt;
&lt;p&gt;Now, we need to make a mental step away from types in a given programming language, into a
world where instead of &lt;em&gt;types&lt;&#x2F;em&gt; talking about specific values in a given language,
we have &lt;em&gt;domains of types&lt;&#x2F;em&gt; that talk about all semantics. We continue to call these types,
though, because types can be used in the abstract to describe mathematical structures.
Semantics go beyond values, we also have to give meaning to the operations.&lt;&#x2F;p&gt;
&lt;p&gt;The insight, then, is this: suppose we have a $T$ that represents all semantic values
of our programming language, we can think of a &quot;semantic type constructor&quot; $F$ that transform
it into a mathematical structure that very accurately describes a notion of computation:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;$F[T] = 1 + T$ partial computation: either returns a result $T$ or nothing.&lt;&#x2F;li&gt;
&lt;li&gt;$F[T] = List[T]$ non determinism: returns a whole list (or set) of results.&lt;&#x2F;li&gt;
&lt;li&gt;$F[T] = S \times T$ stateful computation: operations may read and modify a state $S$&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;One can think of others.  When we see this, we can say $F$ captures the
computational effects of the operations given in such a notion of computation.
Where in a Rust or Haskell program, you return &lt;code&gt;Some(x)&lt;&#x2F;code&gt; or &lt;code&gt;None&lt;&#x2F;code&gt;, we can lift this
to whole computational model or partial computations that either return something or
they don&#x27;t. Such programs (functions) can be composed in a way that preserves their
type structure.&lt;&#x2F;p&gt;
&lt;p&gt;The &quot;monad&quot; part comes in when we talk about composing program fragments from building blocks.
As promised, we will not go into the monad laws and join,unit,bind operations here.
It is enough to say: when we focus on the way programs are composed &#x2F; sequences, we end
up with an abstract framework for reasoning about programs with effects.&lt;&#x2F;p&gt;
&lt;p&gt;This turns out to be super-useful for practical programming. This approach lets us
define our own programming language inside a given programming language. And what&#x27;s
more, we can see embedded &quot;languages&quot; (programs composed from commands) in this way
even if the people who built them never heard about monads.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;effects-in-functional-programming&quot;&gt;Effects in Functional Programming&lt;&#x2F;h3&gt;
&lt;p&gt;This is the place to mention Haskell, where the main function of every program
is a computation in the IO monad. Over the years, people have taken up this
approach in many languages. They:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;use type constructors in their favorite language to structure their programs to implement domain-specific languages&lt;&#x2F;li&gt;
&lt;li&gt;started to call the $F$ itself a &quot;computational effect&quot;&lt;&#x2F;li&gt;
&lt;li&gt;write lots of monad tutorials&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;And this has some justification, because it is useful to define data types and operations
that act as domain-specific languages (the &quot;Interpreter&quot; design pattern, anyone?).&lt;&#x2F;p&gt;
&lt;p&gt;What if I told you that &lt;code&gt;async&lt;&#x2F;code&gt; is an effect? As we know, a widespread way to implement
&lt;code&gt;async&lt;&#x2F;code&gt; functions is to transform them into normal functions that return a &lt;code&gt;Future&amp;lt;T&amp;gt;&lt;&#x2F;code&gt;.
&lt;code&gt;Future&lt;&#x2F;code&gt; is a unary type constructor and we can come up with rules of composing such functions.&lt;&#x2F;p&gt;
&lt;p&gt;I think it is fair to say that the vast majority of programmers will not bother to ask whether monad axioms hold,
presumably because the vast majority of programmers will never have the time and
energy to learn category theory. So using &quot;effect&quot; as a hand-wavy replacement for monad
can certainly be seen in the wild, and we can see the use of it.&lt;&#x2F;p&gt;
&lt;p&gt;And what if we want a partial computation returns an error? &lt;code&gt;Result&amp;lt;T, E&amp;gt; = T + E&lt;&#x2F;code&gt; gives
us the same ways to compose, even if it is not unary type constructor. This is pretty
useful, and we seem not really bothered by the fact that &lt;code&gt;Result&lt;&#x2F;code&gt; takes two type
arguments instead of one. This is because in practice, programmers use monads as an
&quot;abstraction pattern&quot;, &lt;strong&gt;mutatis mutandis&lt;&#x2F;strong&gt;, and the transformations that would
be enabled by adherence to monad laws are less of a concern.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;control-effects-and-effect-handlers&quot;&gt;Control Effects and Effect handlers&lt;&#x2F;h2&gt;
&lt;p&gt;We can see that manipulating memory may be a good candidate for effect tracking, but the print
example shows that we can also single out specific operations and consider these as effects.&lt;&#x2F;p&gt;
&lt;p&gt;What if we committed to a world of user-definable effects? This is where &quot;algebraic effects&quot; and
control flow come in. Control flow is one of the many area where programming language research
is looking for something better than mere function calls and for-loops. Consider the
ability to suspend computation or return through multiple paths and multiple approaches to
package that like exceptions, coroutines, iterators, generators and async functions.&lt;&#x2F;p&gt;
&lt;p&gt;The &quot;algebraic&quot; comes in when we consider a user-definable operation and effect, and that
operation takes parameters. I will not try to get into definitions but just point
to the excellent &lt;a href=&quot;https:&#x2F;&#x2F;effekt-lang.org&#x2F;#intro-handlers&quot;&gt;&quot;Effekt&quot; research programming language&lt;&#x2F;a&gt;
where everything is explained pretty well.&lt;&#x2F;p&gt;
&lt;p&gt;In particular, a type and effect system is used to check whether the (user-defined) effects
are handled. Here, the multiple meanings hit us with full force, the effects - annotations on types - that
are being tracked are effects, as in user-defined operations that can be interleave with
normal control flow.&lt;&#x2F;p&gt;
&lt;p&gt;(updated:) In a language that supports definition of effect handlers one sees the type and effect
checking used for a user-definable composition mechanism. In Jonathan Brachthäuser&#x27;s words:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;monadic effects start with the semantics (like &lt;code&gt;List[T]&lt;&#x2F;code&gt;) and then see which operations
can be supported, while algebraic effects start with the operations (the signature)
and then see which domains can support (implement) them.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h1 id=&quot;the-end&quot;&gt;The End&lt;&#x2F;h1&gt;
&lt;p&gt;I hope this post helped establish a clearer idea how the venerable idea of type and effect
systems, the venerable idea of notions-of-computation and how they get combined in
the &lt;strong&gt;très en vogue&lt;&#x2F;strong&gt; algebraic effects trend in research.&lt;&#x2F;p&gt;
&lt;p&gt;There are multiple deep connections between category and programming language technology.
We only scratched the surface here.&lt;&#x2F;p&gt;
&lt;p&gt;Monads are a remarkable method to structure programming language semantics. That seems to indicate that a science
of programming languages could benefit from using the meta language of categories, types and logic.&lt;&#x2F;p&gt;
&lt;p&gt;For mere practical uses of a type and effect system, that may not be so relevant. And
even in practical uses, we may be fine using a &quot;monad abstraction pattern&quot; for
structure embedded, domain-specific programming languages without really being
constrained by the &quot;mathematics&quot; that led to the concept.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Memory Safety - the missing definition</title>
        <published>2025-09-04T00:00:00+00:00</published>
        <updated>2025-09-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://burakemir.ch/post/memory-safety-the-missing-def/"/>
        <id>https://burakemir.ch/post/memory-safety-the-missing-def/</id>
        
        <content type="html" xml:base="https://burakemir.ch/post/memory-safety-the-missing-def/">&lt;p&gt;There is still no standard, precise definition of memory safety. Here is a modest proposal.&lt;&#x2F;p&gt;
&lt;!-- 
Yet, we need one.

A definition that is both broadly applicable and precise is also not easy to come by. 
In the following, I argue for a particular position. Depending on your background, you may find it 
natural, straightforward or even trivial. However, I fully expect there to be competent people who
find themselves in disagreement.

What I propose is simple: I say, let&#x27;s anchor memory safety in the realm of **language safety**.
This amounts to separating it from **memory safety of execution environments**. 

Coming to agreement on definitions, and framing is a communication challenge on more than one level.
The 21 authors who wrote [&quot;It is time to standardize memory safety&quot;](https:&#x2F;&#x2F;dl.acm.org&#x2F;doi&#x2F;10.1145&#x2F;3708553) paper 
mention &quot;memory-safe and type-safe languages&quot; as one among many things. I appreciate the quest for
vendor-neutral and technology-neutral terminology and &quot;intellectual framework&quot;, and I realize that
there are many programming languages out there. Yet, I do not think it is helpful to ignore the
central position programming language design.

--&gt; 
&lt;blockquote&gt;
&lt;p&gt;Fact. A programming language (PL) consists of a &lt;strong&gt;specification&lt;&#x2F;strong&gt; and &lt;strong&gt;implementation&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The specification lays out precisely what the set of accepted programs is and how the code should behave
when the program is executed. An implementation must &lt;em&gt;conform&lt;&#x2F;em&gt; to the specification and is what enables
programmers to actually use the PL to translate programs to executable code and execute them.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Fact. Programs are executed in an &lt;strong&gt;execution environment&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;An execution environment is not necessarily part of an implementation, but it can be (interpreter).
CPU, operating system and system resources are all part of the execution environment.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Fact. A specification can, implicitly or explicitly, leave the possibility of &lt;strong&gt;execution errors&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Definition. There are two classes of execution errors:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;trapped&lt;&#x2F;strong&gt; errors: these are reliably detected and dealt with by the execution environment&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;untrapped&lt;&#x2F;strong&gt; errors: these are not detected, and execution goes on. The specification cannot prescribe what
behavior take place.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;A trapped error may lead to invocation of an error handler or to execution being aborted (&quot;fail-stop&quot;).
In contrast, untrapped errors include highly problematic situations like undetected out-of-bounds accesses, use-after-free, integer overflows. They can lead to silent data corruption,
hard-to-debug crashes, and also to security vulnerabilities that can be exploited by malicious actors.&lt;&#x2F;p&gt;
&lt;!--
A very simple model by security researcher Thomas Dullien is the _intended finite state machine_[^1]. The program code reflects the programmer&#x27;s intention of how we want a program to behave, which we can think of as a big finite state machine. However, it ultimately gets executed on a real machine (CPU) that may offer many more states. Some of these states may be outside the programmer&#x27;s intention, but enable attackers to breach security properties while continuing execution of the program.

The difference between intention and actual possible behaviors applies in particular to provisioning and accessing memory. In PL with automatic memory management, the execution environment takes care of interaction with the operating system to obtain or release memory. This eliminates many execution errors that stem from programmer mistakes such as _dangling reference _bugs.

Without automatic memory management, it is the programmer&#x27;s job to ensure that all memory accesses are valid. When an invalid access happens, we cannot know what state the execution environment will be in and therefore cannot predict what is going to happen. Bug classes include _out-of-bounds access, use-after-free, _often classified as temporal or spatial memory safety_._

Untrapped errors from invalid memory access are particularly harmful when the system does not manage memory. Such an untrapped error gives the attacker pathways to a large state space of actual behaviors. In contrast, untrapped errors in languages with automatic memory management, while problematic, are less likely to cause harm as the additional invalid states are less exploitable.

**Undefined behavior.** To make things complicated, compiler writers &quot;weaponized&quot; the specification: when source
code does not satisfy assumptions, leading to statically detected case of untrapped errors, this is taken as
a license for compiler to generate code with *arbitrary* behavior. While this can be justified logically &quot;from a contradiction, anything follows&quot;, it is hard to see this as rational: users of compilers would (and should) rather exclude the possibility of untrapped errors, instead of having a program whose output cannot be predicted.

We now have all ingredients in place to appreciate a ~~standard~~[^2], technical definition of safety. Other definitions are possible, but this captures an important part of language safety.  \

--&gt;
&lt;blockquote&gt;
&lt;p&gt;Definition: Execution Safety&lt;&#x2F;p&gt;
&lt;p&gt;A program is &lt;strong&gt;execution safe&lt;&#x2F;strong&gt; if its execution never leads to untrapped errors.&lt;&#x2F;p&gt;
&lt;p&gt;A language L is &lt;strong&gt;execution safe&lt;&#x2F;strong&gt; if all L-programs are execution-safe.&lt;&#x2F;p&gt;
&lt;p&gt;An execution environment is &lt;strong&gt;execution safe for a language L&lt;&#x2F;strong&gt; if execution of L-programs can never lead to untrapped L-errors.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Execution-safety does &lt;strong&gt;not&lt;&#x2F;strong&gt; guarantee absence of crashes, absence of memory leaks, or possibility to perform modular reasoning on programs. Nevertheless, it is a very strong guarantee and many PLs in widespread use do not have this property. Execution environments can deal with the consequences of untrapped errors, which may limit the harm even if the language used to write these programs may not be execution-safe.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Definition: Memory Safety&lt;&#x2F;p&gt;
&lt;p&gt;A program is &lt;strong&gt;memory safe&lt;&#x2F;strong&gt; if no memory access ever leads to untrapped errors.&lt;&#x2F;p&gt;
&lt;p&gt;A language L is &lt;strong&gt;memory safe&lt;&#x2F;strong&gt; if all L programs are memory-safe.&lt;&#x2F;p&gt;
&lt;p&gt;An execution environment is &lt;strong&gt;memory safe for a language L&lt;&#x2F;strong&gt; if execution of L-programs can never lead to
untrapped L-errors due to an operation involving memory access.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Brief discussion&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;These definitions are directly derived from Luca Cardelli&#x27;s &quot;Type Systems&quot; article (2004) from the
CRC Handbook of Computer Science and Engineering, 2nd Edition, Ch. 97. You can find it.&lt;&#x2F;p&gt;
&lt;p&gt;Safety is commonly defined as &quot;absence of unacceptable loss&quot;. Turning this into an effective
definition in the context of programming requires to clarify what unacceptable loss is. Our
definitions above are focused on the mechanics of execution: we do not talk about logic errors,
stealing your private key from the .ssh directory or causing crashes. So our definition of memory safety
is a &quot;technical definition&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;Nevertheless, it seems useful: it applies to a range of programming languages, and thus over
a range of possible language designs.&lt;&#x2F;p&gt;
&lt;p&gt;For safety of execution environment with respoect to a language, it is subtle and important that
the definition of error is tied to language spec L. When an implementation translates to a target language
of CPU instructions, an operation like &quot;dereferencing a dangling pointer&quot; may turn into
&quot;loading memory from an address&quot; which may not be erroneous from the target language point of view.
What makes the operation in the execution environment erroneous is the intent. This intent,
as far as safety guarantees go, has to be grounded in the language specification.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Rust and Carbon, why not both</title>
        <published>2025-08-27T00:00:00+00:00</published>
        <updated>2025-08-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://burakemir.ch/post/rust-carbon-why-not-both/"/>
        <id>https://burakemir.ch/post/rust-carbon-why-not-both/</id>
        
        <content type="html" xml:base="https://burakemir.ch/post/rust-carbon-why-not-both/">&lt;p&gt;Today&#x27;s post is a little different. Instead of delving into discussiong of formal type systems, I&#x27;d like to step back and talk generally about some aspects of linear type systems
as they show up in real life. That means: programming languages and the memory safety discussion today, C++ and Rust. Disclaimer: while the content of this post is very much
related to memory safety which is something I work on at Google, this is my personal blog and everything here is my personal opinion.&lt;&#x2F;p&gt;
&lt;p&gt;In programming, managing memory and resources is one of the most critical and error-prone tasks. Getting it wrong can lead to nasty bugs, from crashes to security vulnerabilities. Two languages that take this challenge seriously, but with vastly different philosophies, are C++ and Rust.&lt;&#x2F;p&gt;
&lt;p&gt;At the heart of this difference lies how their type systems handle the concepts of &lt;strong&gt;copying&lt;&#x2F;strong&gt; and &lt;strong&gt;moving&lt;&#x2F;strong&gt; data. While both languages have syntax for these operations, Rust&#x27;s type system acts as a strict guardian, preventing common errors at compile time, whereas C++ offers more flexibility at the cost of placing the burden of safety squarely on the developer.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-c-way-a-set-of-powerful-conventions&quot;&gt;The C++ Way: A Set of Powerful Conventions&lt;&#x2F;h3&gt;
&lt;p&gt;In C++, the ability for an object to be copied or moved is defined by a set of special member functions. If you&#x27;ve written any C++, you&#x27;ve likely encountered the &lt;strong&gt;&quot;Rule of Five&quot;&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Copy Constructor:&lt;&#x2F;strong&gt; &lt;code&gt;MyType(const MyType&amp;amp; other);&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Copy Assignment Operator:&lt;&#x2F;strong&gt; &lt;code&gt;MyType&amp;amp; operator=(const MyType&amp;amp; other);&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Move Constructor:&lt;&#x2F;strong&gt; &lt;code&gt;MyType(MyType&amp;amp;&amp;amp; other);&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Move Assignment Operator:&lt;&#x2F;strong&gt; &lt;code&gt;MyType&amp;amp; operator=(MyType&amp;amp;&amp;amp; other);&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Destructor:&lt;&#x2F;strong&gt; &lt;code&gt;~MyType();&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;When you create a type that manages a resource, like a memory buffer, you implement these functions to define what it means to copy or move it. A copy usually involves a &quot;deep copy&quot;—allocating new memory and copying the data over. A move is an optimization that &quot;steals&quot; the internal resource from a temporary object, avoiding a costly allocation.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s look at a classic example: a simple string-like class.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;C++&quot; style=&quot;background-color:#383838;color:#e6e1dc;&quot; class=&quot;language-C++ &quot;&gt;&lt;code class=&quot;language-C++&quot; data-lang=&quot;C++&quot;&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;#include &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&amp;lt;cstring&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;#include &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&amp;lt;iostream&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;class &lt;&#x2F;span&gt;&lt;span style=&quot;text-decoration:underline;color:#ffc66d;&quot;&gt;NaiveString &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;public&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;NaiveString&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;char&lt;&#x2F;span&gt;&lt;span&gt;\&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#fd971f;&quot;&gt;s&lt;&#x2F;span&gt;&lt;span&gt;) {
&lt;&#x2F;span&gt;&lt;span&gt;        std::cout &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;lt;&amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;Allocating memory for &amp;#39;&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; s &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;lt;&amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#519f50;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;        size &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;std::&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;strlen&lt;&#x2F;span&gt;&lt;span&gt;(s) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;        data &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= new &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;char&lt;&#x2F;span&gt;&lt;span&gt;[size];
&lt;&#x2F;span&gt;&lt;span&gt;        std::&lt;&#x2F;span&gt;&lt;span style=&quot;color:#da4939;&quot;&gt;memcpy&lt;&#x2F;span&gt;&lt;span&gt;(data, s, size);
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;&#x2F;&#x2F; Move constructor: &amp;quot;steals&amp;quot; the pointer
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;NaiveString&lt;&#x2F;span&gt;&lt;span&gt;(NaiveString&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;amp;&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#fd971f;&quot;&gt;other&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;noexcept
&lt;&#x2F;span&gt;&lt;span&gt;        : &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d0d0ff;&quot;&gt;data&lt;&#x2F;span&gt;&lt;span&gt;(other.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d0d0ff;&quot;&gt;data&lt;&#x2F;span&gt;&lt;span&gt;), &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d0d0ff;&quot;&gt;size&lt;&#x2F;span&gt;&lt;span&gt;(other.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d0d0ff;&quot;&gt;size&lt;&#x2F;span&gt;&lt;span&gt;) {
&lt;&#x2F;span&gt;&lt;span&gt;        std::cout &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;lt;&amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;Moving from &amp;#39;&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;lt;&amp;lt; &lt;&#x2F;span&gt;&lt;span&gt;(other.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d0d0ff;&quot;&gt;data &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt; other.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d0d0ff;&quot;&gt;data &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;lt;&amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#519f50;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;&#x2F;&#x2F; Invalidate the source object!
&lt;&#x2F;span&gt;&lt;span&gt;        other.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d0d0ff;&quot;&gt;data &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6e9cbe;&quot;&gt;nullptr&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;        other.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d0d0ff;&quot;&gt;size &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;~NaiveString&lt;&#x2F;span&gt;&lt;span&gt;() {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span&gt;(data) {
&lt;&#x2F;span&gt;&lt;span&gt;            std::cout &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;lt;&amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;Freeing memory for &amp;#39;&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; data &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;lt;&amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#519f50;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;        } &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;else &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;            std::cout &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;lt;&amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;Destructing a moved-from object&lt;&#x2F;span&gt;&lt;span style=&quot;color:#519f50;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;delete[]&lt;&#x2F;span&gt;&lt;span&gt; data;
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;char&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; data;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;size_t&lt;&#x2F;span&gt;&lt;span&gt; size;
&lt;&#x2F;span&gt;&lt;span&gt;};
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;int &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;main&lt;&#x2F;span&gt;&lt;span&gt;() {
&lt;&#x2F;span&gt;&lt;span&gt;    NaiveString s1(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;hello&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;    std::cout &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;lt;&amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;s1.data = &amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;lt;&amp;lt; &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;void&lt;&#x2F;span&gt;&lt;span&gt;\&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;)s1.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d0d0ff;&quot;&gt;data &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;lt;&amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#519f50;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;&#x2F;&#x2F; Move s1 into s2
&lt;&#x2F;span&gt;&lt;span&gt;    NaiveString s2 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;std::move(s1);
&lt;&#x2F;span&gt;&lt;span&gt;    std::cout &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;lt;&amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;s2.data = &amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;lt;&amp;lt; &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;void&lt;&#x2F;span&gt;&lt;span&gt;\&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;)s2.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d0d0ff;&quot;&gt;data &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;lt;&amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#519f50;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;&#x2F;&#x2F; What about s1 now?
&lt;&#x2F;span&gt;&lt;span&gt;    std::cout &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;lt;&amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;s1.data after move = &amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;lt;&amp;lt; &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;void&lt;&#x2F;span&gt;&lt;span&gt;\&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;)s1.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d0d0ff;&quot;&gt;data &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;lt;&amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#519f50;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;&#x2F;&#x2F; This is the danger zone! C++ lets you do this.
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;&#x2F;&#x2F; Accessing s1.data here is undefined behavior.
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;&#x2F;&#x2F; if (s1.data) {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;&#x2F;&#x2F;     std::cout &amp;lt;&amp;lt; &amp;quot;s1 still contains: &amp;quot; &amp;lt;&amp;lt; s1.data &amp;lt;&amp;lt; &amp;quot;\n&amp;quot;; &#x2F;&#x2F; CRASH!
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;&#x2F;&#x2F; }
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The problem here isn&#x27;t the move itself; it&#x27;s what happens &lt;em&gt;after&lt;&#x2F;em&gt;. The C++ type system doesn&#x27;t stop you from trying to use s1 after its resources have been moved to s2. The s1 object is left in a &quot;valid but unspecified state.&quot; Accessing it is a landmine waiting to be stepped on. &lt;strong&gt;The compiler trusts you not to mess up&lt;&#x2F;strong&gt;, but offers no guarantee.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-rust-way-a-contract-with-the-compiler&quot;&gt;The Rust Way: A Contract with the Compiler&lt;&#x2F;h3&gt;
&lt;p&gt;Rust builds memory safety directly into its type system through three core principles:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Each value has a single &lt;strong&gt;owner&lt;&#x2F;strong&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;There can only be &lt;strong&gt;one owner at a time&lt;&#x2F;strong&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;When the owner goes out of scope, the value is &lt;strong&gt;dropped&lt;&#x2F;strong&gt; (i.e., its resources are freed).&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;In Rust, &lt;strong&gt;moving is the default behavior&lt;&#x2F;strong&gt; for any type that manages resources. When you assign a variable to another, ownership is transferred.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;Rust&quot; style=&quot;background-color:#383838;color:#e6e1dc;&quot; class=&quot;language-Rust &quot;&gt;&lt;code class=&quot;language-Rust&quot; data-lang=&quot;Rust&quot;&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;main&lt;&#x2F;span&gt;&lt;span&gt;() {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;&#x2F;&#x2F; String owns heap-allocated memory
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; s1 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;String&lt;&#x2F;span&gt;&lt;span&gt;::from(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;hello&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;&#x2F;&#x2F; Ownership of the data is MOVED from s1 to s2.
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;&#x2F;&#x2F; s1 is now considered uninitialized.
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; s2 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; s1;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;&#x2F;&#x2F; This line will not compile! 
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;&#x2F;&#x2F; The compiler prevents a &amp;quot;use after move&amp;quot; error.
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;&#x2F;&#x2F; println!(&amp;quot;The value of s1 is: {}&amp;quot;, s1); 
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;&#x2F;&#x2F;                                      ^^ value borrowed here after move
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    println!(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;The value of s2 is: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6d9cbe;&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, s2);
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is the crucial difference. The Rust compiler &lt;em&gt;tracks ownership&lt;&#x2F;em&gt;. It knows that s1 is no longer valid after the move and turns a potential runtime bug into a &lt;strong&gt;compile-time error&lt;&#x2F;strong&gt;. It&#x27;s not a convention; it&#x27;s a hard-and-fast rule enforced by the type system.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;so-how-do-you-copy-in-rust&quot;&gt;So, How Do You Copy in Rust?&lt;&#x2F;h4&gt;
&lt;p&gt;What if you have data that is simple, lives entirely on the stack (like an integer), and is cheap to copy? For this, Rust has the Copy trait.&lt;&#x2F;p&gt;
&lt;p&gt;A type is Copy if making a bit-for-bit copy of it is a complete and valid clone. Think of types like i32, f64, bool, or a struct containing only other Copy types.&lt;&#x2F;p&gt;
&lt;p&gt;When you assign a Copy type, the original variable remains valid.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;Rust&quot; style=&quot;background-color:#383838;color:#e6e1dc;&quot; class=&quot;language-Rust &quot;&gt;&lt;code class=&quot;language-Rust&quot; data-lang=&quot;Rust&quot;&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;main&lt;&#x2F;span&gt;&lt;span&gt;() {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;&#x2F;&#x2F; i32 implements the Copy trait
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; x &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;&#x2F;&#x2F; A copy is made. Both x and y are valid.
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; y &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; x;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    println!(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;x = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6d9cbe;&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;, y = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6d9cbe;&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#c1be91;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, x, y); &lt;&#x2F;span&gt;&lt;span style=&quot;color:#95815e;&quot;&gt;&#x2F;&#x2F; This works perfectly!
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The compiler enforces a critical rule: &lt;strong&gt;you cannot implement Copy for a type that manages a resource&lt;&#x2F;strong&gt;. For example, String cannot be Copy because it owns a pointer to heap memory. If you could copy a String, you&#x27;d have two variables pointing to the same memory, leading to a &quot;double free&quot; error when both go out of scope. The compiler forbids this, neatly closing another door to memory corruption.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-philosophical-divide-monocle-face&quot;&gt;The Philosophical Divide 🧐&lt;&#x2F;h3&gt;
&lt;p&gt;The difference boils down to two philosophies:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;C++&lt;&#x2F;th&gt;&lt;th&gt;Rust&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Trusts the Developer:&lt;&#x2F;strong&gt; Provides powerful tools (move semantics) and trusts the programmer to use them correctly. Safety is a matter of discipline and convention (e.g., not using an object after moving from it).&lt;&#x2F;td&gt;&lt;td&gt;&lt;strong&gt;Verifies with the Compiler:&lt;&#x2F;strong&gt; Bakes ownership and moving directly into the type system. The compiler &lt;em&gt;guarantees&lt;&#x2F;em&gt; at compile time that you cannot use a moved value or accidentally create multiple owners of the same resource.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Opt-out Safety:&lt;&#x2F;strong&gt; By default, types can be copied or moved if the syntax is valid. The developer must explicitly delete functions (e.g., = delete;) to make a type non-copyable or non-movable.&lt;&#x2F;td&gt;&lt;td&gt;&lt;strong&gt;Opt-in Simplicity:&lt;&#x2F;strong&gt; Moving is the default for complex types. Simple, bit-wise copying is an opt-in behavior via the Copy trait, which the compiler validates to ensure it&#x27;s used safely.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Runtime Errors:&lt;&#x2F;strong&gt; Mistakes like use-after-move or double-frees manifest as crashes or undefined behavior at runtime, which can be difficult to debug.&lt;&#x2F;td&gt;&lt;td&gt;&lt;strong&gt;Compile-time Errors:&lt;&#x2F;strong&gt; The same mistakes are caught by the compiler before the program can even run, providing clear, actionable feedback.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h3 id=&quot;under-the-hood-a-glimpse-into-rust-s-type-theory&quot;&gt;Under the Hood: A Glimpse into Rust&#x27;s Type Theory&lt;&#x2F;h3&gt;
&lt;p&gt;So how does the Rust compiler pull this off? It&#x27;s not magic; it&#x27;s the practical application of ideas from programming language research, specifically a &lt;strong&gt;substructural type system&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;At its core, this system treats variables that own resources as, well, &lt;em&gt;resources&lt;&#x2F;em&gt;. A resource can be used, and once it&#x27;s fully given away (or &quot;consumed&quot;), it&#x27;s gone. This is where the idea of a &lt;strong&gt;linear type system&lt;&#x2F;strong&gt; comes in—a specific flavor of substructural system where a resource must be consumed &lt;em&gt;exactly once&lt;&#x2F;em&gt;. When you write let s2 = s1;, the String owned by s1 is consumed by the move. The type system then invalidates s1 to prevent it from being used a second time, thus upholding the &quot;use once&quot; rule.&lt;&#x2F;p&gt;
&lt;p&gt;To enforce this, the compiler uses &lt;strong&gt;flow-sensitive typing&lt;&#x2F;strong&gt;. This means it doesn&#x27;t just know a variable&#x27;s type; it tracks its &lt;em&gt;state&lt;&#x2F;em&gt; as it flows through your code. It knows that s1 is valid &lt;em&gt;before&lt;&#x2F;em&gt; the move, but invalid &lt;em&gt;after&lt;&#x2F;em&gt; it. Finally, this system extends to references (&amp;amp; and &amp;amp;mut), which are more than just pointers. They are special types that come with compiler-enforced &lt;strong&gt;invariants&lt;&#x2F;strong&gt;, or rules that must always hold true. The most famous of these is that you can have either many immutable references (readers) or exactly one mutable reference (a writer), but never both at the same time.&lt;&#x2F;p&gt;
&lt;p&gt;Together, these ingredients—a type system that understands consumption, tracks state through program flow, and enforces strict rules on references—form the foundation of Rust&#x27;s &quot;borrow checker&quot; and its celebrated compile-time safety guarantees.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;bridging-the-divide-interoperability-with-c&quot;&gt;Bridging the Divide: Interoperability with C++&lt;&#x2F;h3&gt;
&lt;p&gt;This brings us to a crucial question: What happens when we interface with existing C++ code? Rust&#x27;s strict safety discipline, while a huge benefit, can prevent the direct porting of some perfectly valid C++ APIs. In C++, it&#x27;s common to write APIs that are safe due to specific, documented invariants that a compiler can&#x27;t necessarily understand.&lt;&#x2F;p&gt;
&lt;p&gt;A fantastic example is &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;abseil&#x2F;abseil-cpp&#x2F;blob&#x2F;master&#x2F;absl&#x2F;container&#x2F;node_hash_map.h&quot;&gt;&lt;code&gt;absl::node_hash_map&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;. This data structure guarantees &lt;strong&gt;pointer stability&lt;&#x2F;strong&gt;: you can look up an element and hold onto a pointer to it, and that pointer will remain valid even if you later mutate the map by adding new elements. This pattern is fundamentally incompatible with Rust&#x27;s standard aliasing rules. An insert operation on a Rust HashMap requires a unique mutable reference (&amp;amp;mut self), which invalidates all other references to its elements. The Rust compiler has no way to know that Abseil&#x27;s implementation is special; it sees a violation of its core &quot;aliasing XOR mutability&quot; rule and forbids the code.&lt;&#x2F;p&gt;
&lt;p&gt;So, what would it take to teach Rust&#x27;s type system about the unique guarantees of &lt;code&gt;absl::node_hash_map&lt;&#x2F;code&gt;? You don&#x27;t. Instead, Rust provides a controlled escape hatch for these situations: the &lt;strong&gt;unsafe&lt;&#x2F;strong&gt; keyword. To wrap such a library, you would write a safe public API that internally uses unsafe blocks to call the C++ code. The Rust wrapper&#x27;s creator takes on the responsibility of manually upholding the safety invariants that the borrow checker can no longer verify.&lt;&#x2F;p&gt;
&lt;p&gt;This is often accomplished using &lt;strong&gt;interior mutability&lt;&#x2F;strong&gt; primitives like UnsafeCell&amp;lt;T&amp;gt;. This type tells the compiler, &quot;Don&#x27;t worry about the borrowing rules for this data; I will manage them myself.&quot; By wrapping the C++ map pointer in a type that uses UnsafeCell, you can expose methods like insert that take a shared reference (&amp;amp;self) while still performing mutation internally. The key is that this unsafe logic is contained within a small, well-audited boundary, allowing the rest of the Rust application to interact with it in a completely safe and idiomatic way.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-path-forward-beyond-unsafe&quot;&gt;The Path Forward: Beyond &quot;Unsafe&quot;&lt;&#x2F;h3&gt;
&lt;p&gt;By using unsafe, we&#x27;ve told the Rust compiler to look away, allowing us to manually uphold the invariants of our C++ library. While this violates Rust&#x27;s standard rules, it&#x27;s a pragmatic necessity for interoperability. A lot of code will be written this way, and despite this compromise, the resulting programs are still a massive improvement. The vast majority of the application benefits from Rust&#x27;s static checking, containing the potential for memory bugs to small, auditable sections—a far safer world than a pure C++ program.&lt;&#x2F;p&gt;
&lt;p&gt;The problem here isn&#x27;t a flaw in Rust. Its powerful invariants were simply not designed for the C++ ecosystem, where code may arbitrarily hold on to pointers. The manual reasoning required for unsafe blocks is fragile; a future change elsewhere could unknowingly invalidate the assumptions and reintroduce a bug. This highlights a gap in the programming language landscape: there is no smooth gradient from the &quot;no guarantees&quot; world of C++ to the &quot;full, statically checked&quot; world of safe Rust.&lt;&#x2F;p&gt;
&lt;p&gt;This is the gap that experimental projects like &lt;strong&gt;Carbon&lt;&#x2F;strong&gt; aim to fill. Carbon&#x27;s goal is to devise a language that enables a gradual migration from C++, combining it with the need for full, statically checked memory safety. To succeed, its type system must find a way to provide guarantees around mutable access even in the presence of aliasing. If Carbon can express a concept like pointer stability directly in its types, it would require a different set of global guarantees and aliasing rules than Rust&#x27;s. The ultimate challenge lies in safely composing programs written in a &quot;legacy C++&quot; style with new code written in a stricter, safer mode, creating a true bridge to a memory-safe future.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;conclusion-two-paths-to-a-safer-future&quot;&gt;Conclusion: Two Paths to a Safer Future&lt;&#x2F;h3&gt;
&lt;p&gt;Throughout this journey, we&#x27;ve seen how a language&#x27;s type system is the bedrock of memory safety. C++ provides the tools for manual resource management, but places the burden of correctness on the developer. Rust, with its revolutionary ownership, move semantics, and &lt;code&gt;Copy&lt;&#x2F;code&gt; trait, shifts that burden to the compiler, turning potential runtime disasters into compile-time errors.&lt;&#x2F;p&gt;
&lt;p&gt;While Rust&#x27;s model is a monumental step forward, its strictness creates a philosophical divide at the boundary with C++. The &lt;code&gt;unsafe&lt;&#x2F;code&gt; keyword offers a pragmatic bridge, but it underscores a fundamental challenge: fitting flexible C++ idioms into Rust&#x27;s rigid world of invariants.&lt;&#x2F;p&gt;
&lt;p&gt;This is precisely why &lt;strong&gt;Rust and Carbon should not be seen as competitors&lt;&#x2F;strong&gt;, but as different tools for different, equally important jobs.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Rust&lt;&#x2F;strong&gt; 🚀 excels in new, &quot;greenfield&quot; projects where safety is paramount from day one. It&#x27;s the ideal choice for building new systems or for creating self-contained, high-performance components that integrate with a larger ecosystem through clear API boundaries compatible with its aliasing rules.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Carbon&lt;&#x2F;strong&gt; 🏗️ is designed to tackle a different beast entirely: the gradual and interoperable migration of massive, existing C++ codebases. Its goal is to provide an evolutionary path, allowing teams to incrementally bring parts of their code into a world of statically-checked safety without a complete, high-risk rewrite.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Ultimately, both languages are vital to the future of systems programming. They represent a shared mission to eliminate memory bugs, but they approach it from different starting points—one building a new, safe foundation, and the other building a bridge from the world we already have.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>CEK and Control Operators</title>
        <published>2024-01-05T00:00:00+00:00</published>
        <updated>2024-01-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://burakemir.ch/post/cek-and-control/"/>
        <id>https://burakemir.ch/post/cek-and-control/</id>
        
        <content type="html" xml:base="https://burakemir.ch/post/cek-and-control/">&lt;p&gt;Today is a good day to recall some foundations of formal abstract machines, continuations, control and data stacks.
And a good place to place to start is the CEK machine, described in Felleisen and Friedman&#x27;s 1986 paper
&quot;&lt;a href=&quot;https:&#x2F;&#x2F;legacy.cs.indiana.edu&#x2F;ftp&#x2F;techreports&#x2F;TR197.pdf&quot;&gt;Control operators, the SECD machine and the $\lambda$ calculus.&lt;&#x2F;a&gt;&quot;  and
Felleisen&#x27;s 1987 &lt;a href=&quot;https:&#x2F;&#x2F;www2.ccs.neu.edu&#x2F;racket&#x2F;pubs&#x2F;dissertation-felleisen.pdf&quot;&gt;dissertation&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;An &lt;em&gt;abstract machine&lt;&#x2F;em&gt; is a device and method for formally specifying program semantics: we define
the meaning of a program by describing a state machine that obtains a result. In other words,
we are defining the meaning by providing a particular kind of interpreter. This should be fun!&lt;&#x2F;p&gt;
&lt;p&gt;An abstract machine does not have instructions but operates on &lt;em&gt;terms&lt;&#x2F;em&gt;. This makes
abstract machines different from processors or virtual machines. Terms (abstract syntax) are a high-level, formal
representation of a program that fully captures its essence.&lt;&#x2F;p&gt;
&lt;p&gt;We will work with a simple $\lambda$-calculus. Formally, $\lambda$-calculus is a rewriting
system and the basic question (word problem) consists of deciding whether two terms are equivalent. We want
to come up with a mechanical way of simplifying the terms by applying $\beta$ reduction:&lt;&#x2F;p&gt;
&lt;p&gt;$$ (\lambda x. M) N \longrightarrow_\beta M [x := N] \ $$&lt;&#x2F;p&gt;
&lt;p&gt;The $\lambda$ calculus is minimalistic but it can nevertheless be used to express all concepts in programming languages.
Felleisen&#x27;s work from that time deals with storage and assignment, too (the CESK machine), but we will not do that here.
In order to simplify the exposition, we also defer the discussion of control operators $\mathcal{C}$ or $\mathcal{A}$&lt;&#x2F;p&gt;
&lt;h2 id=&quot;call-by-value-evaluation&quot;&gt;Call-by-value evaluation&lt;&#x2F;h2&gt;
&lt;p&gt;Let&#x27;s start with syntax:&lt;&#x2F;p&gt;
&lt;p&gt;$$ M, N ::= x\ |\ \lambda x. M\ |\ M N\ $$&lt;&#x2F;p&gt;
&lt;!-- next: Bierman a computational interpretation of lambda-mu calculus --&gt;
&lt;p&gt;A term is either a variable, a $\lambda$-abstraction or an application. In an application $M N$, let&#x27;s call $M$ the
&quot;function&quot; term and $N$ the &quot;argument&quot; term. We ought to discuss free and bound variables, the pitfalls and
conventions to avoid them, but we omit this.&lt;&#x2F;p&gt;
&lt;p&gt;As mentioned, a computation step is a $\beta$ reduction. Specifically, reduction happens in application terms
where the function is a $\lambda$ abstraction.
So far this leaves unspecified in which order we should reduce application terms and also what
kind of values can be bound to $x$.  We want to fix that and clarify that we want a variable to be bound
to &lt;em&gt;values&lt;&#x2F;em&gt; $V$, by which we mean $\lambda$-expression that cannot be reduced further,
and that we do not reduce &lt;em&gt;under&lt;&#x2F;em&gt; a $\lambda$-abstraction.&lt;&#x2F;p&gt;
&lt;p&gt;A way to make this precise is to define &lt;em&gt;evaluation contexts&lt;&#x2F;em&gt;. We describe precisely where an evaluation step
can take place and write that particular location as $[~ ]$.&lt;&#x2F;p&gt;
&lt;p&gt;$$ {\color{lightgreen}C[~ ]}\ ::= [~ ]\ |\ {\color{lightgreen}C[~ ]}\ N\ |\ V\ {\color{\lightgreen}C[~ ]}\ $$&lt;&#x2F;p&gt;
&lt;p&gt;In other words, we are looking for the innermost application term, and we reduce the function term before we reduce the argument term.&lt;&#x2F;p&gt;
&lt;p&gt;It is now interesting and essential to see that an evaluation context ${\color{\lightgreen}C[~ ]}$ can be split up
into multiple &lt;em&gt;frames&lt;&#x2F;em&gt; which we can arranged as a list (stack) to recover the original context:&lt;&#x2F;p&gt;
&lt;p&gt;$$ \mathrm{Fr} ::= [~ ]\ |\ [~ ] N\ |\ V [~ ] $$&lt;&#x2F;p&gt;
&lt;p&gt;When descending into an evaluation context, we turn each level into a frame and
put it on a stack. For the other direction, we take a stack of frames and plug each frame into the next one to obtain
the original evaluation context.  For example, writing $::$ as separator and having stacks grow to the left, the evaluation
context $V_1 (V_2 (([] N)))$ becomes $[~] :: ([~] N) :: (V_2 [~]) :: (V_1 [~])$.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;continuations&quot;&gt;Continuations&lt;&#x2F;h2&gt;
&lt;p&gt;The key idea now is this: since frames are particular points in the term, we can associate these
points with a bit of data that specifies what our abstract machine should do next. The data
we need to keep track of are &lt;em&gt;semantic values&lt;&#x2F;em&gt; $V$ which are the results of evaluating
expressions and &lt;em&gt;environments&lt;&#x2F;em&gt; $\rho$ which map variables to semantic values. An
empty environment is written $\emptyset$ and extending an environment $\rho$ with
a binding $x:=V$ is written $[x := V]\rho$&lt;&#x2F;p&gt;
&lt;p&gt;For now, the only kind of semantic value we can have will be a &lt;em&gt;closure&lt;&#x2F;em&gt;, that is,
a pair $\langle M, \rho\rangle$ of an abstraction $M$ and an environment $\rho$
that captures assignments for the free variables that might occur. So for
example, a $(\lambda x. \lambda y. x y) (\lambda z.z)$ can be evaluated to
$\langle \lambda y. x y, [ x := (\lambda z.z) ]\rangle$&lt;&#x2F;p&gt;
&lt;p&gt;Let us call the frame annotated with the data &lt;em&gt;continuation points&lt;&#x2F;em&gt; and write them down.&lt;&#x2F;p&gt;
&lt;p&gt;$$ \kappa ::= \mathtt{stop}\ |\ \mathtt{arg}~N\ \rho :: \kappa\ |\ \mathtt{fun}~V :: \kappa $$&lt;&#x2F;p&gt;
&lt;p&gt;The definition reads like the definition of a stack (the data structure) that grows to the left.
Compare this to the definition of frames $\mathrm{Fr}$. We do not have a need to represent $[~]$,
but we do want to represent the empty stack. We have:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;$\mathtt{stop}$ for the empty stack,&lt;&#x2F;li&gt;
&lt;li&gt;a case $\mathtt{arg}~N~\rho$ for evaluating an argument in environment $\rho$ and&lt;&#x2F;li&gt;
&lt;li&gt;a case $\mathtt{fun}~V$ that represents an evaluated function term $V$ waiting for its argument.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;We need one more case for returning the result of evaluation. We write this as $\mathtt{ret}\ V$
and note that it can only occur at the top of the stack:&lt;&#x2F;p&gt;
&lt;p&gt;$$ K = \mathtt{ret}\ V :: \kappa\ | \ \kappa $$&lt;&#x2F;p&gt;
&lt;!--
$$
\begin{array}{ll}
x &amp; x \in \mathsf{Var} \\\\
\lambda x. M &amp; \\\\
M N &amp; \\\\
\mathcal{C} M &amp; \\\\
\mathcal{A} M &amp; \\\\
\end{array}
$$
--&gt;
&lt;!--
$$
\begin{array}{ll}
[~ ] &amp; \\\\
[~ ] N &amp; \\\\
V [~ ] &amp; \\\\
\mathcal{C} [~ ] &amp; \\\\
\mathcal{A} [~ ] &amp; \\\\
\end{array}
$$
--&gt;
&lt;p&gt;The CEK machine has a control register C, and environment $\rho$, and a stack K. Together, these
three registers form the state. The control register can be empty which we write as $\updownarrow$ or contain
a term $M$. The rules are as follows:&lt;&#x2F;p&gt;
&lt;p&gt;$$
\begin{array}{lllllll}
\langle x, &amp;amp;\rho, &amp;amp;\kappa \rangle &amp;amp;\longrightarrow &amp;amp;\langle \updownarrow, &amp;amp;\emptyset, &amp;amp;\mathtt{ret}~ \rho(x) :: \kappa\rangle \\
\langle \lambda x.M, &amp;amp;\rho, &amp;amp;\kappa \rangle &amp;amp;\longrightarrow &amp;amp;\langle \updownarrow, &amp;amp;\emptyset, &amp;amp;\mathtt{ret}~ \langle\lambda x.M, \rho\rangle :: \kappa \rangle \\
\langle M N, &amp;amp;\rho, &amp;amp;\kappa \rangle  &amp;amp;\longrightarrow &amp;amp;\langle M, &amp;amp;\rho, &amp;amp;\mathtt{arg}~ N~ \rho :: \kappa \rangle \\
\langle \updownarrow, &amp;amp;\emptyset, &amp;amp;\mathtt{ret} V :: \mathtt{arg} N \rho :: \kappa \rangle  &amp;amp;\longrightarrow &amp;amp;\langle N, &amp;amp;\rho, &amp;amp;\mathtt{fun}~ V :: \kappa \rangle \\
\langle \updownarrow, &amp;amp;\emptyset, &amp;amp;\mathtt{ret} V :: \mathtt{fun} \langle\lambda x. M, \rho\rangle :: \kappa \rangle  &amp;amp;\longrightarrow &amp;amp;\langle M, &amp;amp;[x := V]\rho, &amp;amp;\kappa \rangle \\
\end{array}
$$&lt;&#x2F;p&gt;
&lt;p&gt;In order to complete the definition we should talk about &quot;loading&quot; $\lambda$-expressions into the machine, let it
perform transitions until it is done, then &quot;unloading&quot; the result.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Loading $M$ means setting the initial state to $\langle M, \emptyset, \mathtt{stop}\rangle$&lt;&#x2F;li&gt;
&lt;li&gt;The terminal state should look like $\langle \updownarrow, \emptyset, \mathtt{ret} V :: \mathtt{stop}\rangle$. From
this, we can unload $V$.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;There are terms that will make the machine loop. For a closed term $M$, if the machine terminates, it will end
up in a terminal state and we should be able to unload. Therefore we can define a partial function $eval_{CEK}$
which loads a term $M$, applies transitions, and if it ends up in a terminal state, returns $V$. One can
then prove that if $eval_{CEK} (M) = V$ then $M \longrightarrow^* V$.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;control-operators&quot;&gt;Control operators&lt;&#x2F;h2&gt;
&lt;p&gt;What if we went further in our approach of adding data to our stack frames? Suppose, our semantic values
were not only closures but could also capture continuations (stacks). Then we could restore them and
get a notion of &quot;jumping&quot;. We add two control operators ${\color{lightgreen}\mathcal{C}}$ and
${\color{lightgreen}\mathcal{A}}$:&lt;&#x2F;p&gt;
&lt;p&gt;$$ M, N ::= x\ |\ \lambda x. M\ |\ M N\ |\ {\color{lightgreen}\mathcal{C}} M\ |\ {\color{lightgreen}\mathcal{A}} M $$&lt;&#x2F;p&gt;
&lt;p&gt;We skip evaluation context and jump straight to frames:&lt;&#x2F;p&gt;
&lt;p&gt;$$ \mathrm{Fr} ::= [~ ]\ |\ [~ ] N\ |\ V [~ ]\ |\ {\color{lightgreen}\mathcal{C}} [~ ]\ |\ {\color{lightgreen}\mathcal{A}} [~ ] $$&lt;&#x2F;p&gt;
&lt;p&gt;Our continuations is almost the same, but gets a continuation marker:&lt;&#x2F;p&gt;
&lt;p&gt;$$ \kappa ::= \mathtt{stop}\ |\ {\color{lightgreen}\mathtt{cont}} :: \kappa\ |\ \mathtt{arg} N \rho :: \kappa\ |\ \mathtt{fun} V :: \kappa $$&lt;&#x2F;p&gt;
&lt;p&gt;Our semantic values $V$ can now either be closures or p-continuations $\langle{\color{lightblue}\mathtt{p}}, \kappa\rangle$.
With this, we can now add additional transitions for the control operators:&lt;&#x2F;p&gt;
&lt;p&gt;$$
\begin{array}{lllllll}
\langle {\color{lightgreen}\mathcal{C}} M, &amp;amp;\rho, &amp;amp;\kappa \rangle &amp;amp;\longrightarrow &amp;amp;\langle M, &amp;amp;\rho, &amp;amp;{\color{lightgreen}\mathtt{cont}} :: \kappa\rangle \\
\langle \updownarrow, &amp;amp;\emptyset, &amp;amp;\mathtt{ret} \langle\lambda x. M, \rho\rangle :: {\color{lightgreen}\mathtt{cont}} :: \kappa \rangle  &amp;amp;\longrightarrow &amp;amp;\langle M, &amp;amp;[x := \langle{\color{lightblue}\mathtt{p}}, \kappa\rangle]\rho, &amp;amp;\mathtt{stop} \rangle \\
\langle \updownarrow, &amp;amp;\emptyset, &amp;amp;\mathtt{ret} \langle{\color{lightblue}\mathtt{p}}, \kappa_0 \rangle :: {\color{lightgreen}\mathtt{cont}} :: \kappa \rangle  &amp;amp;\longrightarrow &amp;amp; \langle \updownarrow, &amp;amp;\emptyset, &amp;amp;\mathtt{ret}\langle{\color{lightblue}\mathtt{p}}, \kappa\rangle :: \kappa_0 \rangle \\
\langle \updownarrow, &amp;amp;\emptyset, &amp;amp;\mathtt{ret}~V :: \mathtt{fun} \langle{\color{lightblue}\mathtt{p}}, \kappa_0 \rangle :: \kappa \rangle  &amp;amp;\longrightarrow &amp;amp; \langle \updownarrow, &amp;amp;\emptyset, &amp;amp;\mathtt{ret}~V:: \kappa_0 \rangle \\
\langle {\color{lightgreen}\mathcal{A}} M, &amp;amp;\rho, &amp;amp;\kappa \rangle  &amp;amp;\longrightarrow &amp;amp; \langle M, &amp;amp;\rho, &amp;amp;\mathtt{stop} \rangle \\
\end{array}
$$&lt;&#x2F;p&gt;
&lt;p&gt;I am not going to reproduce the entire paper. It includes the CK machine (which substitutes eagerly, instead
of putting bindings into an environment). This is useful for proving properties, but substitution is something
that is avoided in actual implementations.  The paper goes on to obtain a calculus (via the CC machine and the
C rewriting system) which is proven equivalent to the CEK machine semantics (with control operators).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;stop-the-empty-stack&quot;&gt;stop: the empty stack&lt;&#x2F;h2&gt;
&lt;p&gt;What I wanted for now: a self-contained description of the CEK, a call-by-value abstract machine. When we strip
away the discussion of control operators, we can see the beautifully simple idea that capturing &quot;what needs to
be done next&quot; in a control stack.&lt;&#x2F;p&gt;
&lt;p&gt;The stack is very much a control stack: while is has some data, this data is for the machine itself. The actual argument
passing happens in the environment. The environment however, is not actually a stack: it is captured in closures
and extended at different times so it looks more like a tree. You can read a bit more in
Principles of Programming Languages &lt;a href=&quot;https:&#x2F;&#x2F;felleisen.org&#x2F;matthias&#x2F;4400-s20&#x2F;lecture23.html&quot;&gt;lecture notes&lt;&#x2F;a&gt; which
also extend the CEK wth storage, which yields the CESK.&lt;&#x2F;p&gt;
&lt;p&gt;Abstract machines correspond closely to evaluators via transform to continuation passing style. There are many papers about this.
Ager, Biernacki, Danvy and Midtgaard &lt;a href=&quot;https:&#x2F;&#x2F;www.brics.dk&#x2F;RS&#x2F;03&#x2F;13&#x2F;BRICS-RS-03-13.pdf&quot;&gt;A Functional Correspondence between Evaluators and Abstract Machines&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Abstract machines have been used in correct-by-design programming language implementations. The challenge is in
representing environments efficiently: a closure may not need to access the &lt;em&gt;entire&lt;&#x2F;em&gt; environment.
There is a nice discussion about the role of abstract machines for PL implementations in Xavier Leroy&#x27;s talk &lt;a href=&quot;https:&#x2F;&#x2F;xavierleroy.org&#x2F;talks&#x2F;zam-kazam05.pdf&quot;&gt;&quot;From Krivine&#x27;s machine to the Caml implementations&quot;&lt;&#x2F;a&gt;. A properly efficient
implementation would translate to machine code, using registers or generally
any calling convention - but if one does use an abstract machine, one can make it better by applying techniques
such as keeping some of the environment in the stack and pushing multiple arguments on the stack as a way to access them faster.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>CBPV and Natural Deduction - Part 4. Polarized Logic</title>
        <published>2023-09-16T00:00:00+00:00</published>
        <updated>2023-09-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://burakemir.ch/post/cbpv-pt4-polarized/"/>
        <id>https://burakemir.ch/post/cbpv-pt4-polarized/</id>
        
        <content type="html" xml:base="https://burakemir.ch/post/cbpv-pt4-polarized/">&lt;p&gt;This is the last and final part of my little study of polarized
natural deduction by means of CBPV. The previous parts are
&lt;a href=&quot;https:&#x2F;&#x2F;burakemir.ch&#x2F;post&#x2F;cbpv-pt1-small-steps&#x2F;&quot;&gt;&quot;pt1. small steps&quot;&lt;&#x2F;a&gt;,
&lt;a href=&quot;https:&#x2F;&#x2F;burakemir.ch&#x2F;post&#x2F;cbpv-pt2-sum-product&#x2F;&quot;&gt;&quot;pt2. sums and products&quot;&lt;&#x2F;a&gt;, and
&lt;a href=&quot;https:&#x2F;&#x2F;burakemir.ch&#x2F;post&#x2F;cbpv-pt3-linear-logic&#x2F;&quot;&gt;&quot;pt3. linear logic&quot;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;In this part, I will sum up what I find this interesting. This is
going to be a bit more personal&#x2F;opinionated&#x2F;colored than the previous
parts.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;proof-theoretical-semantics&quot;&gt;Proof-theoretical semantics&lt;&#x2F;h2&gt;
&lt;p&gt;CBPV as polarized natural deduction helps develop an intuition for &quot;proof-theoretical semantics.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;It may be a subjective preference, but I consider intuition important.
I believe that in the ideal world, intuition, &quot;explanatory power&quot; and
teachability would play a role that has weight equal or greater than
&quot;new results&quot; of research. This is clearly not the world we
live in, but we can nevertheless asipre.&lt;&#x2F;p&gt;
&lt;p&gt;So let me draw a rough &quot;baseline&quot; of logic, computation and programming languages.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Natural deduction (not sequent calculus) is the standard notation for
discussing formal reasoning, proof, structural and substructural proof theory.
It goes back to Jaskowski and Gentzen, but today, two people deserve special mention:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Dag Prawitz for picking up proof-theoretic semantics and natural
deduction, providing a normalization theorem for natural deduction
calculi&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Per Martin-Löf for basing his presentation of &lt;a href=&quot;https:&#x2F;&#x2F;archive-pml.github.io&#x2F;martin-lof&#x2F;pdfs&#x2F;Bibliopolis-Book-retypeset-1984.pdf&quot;&gt;intuitionistic type
theory&lt;&#x2F;a&gt; on the natural deduction style and establishing the concept of
judgment.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Type systems are presented as natural deduction calculi (with &quot;localized assumptions&quot;, so a judgment looks like a sequent of sequent calculus). Type systems provide the most effective form of mechanized reasoning and program analysis
that we have in programming languages.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;!--This is not even
mentioning the advantages for documentation, IDE support, modularity
and separate compilation. In the Curry-Howard perspective, type-checking is 
a strangely backwards operation where we have a proof and are looking
for the proposition it is proving.
--&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Sequent calculus is the device used in more formal studies of reasoning,
structured and substructual proof. When we use sequent calculus, we
accept a greater distance to intuition and &quot;informal reasoning&quot; for
technical reasons. Automated reasoning using &quot;semantic tableaux&quot; is
essentially the same as working with sequent calculus.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;In &lt;a href=&quot;https:&#x2F;&#x2F;www.paultaylor.eu&#x2F;stable&#x2F;prot.pdf&quot;&gt;Proofs and Types&lt;&#x2F;a&gt;, Jean-Yves Girard argues that sequent calculus is &quot;the prettiest illustration of
the symmetries of Logic&quot;, and that it was &quot;generally ignored by computer scientists.&quot; This may have been true at the time, but it is certainly no longer the case.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Samson Abramsky does give the sequent calculus its deserved treatment
in &lt;a href=&quot;https:&#x2F;&#x2F;www.sciencedirect.com&#x2F;science&#x2F;article&#x2F;pii&#x2F;030439759390181R&quot;&gt;Computational interpretations of linear logic&lt;&#x2F;a&gt;, though Girard may not have had an operational reading in mind. Abramsky describes a symmetry between
constructors (right rules, introduction rules) and destructors (left rules,
elimination rules) which gives a proof-theoretic explanation on
insights that go back to the McCarthy and Landin.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;focusing-and-uniform-proofs&quot;&gt;Focusing and uniform proofs&lt;&#x2F;h2&gt;
&lt;p&gt;Now that we have established a (possibly subjective) baseline, let&#x27;s talk
about focusing. Focusing makes it appearance in logic programming: here
computation is not proof normalization, but proof &lt;strong&gt;search&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Dale Miller, Gopalan Nadathur, Frank Pfenning and Andre Scredrov. &quot;Uniform proofs as the foundation for logic programming&quot;. Annals of Pure and Applied Logic. 51:125-157, 1991&lt;&#x2F;li&gt;
&lt;li&gt;Around roughly the same time, Jean-Marc Andreoli published &quot;Logic programming with focusing proofs in linear logic.&quot;. Journal of Logic and Computation. 2(3):197-347&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Focusing is a &lt;strong&gt;structuring principle&lt;&#x2F;strong&gt; for proofs. It is a way to eliminate
the redundancy that is introduced when passing from natural deduction to
sequent calculus (Pfennings &lt;a href=&quot;https:&#x2F;&#x2F;www.cs.cmu.edu&#x2F;~fp&#x2F;courses&#x2F;oregon-m10&#x2F;04-focusing.pdf&quot;&gt;lectures notes&lt;&#x2F;a&gt;). Girard was aware of
Andreoli&#x27;s work and referenced it &quot;On the unity of logic&quot;, introducing
&quot;positive&quot; and &quot;negative&quot; polarity as concepts.&lt;&#x2F;p&gt;
&lt;p&gt;The key idea is that if a rule of inference is &lt;strong&gt;invertible&lt;&#x2F;strong&gt;, it makes sense to
apply it directly and not look for other rules. When invertible rules
have priority over others, this reduces the large search space of proofs.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Polarized focusing&lt;&#x2F;strong&gt; goes further: in the context of proof search is about &quot;combining
runs of connectives that are positive or negative, with explicit coercions
between runs. These coercions, written $\uparrow$ and $\downarrow$ are
called &lt;em&gt;shift operators&lt;&#x2F;em&gt;.&quot; (Pfenning, ibid.) This is what we discussed
in this series.&lt;&#x2F;p&gt;
&lt;!--
## Applications of Linear Logic
* After pt3, I prepared a talk [&quot;Call-by-push-value&quot; and ownership](https:&#x2F;&#x2F;burakemir.ch&#x2F;odersky-fest-23&#x2F;) where I shared my intention to apply some of this 
content to formalize a part of Rust&#x27;s type system.

  * In short, it has been known for a long time that linear&#x2F;affine types 
and substructural logic can be used to model resource management. The
wikipedia article on 
[Bunched logic](https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Bunched_logic#Applications)
mentions John C. Reynolds using an affine type theory in 1978. This is
a whopping 9 years before Girard published &quot;linear logic&quot;.

  * This is not the place to discuss details neither the subtleties how the 
&quot;no duplication&quot; linearity constraints is part of such substructural logics
nor what part of Rust&#x27;s types system actually matches the &quot;no duplication&quot;
of linear logic. However, I found out that (besides Phil Wadler&#x27;s numerous
papers on linear logic), Martin Oderky published a little-known paper on 
&quot;observers for linear logic&quot; which describes read-only access to linear
types as useful in programming, and which is very close to the short-lived, 
immutable, shared references we call &quot;borrows&quot; today.
     * The &quot;lifetime parameters&quot; are what research calls &quot;region variables&quot; and I think Tofte &amp;amp; Talpin&#x27;s &quot;region-based memory management&quot; may be a good
best reference (it is at least what I learnt in grad school). Lots of
people researched regions afterwards.



https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Bunched_logic#Applications
 in types ing resources like memory. I am talking the 1970s.
John C. Reynolds in 1978 (via wikipedia)
There are
more and related approaches, such as Tofte &amp;amp; Talpin&#x27;s &quot;region-based memory
management&quot;, uniqueness types and more recent paper by Guillaume
Munch-Maccagnoni [&quot;Resource Polymorphism&quot;](https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;1803.02796)
which discusses the use even in a garbage-collected language.


 for the [OderskyFest 2023](https:&#x2F;&#x2F;burakemir.ch&#x2F;odersky-fest-23&#x2F;)

# Rewind: Logic and Computation

I want to start with a few big picture thoughts what keeps on bringing
me back to logic.

am gathering some thoughts on why polarity and focusing
holds promise towards identifying &quot;fundamental&quot; concepts in programming language research.
Even without the Curry-Howard perspective and logic, distinguishing between
data and computation makes immediate sense. Can we get our formal systems
to reflect this intuition?
--&gt;
&lt;h2 id=&quot;what-just-happened&quot;&gt;What just happened?&lt;&#x2F;h2&gt;
&lt;p&gt;We saw how call-by-push-value (CBPV) &quot;separates&quot; typed $\lambda$-calculus
into &lt;em&gt;value types&lt;&#x2F;em&gt; and &lt;em&gt;computation types&lt;&#x2F;em&gt;. We obtain a type system which can be
viewed as a natural deduction calculus. This view may seem slightly forced, since
operations like $\mathtt{thunk}$ and $\mathtt{force}$ that control evalution
do not seem very logical. But there are compelling reasons to have them!&lt;&#x2F;p&gt;
&lt;p&gt;If we consider the treatment of inference and assumptions in linear
logic, the familiar operators $\vee, \wedge$ separate into additive
versions $\oplus, \&amp;amp;$ as well as multiplicate versions  ⅋ $\otimes$.&lt;&#x2F;p&gt;
&lt;p&gt;Some of these types $\oplus, \otimes$ look like data type constructors,
and we called these positive or value types. For the others  ⅋ $\&amp;amp;$.
evaluation does not proceed until the environment demands it. These are
negative or computation types.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Going back to Bob Harper&#x27;s post &lt;a href=&quot;https:&#x2F;&#x2F;existentialtype.wordpress.com&#x2F;2012&#x2F;08&#x2F;25&#x2F;polarity-in-type-theory&#x2F;&quot;&gt;polarity in type theory&lt;&#x2F;a&gt;: positive types come
with a &lt;em&gt;single&lt;&#x2F;em&gt; elimination rules which describe how the proof makes
sense of the constituent(s) of the proposition. The connective is
&lt;strong&gt;inductively defined&lt;&#x2F;strong&gt; in the sense that the introduction rule
completely determines what the elimination rule does. It &quot;writes itself&quot;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;On the other hand, negative types come with elimination rules that
determine what the proofs are going to look like. They are &lt;strong&gt;coinductively
defined&lt;&#x2F;strong&gt; in the sense that &quot;there is no commitment to the internal
structure of a proof&quot;, anything that provides a way to apply
elimination rules is acceptable. These may be called &quot;lazy types&quot;,
computation is suspended.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;There is more to say here (concurrency and &quot;par&quot;, applications to
memory management, category theory) but that will have to happen
some other time.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;putting-it-all-together&quot;&gt;Putting it all together&lt;&#x2F;h2&gt;
&lt;p&gt;Types can be defined by either introduction or elimination rules, and
the straightforward way to interpret this is to think of negative
types as suspending evaluation (&quot;lazy&quot;, unevaluated, &quot;objects&quot;) and
positive types as being fully evaluated (&quot;structured data&quot;).&lt;&#x2F;p&gt;
&lt;p&gt;Having both of these in a single calculus, that moreover corresponds to
polarized natural deduction, is simply amazing. Surely, being able to
encode various formal calculi that are either call-by-name or call-by-value
is interesting. From a more practical perspective, it is now easy to
see that when one wants to formalize &quot;object-oriented style,&quot; which will
decidedly involve something like records on unevaluated functions, this
will involve negative types.&lt;&#x2F;p&gt;
&lt;p&gt;To give a vauge, but hopefully illuminating idea: consider how a &quot;vtable&quot;
is quite literally a record of function pointers, &quot;waiting&quot; for
program execution to select one among them before proceeding with
computation. And how representing an object involves carrying around a
vtable.&lt;&#x2F;p&gt;
&lt;p&gt;All this makes me think that when formalizing a programming language, it seems
very attractive to translate the calculus to CBPV (or something like CBPV).
Of course, this supposes that formalization is taking place - it looks
like I will finally have some motivation to learn a proof assistant.&lt;&#x2F;p&gt;
&lt;p&gt;I hope you found this little series useful in developing intuition for
linear logic as well as the role of &quot;negative types.&quot;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>CBPV and Natural Deduction - Part 3. Linear Logic</title>
        <published>2023-08-25T00:00:00+00:00</published>
        <updated>2023-08-25T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://burakemir.ch/post/cbpv-pt3-linear-logic/"/>
        <id>https://burakemir.ch/post/cbpv-pt3-linear-logic/</id>
        
        <content type="html" xml:base="https://burakemir.ch/post/cbpv-pt3-linear-logic/">&lt;p&gt;Welcome back to our study of polarized natural deduction and what
CBPV has to do with it. For the previous parts
of this journey, check out &lt;a href=&quot;https:&#x2F;&#x2F;burakemir.ch&#x2F;post&#x2F;cbpv-pt1-small-steps&#x2F;&quot;&gt;&quot;pt1. small steps&quot;&lt;&#x2F;a&gt;
and &lt;a href=&quot;https:&#x2F;&#x2F;burakemir.ch&#x2F;post&#x2F;cbpv-pt2-sum-product&#x2F;&quot;&gt;&quot;pt2. sums and products&quot;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-happened-so-far&quot;&gt;What happened so far&lt;&#x2F;h2&gt;
&lt;p&gt;In part 1, we introduced the essential parts of call-by-push-value (CBPV):
splitting types into value and computation types, with shifts between
these worlds. We saw that static typing constrains evaluation order,
without the need for an external specification like evaluation context
definition, and that this enables us to give an abstract machine.
Although the CK machine still uses substitution, the fact that it
only looks at bounded depth from the root makes it already a lot
more efficient than a recursive evaluator that has to descend
a term and looks for redexes. We hinted at the connection with
intermediate representation in compilers, given that all
intermediate results are named.&lt;&#x2F;p&gt;
&lt;p&gt;In part 2, we added sum and products tyes as value types, and also a
second product type as computation type. We hinted that the difference
between the two product types has to do with linear logic.&lt;&#x2F;p&gt;
&lt;p&gt;In this part, we reveal how linear logic relates to these two
different kind of product types. The very notion of propositions having
polarity comes from linear logic; going in this direction is
a deliberate choice in order to simple, intuitive explanation.&lt;&#x2F;p&gt;
&lt;p&gt;Another choice to discuss CBPV is to focus on natural deduction.
Almost all linear logic discourse happens on sequent calculi, but
Prawitz that natural deduction is illuminating, as witnessed by
the fact that the simplest example of Curry-Howard-Lambek
correspondence is between $\lambda$ calculus and natural deduction
for minimal logic.&lt;&#x2F;p&gt;
&lt;p&gt;Let us dive right in and get from natural deduction to linear natural deduction.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;assumptions-and-linearity&quot;&gt;Assumptions and Linearity&lt;&#x2F;h2&gt;
&lt;p&gt;We formulated our typing rules in the standard way, with judgments
that read $\Gamma \vdash e : T$. In terms of logic, this is a
hypothetical judgment &quot;$T$ is true under assumptions $\Gamma$&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;This style of writing judgments is called &quot;localized assumptions&quot; or
sometimes sequent style: all available assumptions are repeated on
every node of our derivation. Most treatments of natural deduction
instead assumptions as some leaf nodes that are marked when
they are discharged.&lt;&#x2F;p&gt;
&lt;p&gt;In the programming view, assumptions are assignments of a type to a variable.
In using the $\lambda$-calculus as a programming language, we can use
variables in an unconstrained maner, as in these expressions:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;$\mathrm{twice} := \lambda f: A \rightarrow A. \lambda x: A. f (f x)$ and $\mathrm{double} := \lambda x: Int. x + x$&lt;&#x2F;li&gt;
&lt;li&gt;$\mathrm{K} := \lambda x. \lambda y. x$&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Type derivations for the bodies $f (f x)$ and $x + x$ and $x$ will use variables
from the typing context more than once. In the case of $K$, there will be
variable $y$ introduced to the context that is not used at all.
These examples show that we use $\Gamma$ as a set of assumptions. We can freely
use anything that is in the set.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Linearity&lt;&#x2F;em&gt; use a variable exactly once. Just as in mathematics, a linear equation has
the shape $a * x + b = 0$ where $x$ is used once (with $a \neq 0$, thus polynomial degree 1), in &lt;em&gt;linear logic&lt;&#x2F;em&gt;,
we are interested in the case that an assumption is used exactly once.
Why would we do this? There are many concrete applications to linearity
in programming languages. The one we will be most interested in is the
inherent notion of &lt;em&gt;exclusive ownership&lt;&#x2F;em&gt; that comes from treating types
as resources.&lt;&#x2F;p&gt;
&lt;p&gt;A close friend of linearity is &lt;em&gt;affinity&lt;&#x2F;em&gt; where polynomial degree may
be either 1 or 0. We can ignore variables. This is pretty interesting as
you can see from the examples: with an affine type system, we can still
assign a type to terms like $K$ combinator that ignore variables.
The more practical example is code like this:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#383838;color:#e6e1dc;&quot;&gt;&lt;code&gt;&lt;span&gt;fn (x: &amp;amp;mut u32) {
&lt;&#x2F;span&gt;&lt;span&gt;  if (some_condition()) { *x = 1; }
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;!--
There is more to say about linear logic than these applications, but for 
our purposes, understanding CBPV as polarized natural deduction (with an
application to tracking exclusive ownership) this is sufficient.
--&gt;
&lt;!--
Note that if a program was already linear, our rules would already be 
good for typing it. We now want to refine our typing rules so that only
linear programs, to exclude the possibility
of using a variable more than once.
--&gt;
&lt;!--
We can still consider the context to be a set; we just need to careful
when the rules combine typing contexts. We want to make sure that contexts
are disjoint sets.
--&gt;
&lt;!--
Consequently, the expressions above will not be typable. The types come with
an inherent ownership: they are resource, and - in modern programming terms -
a $\lambda$ expression has *ownership* of these resources. When we combine
derivations, we make explicit that they do not share any assumptions.
Let&#x27;s jump right in.
--&gt;
&lt;h2 id=&quot;linear-cbpv&quot;&gt;Linear CBPV&lt;&#x2F;h2&gt;
&lt;p&gt;We can now define a linear natural deduction calculus, using the standard notation for
linear logic connectives. We will do this by simply repeating all the rules
we had previously for call-by-push-value, but now with the added constraint
that variables (assumptions) are used exactly once. For the judgment
$\Gamma \vdash e: T$ we require that exactly the free variables in $e$ appear in $\Gamma$.
If we want an affine type discipline instead, we require that $\Gamma$ be a superset
of all the variables in $e$.&lt;&#x2F;p&gt;
&lt;p&gt;$$
\begin{prooftree}
\AxiomC{$x : A^+ \in \Gamma$}
\RightLabel{$(\mathrm{hyp})$}
\UnaryInfC{$\Gamma \vdash x: A^+$}
\end{prooftree}
$$&lt;&#x2F;p&gt;
&lt;p&gt;Introduction and elimination rules for &lt;em&gt;linear implication&lt;&#x2F;em&gt; $\multimap$.
Note how we use $\Delta$ to emphasize that variables are disjoint from $\Gamma$.&lt;&#x2F;p&gt;
&lt;p&gt;$$
\begin{prooftree}
\AxiomC{$\Gamma, x: A^+ \vdash s: B^-$}
\RightLabel{$(\multimap_I)$}
\UnaryInfC{$\Gamma \vdash (\lambda x: A^+. s):\, A^+ \multimap B^-$}
\end{prooftree}
\quad
\quad
\begin{prooftree}
\AxiomC{$\Gamma \vdash s:\, A^+ \multimap B^-$}
\AxiomC{$\Delta \vdash t:\, A^+$}
\RightLabel{$(\multimap_E)$}
\BinaryInfC{$\Gamma, \Delta \vdash (s\ t):\, B^-$}
\end{prooftree}
$$&lt;&#x2F;p&gt;
&lt;p&gt;Linear implication $A^+ \multimap B^-$ is different from arrow type:
the argument resource $A^+$ is &lt;em&gt;consumed&lt;&#x2F;em&gt; and in return we get a certain
computation resource $B^-$.&lt;&#x2F;p&gt;
&lt;p&gt;Now comes the shift from values to computations. As before, if you
compare with &lt;a href=&quot;https:&#x2F;&#x2F;burakemir.ch&#x2F;post&#x2F;cbpv-pt1-small-steps&#x2F;&quot;&gt;part 1&lt;&#x2F;a&gt;, the only difference
is that there is a separate, disjoint context named $\Delta$.&lt;&#x2F;p&gt;
&lt;p&gt;$$
\begin{prooftree}
\AxiomC{$\Gamma \vdash s: A^+$}
\RightLabel{$(\uparrow_I)$}
\UnaryInfC{$\Gamma \vdash \mathtt{return}\ s:\, \uparrow\!{}A^+$}
\end{prooftree}
\quad
\quad
\begin{prooftree}
\AxiomC{$\Gamma \vdash s:\, \uparrow\!{}A^+$}
\AxiomC{$\Delta, x: A^+ \vdash t:\, C^-$}
\RightLabel{$(\uparrow_E)$}
\BinaryInfC{$\Gamma, \Delta \vdash \mathtt{let\ val}\ x = s\ \mathtt{in}\ t:\, C^-$}
\end{prooftree}
$$&lt;&#x2F;p&gt;
&lt;p&gt;This is easy! The rules for introducing $(\downarrow_I)$ and eliminating
$(\downarrow_E)$ the shift from computation to values do not actually change so
we don&#x27;t repeat them here (consult &lt;a href=&quot;https:&#x2F;&#x2F;burakemir.ch&#x2F;post&#x2F;cbpv-pt1-small-steps&#x2F;&quot;&gt;part 1&lt;&#x2F;a&gt;).
We have defined a core linear CBPV calculus with abstraction and application.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sums-and-products&quot;&gt;Sums and Products&lt;&#x2F;h2&gt;
&lt;p&gt;We move on to sum and product types discussed in &lt;a href=&quot;https:&#x2F;&#x2F;burakemir.ch&#x2F;post&#x2F;cbpv-pt2-sum-product&#x2F;&quot;&gt;part 2&lt;&#x2F;a&gt;. There,
we noticed two distinct product types: a value pair type and a computation record type.&lt;&#x2F;p&gt;
&lt;p&gt;The sum and product value types correspond to disjunction and conjuction in minimal and intuitionistic
logic. In linear logic, there are multiple ways to define disjunction. We use standard, but different symbols
for the corresponding linear logic connectives.&lt;&#x2F;p&gt;
&lt;p&gt;The linear version of our sum value type correspons to &lt;em&gt;additive disjunction&lt;&#x2F;em&gt; $\oplus$ (still called &quot;plus&quot;):
$$
\begin{prooftree}
\AxiomC{$\Gamma\vdash v: A_j^+$}
\RightLabel{$(\oplus_I)$}
\UnaryInfC{$\Gamma \vdash \mathtt{inj}_i\ v : {\color{lightgreen}{{\large \oplus}_I A^+_i}}$}
\end{prooftree}
$$&lt;&#x2F;p&gt;
&lt;p&gt;$$
\begin{prooftree}
\AxiomC{$\Gamma \vdash v : {\color{\lightgreen}{{\large \oplus}_I A^+_i}}$}
\AxiomC{$\ldots \Delta_i, x: A_i^+ \vdash M_i : B^- \ldots$}
\RightLabel{$(\oplus_E)$}
\BinaryInfC{$\Gamma \ldots \Delta_i \ldots \vdash \mathtt{match}\ V\ \{\ldots, \mathtt{case}\ i: x.M_i \ldots\}: B^-$}
\end{prooftree}
$$&lt;&#x2F;p&gt;
&lt;p&gt;Our pair value type, as hinted at in the last part, is &lt;em&gt;multiplicative conjunction&lt;&#x2F;em&gt; $\otimes$ (&quot;tensor&quot;): we cannot
use a component of a pair and drop the other one, we have to use both.&lt;&#x2F;p&gt;
&lt;p&gt;$$
\begin{prooftree}
\AxiomC{$\Gamma\vdash v_1: A_1^+$}
\AxiomC{$\Delta\vdash v_2: A_2^+$}
\RightLabel{$(\otimes_I)$}
\BinaryInfC{$\Gamma, \Delta \vdash (v_1, v_2) :\, {\color{lightgreen}{A_1^+ \otimes A_2^+}}$}
\end{prooftree}
$$&lt;&#x2F;p&gt;
&lt;p&gt;$$
\begin{prooftree}
\AxiomC{$\Gamma\vdash v: {\color{\lightgreen}{A_1^+ \otimes A_2^+}}$}
\AxiomC{$\Delta, x: A_1^+, y: A_2^+ \vdash M: B^-$}
\RightLabel{$(\otimes_E)$}
\BinaryInfC{$\Gamma, \Delta \vdash \mathtt{match}\ V\ \mathtt{as}\ (x, y).M : B^-$}
\end{prooftree}
$$&lt;&#x2F;p&gt;
&lt;p&gt;Finally, let us look at the &quot;lazy&quot; (unevaluated) pair computation type. This connective
is called additive conjunction and written $\&amp;amp;$ (pronounced &quot;with&quot;).
For a linear record of computation, we cannot use multiple fields, we can pick one,
losing access to the rest.&lt;&#x2F;p&gt;
&lt;p&gt;$$
\begin{prooftree}
\AxiomC{$\ldots \Gamma_i \vdash s_i: B_i^- \ldots$}
\RightLabel{$({\large \&amp;amp;}_I)$}
\UnaryInfC{$\ldots \Gamma_i \ldots \vdash \lambda\{\ldots i.s_i\ldots \}: {\color{lightblue}{{\large \&amp;amp;}_I\ i.B_i^-}}$}
\end{prooftree}
$$&lt;&#x2F;p&gt;
&lt;p&gt;$$
\begin{prooftree}
\AxiomC{$\Gamma\vdash s : {\color{lightblue}{{\large \&amp;amp;}_{i \in I}\ i.B_i^-}}$}
\RightLabel{$({\large \&amp;amp;}_E)$}
\UnaryInfC{$\Gamma \vdash s\ \mathtt{get}\ i: B_i^-$}
\end{prooftree}
$$&lt;&#x2F;p&gt;
&lt;p&gt;We have defined a linear CBPV calculus with &quot;plus&quot; $\oplus$ (additive disjunction),
&quot;tensor&quot; $\otimes$ (multiplicative conjuction) and &quot;with&quot; $\&amp;amp;$ (additive conjunction) .&lt;&#x2F;p&gt;
&lt;p&gt;At this point, you may wonder about the missing combination: multiplicative disjunction. This
is written ⅋ (pronounced &quot;par&quot;) and corresponds to a sort of separate composition (say,
parallel composition of processes).  Other notions of composition along two dimension work,
too, for instance space and time (fun fact that concurrency is &quot;Nebenläufigkeit&quot; in German,
which &quot;side-by-side running&quot;).  All this and more linear logic concepts would lead us slightly
too far away from our series topic.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;towards-an-understanding-of-polarity&quot;&gt;Towards an understanding of polarity&lt;&#x2F;h2&gt;
&lt;p&gt;In our journey to understand polarity in natural deduction, we have arrived at a happy place that
lets us see a clear and easy to remember way to relate computation to CBPV, understood
as the analogon of an intermediate representation in a compiler. The order of evaluation
is specified without the help of external means.&lt;&#x2F;p&gt;
&lt;p&gt;In the next and final part, we shall look at polarity in more detail and discuss possible
applications for programming language implementation.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>CBPV and Natural Deduction - Part 2. Sums and Products</title>
        <published>2023-08-20T00:00:00+00:00</published>
        <updated>2023-08-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://burakemir.ch/post/cbpv-pt2-sum-product/"/>
        <id>https://burakemir.ch/post/cbpv-pt2-sum-product/</id>
        
        <content type="html" xml:base="https://burakemir.ch/post/cbpv-pt2-sum-product/">&lt;p&gt;We are continuing our look at call-by-push-value (CBPV), natural deduction and
abstract machines. &lt;a href=&quot;https:&#x2F;&#x2F;burakemir.ch&#x2F;post&#x2F;cbpv-pt1-small-steps&#x2F;&quot;&gt;Last time&lt;&#x2F;a&gt; we looked
at a bare-bones version so we could focus on $\lambda$-abstraction and
application.&lt;&#x2F;p&gt;
&lt;p&gt;In this part, we will only add sum and product types. In the next part we can
then shift our view towards linear logic concepts and resources.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sum-and-product-types&quot;&gt;Sum and Product Types&lt;&#x2F;h2&gt;
&lt;p&gt;We add a sum type $ \Sigma A_i $ and a product type $A_1 \times A_2$ to our value types. We also add lazy products,
$\Pi_{i \in I}\ i.B_i^-$ for reasons that have to do with the fine-grained distinction between
value and computation types.  The presentation in this section follows Levy&#x27;s book closely, except
minor changes in syntax.&lt;&#x2F;p&gt;
&lt;!-- par &amp;#x214B; --&gt;
&lt;p&gt;$$
\begin{array}{lll}
A^+ &amp;amp;::= &amp;amp; \mathbf{1}\ |\ {\color{lightgreen}{\Sigma_{i \in I} A_i}}\ |\ {\color{lightgreen}{A_1^+ \times A_2^+}}\ |\ \downarrow{A^-} \\
B^- &amp;amp;::= &amp;amp; A^+ \rightarrow B^-\ |\ {\color{lightblue}{\Pi_{i \in I}\ i.B_i^-}}\ |\ \uparrow{A^+}
\end{array}
$$&lt;&#x2F;p&gt;
&lt;p&gt;By looking at the introduction and elimination rules, we can get intuition what  sum types are.
can construct value of sum type by &lt;em&gt;injecting&lt;&#x2F;em&gt;, and when we have a value of sum type,
we can perform a case-distinction and recover which injector was used. We use a $\mathtt{match}$
syntax for the case distinction. The only special thing for CBPV is that sum types are
made from value types, they are themselves value types, but a match is a computation and
therefore yields a computation type.&lt;&#x2F;p&gt;
&lt;p&gt;$$
\begin{prooftree}
\AxiomC{$\Gamma\vdash v: A_j^+$}
\RightLabel{$(+_I)$}
\UnaryInfC{$\Gamma \vdash \mathtt{inj}_i\ v : {\color{lightgreen}{\Sigma_I A^+_i}}$}
\end{prooftree}
$$&lt;&#x2F;p&gt;
&lt;p&gt;$$
\begin{prooftree}
\AxiomC{$\Gamma \vdash v : {\color{\lightgreen}{\Sigma_I A^+_i}}$}
\AxiomC{$\ldots \Gamma, x: A_i^+ \vdash M_i : B^- \ldots$}
\RightLabel{$(+_E)$}
\BinaryInfC{$\Gamma \vdash \mathtt{match}\ V\ \{\ldots, \mathtt{case}\ i: x.M_i \ldots\}: B^-$}
\end{prooftree}
$$&lt;&#x2F;p&gt;
&lt;p&gt;We do the same with a pair type: using pair syntax constructs a pair, both components
have to be value types and the pair itself is a value type. Elimination is interesting:
we require that both values are bound at the same time. The reason for this is that
in CBPV, projection would be a computation.&lt;&#x2F;p&gt;
&lt;p&gt;$$
\begin{prooftree}
\AxiomC{$\Gamma\vdash v_1: A_1^+$}
\AxiomC{$\Gamma\vdash v_2: A_2^+$}
\RightLabel{$(\times_I)$}
\BinaryInfC{$\Gamma \vdash (v_1, v_2) :\, {\color{lightgreen}{A_1^+ \times A_2^+}}$}
\end{prooftree}
$$&lt;&#x2F;p&gt;
&lt;p&gt;$$
\begin{prooftree}
\AxiomC{$\Gamma\vdash v: {\color{\lightgreen}{A_1^+ \times A_2^+}}$}
\AxiomC{$\Gamma, x: A_1^+, y: A_2^+ \vdash M: B^-$}
\RightLabel{$(\times_E)$}
\BinaryInfC{$\Gamma \vdash \mathtt{match}\ V\ \mathtt{as}\ (x, y).M : B^-$}
\end{prooftree}
$$&lt;&#x2F;p&gt;
&lt;p&gt;Taken together, the value types for sums and products are enough to give us sum-of-product algebraic datatypes,
though pattern matching operates only on one level at a time.&lt;&#x2F;p&gt;
&lt;p&gt;In terms of logic, sums are disjunction and pairs are conjunction. Defining pairs
in this way is a harbinger of what is to follow in the next part: Bob Harper says one
might as well write $v_1 \otimes v_2$ (tensor) in his post
on &lt;a href=&quot;https:&#x2F;&#x2F;existentialtype.wordpress.com&#x2F;2012&#x2F;08&#x2F;25&#x2F;polarity-in-type-theory&#x2F;&quot;&gt;polarity in type theory&lt;&#x2F;a&gt;,
but admits it is pointless if we are not doing linear logic.
We leave this discussion of linear logic to the next part.&lt;&#x2F;p&gt;
&lt;p&gt;Now we come to the &quot;lazy product&quot;, which is closer in spirit to records of functions (which could
be called &quot;objects&quot;, but this is simplifying objects a lot). We bundle suspended computations in a
record, and we have a computation to select a particular &quot;field&quot; from this record.&lt;&#x2F;p&gt;
&lt;!--\UnaryInfC{$\Gamma \vdash \lambda\\{\\} :\\, $}--&gt;
&lt;p&gt;$$
\begin{prooftree}
\AxiomC{$\ldots \Gamma \vdash s_i: B_i^- \ldots$}
\RightLabel{$(\Pi_I)$}
\UnaryInfC{$\Gamma \vdash \lambda\{\ldots i.s_i\ldots \}: {\color{lightblue}{\Pi_I\ i.B_i^-}}$}
\end{prooftree}
$$&lt;&#x2F;p&gt;
&lt;p&gt;$$
\begin{prooftree}
\AxiomC{$\Gamma\vdash s : {\color{lightblue}{\Pi_{i \in I}\ i.B_i^-}}$}
\RightLabel{$(\Pi_E)$}
\UnaryInfC{$\Gamma \vdash s\ \mathtt{get}\ i: B_i^-$}
\end{prooftree}
$$&lt;&#x2F;p&gt;
&lt;p&gt;Also here, we shall leave the corresponding linear logic connector, &amp;amp; &quot;with&quot;, for the next part.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;machine-transitions&quot;&gt;Machine Transitions&lt;&#x2F;h2&gt;
&lt;p&gt;We extend the CK machine accordingly. There is a new stack frame $(\_ \mathtt{get}\ i)$, otherwise
the transitions are as one would expect them. As before, the heavy lifting in CK machine is done
by substitution.&lt;&#x2F;p&gt;
&lt;p&gt;$$
\begin{array}{llll}
C                                        &amp;amp; K &amp;amp; \rightsquigarrow &amp;amp; C&#x27; &amp;amp; K&#x27; \\
s\ \mathtt{get}\ i         &amp;amp; k &amp;amp; &amp;amp; s   &amp;amp;  (\_ \mathtt{get}\ i)::k \\
\lambda\{\ldots i.s_i\ldots \}         &amp;amp; (\_ \mathtt{get}\ i)::k &amp;amp; &amp;amp; s_i   &amp;amp;  k \\
\mathtt{match} (v_1, v_2)\ \mathtt{as}\ (x, y).M  &amp;amp; k &amp;amp;                 &amp;amp; M[x := v_1, y:= v_2]  &amp;amp; k \\
\mathtt{match} (\mathtt{inj}\ i\ v) \{ \ldots \mathtt{case}\ i: x.M_i\ldots \} &amp;amp; k &amp;amp;                 &amp;amp; M_i [x:=v] &amp;amp; k \\
\end{array}
$$&lt;&#x2F;p&gt;
&lt;h2 id=&quot;preview-of-the-next-part&quot;&gt;Preview of the next part&lt;&#x2F;h2&gt;
&lt;p&gt;We have discussed CBPV following a narrative of polarized natural deduction. There
were some previews of linear logic discussion, but fundamentally, the types could
not yet be interpreted as linear logic proposition.&lt;&#x2F;p&gt;
&lt;p&gt;The reason for this is that in natural deduction, assumptions can be used multiple
times and discharged whenever we want. This corresponds to the structural rules of
sequent calculus, of which Girard says they are the most important of them all.&lt;&#x2F;p&gt;
&lt;p&gt;$$
\begin{prooftree}
\AxiomC{$x : A^+ \in \Gamma$}
\RightLabel{$(\mathrm{hyp})$}
\UnaryInfC{$\Gamma \vdash x: A^+$}
\end{prooftree}
$$&lt;&#x2F;p&gt;
&lt;p&gt;Therefore, if we want to set up linear natural deduction, we have to first
make precise where and how this unconstrained use of hypotheses takes place.
We can then see how to change perspective and decree that assumptions can be
used exactly once (linear) or up to once (affine). Stay tuned for the next
session.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>CBPV and Natural Deduction - Part 1. Small steps</title>
        <published>2023-07-22T00:00:00+00:00</published>
        <updated>2023-07-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://burakemir.ch/post/cbpv-pt1-small-steps/"/>
        <id>https://burakemir.ch/post/cbpv-pt1-small-steps/</id>
        
        <content type="html" xml:base="https://burakemir.ch/post/cbpv-pt1-small-steps/">&lt;p&gt;I have been reading up on call-by-push-value (CBPV),
a variation of $\lambda$-calculus that is more
fine-grained in its treatment of argument-passing.
I then came across a chapter
from Frank Pfenning&#x27;s 2016 &lt;a href=&quot;https:&#x2F;&#x2F;www.cs.cmu.edu&#x2F;~fp&#x2F;courses&#x2F;15816-f16&#x2F;schedule.html&quot;&gt;lecture notes on substructual logic&lt;&#x2F;a&gt; that
characterizes CBPV as &lt;em&gt;polarized natural deduction.&lt;&#x2F;em&gt; In a small series
of posts, I am exploring what this means and how this relates to
compilers.&lt;&#x2F;p&gt;
&lt;p&gt;The Curry-Howard-Lambek correspondence is a nice way to connect logic and computation.
I have written about this in previous posts on my old blog, see
&lt;a href=&quot;https:&#x2F;&#x2F;bq9.blogspot.com&#x2F;2020&#x2F;04&#x2F;higher-order-logic-and-equality.html&quot;&gt;Higher-order logic and equality&lt;&#x2F;a&gt;
and
&lt;a href=&quot;https:&#x2F;&#x2F;bq9.blogspot.com&#x2F;2020&#x2F;05&#x2F;intuitionistic-propositional-logic-and.html&quot;&gt;Intuitionistic Propositional Logic and Natural Deduction&lt;&#x2F;a&gt;.
For the first part, those posts should be enough to tag along.
In the next parts, we may look at some fine points of natural deduction.&lt;&#x2F;p&gt;
&lt;!--
we sequential composition
Now CBPV raises a question:
A few reasons: 
* What does this &quot;finer-grained treatment of passing arguments&quot; correspond to
in this logical perspective? 
* if we instead regard $\lambda$-calculus as a model of computation, there are
also *abstract machines* which would be more fine-grained models of computation.
Does CBPV yield insights that we can put to good use when passing from
the $\lambda$-calculus to the lower-level machine formalisms? Could these
insights help us with the design of intermediate representations (IR) for
compilers that would support reasoning about correctness of program
transformations and optimizations?
--&gt;
&lt;!--
For the second perspective, there will be a follow up at some point. For
a sneak preview, consider the a paper [Structural Operational Semantics for Control Flow Graph Machines](https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;1805.05400&#x27;) by Dmitri Garbuzov, William Mansky, Christine Rizkallah, Steve Zdancewic.
--&gt;
&lt;h1 id=&quot;reduction-and-strategy&quot;&gt;Reduction and strategy&lt;&#x2F;h1&gt;
&lt;p&gt;In $\lambda$-calculus, our elementary computation step is a $\beta$-reduction.
Taking the perspective of the Curry-Howard-Lambek correspondence, we can regard
a type as a logical proposition and a term of typed $\lambda$-calculus as a proof
of this proposition. Here, $\beta$-reduction is a rewriting
of the proof, which removes a &#x27;detour&#x27; in the proof. In other words, computation is proof normalization.&lt;&#x2F;p&gt;
&lt;p&gt;$$
( \lambda x : A .  M)\ N \longrightarrow_β M [ x := N ]
$$&lt;&#x2F;p&gt;
&lt;p&gt;Here, $[ x := N ]$ is our way of writing substitution. The full definition requires
the usual careful treatment of bound names. The rewriting can take place anywhere in
the term.&lt;&#x2F;p&gt;
&lt;!--
Resource-efficient programming language implementations require
*lowering* substitution and symbolic representation, i.e. find lower-level representations 
that have same meaning (operational semantics). But let&#x27;s not get ahead of ourselves:
we should first have an operational semantics.
--&gt;
&lt;p&gt;Suppose we wanted to specify the &lt;em&gt;order&lt;&#x2F;em&gt; of computation steps. When there are not one, but several reducible expressions,
which reduction should happen first?&lt;&#x2F;p&gt;
&lt;p&gt;A small-step semantics would specify not only reduction, but also where exactly evaluation takes place.
To this end, one defines &lt;em&gt;evaluation context&lt;&#x2F;em&gt;, a term with a hole that specifies exactly
where in the term reduction is permitted to happen. Here is a sample definition, where we consider
$\lambda$-abstractions as values (we do not reduce under a $\lambda$.)&lt;&#x2F;p&gt;
&lt;p&gt;$$
\begin{array}{lll}
E &amp;amp;::= &amp;amp;x\ |\ \lambda x. E\ |\ E\ E \\
C &amp;amp;::= &amp;amp;[~]\ |\ E\ C\ |\ C\ V \\
V &amp;amp;::= &amp;amp;\lambda x. E
\end{array}
$$&lt;&#x2F;p&gt;
&lt;p&gt;When we have a context, we can fill its hole with a $\lambda$-expression and now exactly
where evaluation takes place. The hole of a context could also be filled with another
context.&lt;&#x2F;p&gt;
&lt;p&gt;The definition of evaluation contexts forces the argument (operand) in
an application to be evaluated before the operator. The example above is thus a form
of call-by-value. Note that the definition of $C$ comes with a somewhat arbitrary decision to evaluate the operand
before the operator. For call-by-name, passing a term that is not value would
require a context like $[~]\ E$.&lt;&#x2F;p&gt;
&lt;p&gt;Our specification of evaluation contexts seems to impose order by
defining what form of argument-passing is possible; in other
words, constraining (or leaving unconstrained) what can be bound to an identifier.&lt;&#x2F;p&gt;
&lt;!--
This brings us to a fundamental question: what can we bind to a variable? We
may want to require that an argument of a $\lambda$-expression
has to be reduced as much as possible before it is being bound to a
variable. Or we may say, let any term be bound, and let the reduction 
happen later when we cannot delay it further.
This is, very roughly, the difference of call-by-value vs call-by-name.

Another fundamental question is: how much do we reduce? Specifically,
if we have a $\lambda$ expression, do we keep looking for reducible
expressions? In many applications it is fine to stop reducing when
a term has become a $\lambda$-expression, but when we talk about
normal form of a proof, we want to reach a form where all reductions
have been carried out and no more are possible.
--&gt;
&lt;h1 id=&quot;values-and-computations&quot;&gt;Values and computations&lt;&#x2F;h1&gt;
&lt;p&gt;Instead of defining evaluation contexts separately, we now
look at a different way of impose order on evaluation.
In doing so, we start treating contexts as computation (filling the hole
with a value is something that can produce a new value). We will see that
what we are about to do is not very different from specifying an
intermediate representation (IR) of a compiler.&lt;&#x2F;p&gt;
&lt;p&gt;CBPV is a calculus that encompasses both call-by-value and call-by-name.
It achieves this through a fine-grained distinction between terms that are
&lt;em&gt;values&lt;&#x2F;em&gt; vs terms that are &lt;em&gt;computations&lt;&#x2F;em&gt; which is enfored by a
type disciple. Therefore we will have value types
$A^+$ and computation types $B^-$:&lt;&#x2F;p&gt;
&lt;p&gt;$$
\begin{array}{lll}
B^- &amp;amp;::= &amp;amp; A^+ \rightarrow B^-\ |\ \uparrow{A^+} \\
A^+ &amp;amp;::= &amp;amp;\mathbf{1}\ |\ \downarrow{B^-}
\end{array}
$$&lt;&#x2F;p&gt;
&lt;p&gt;The type operators $\uparrow{}$ and $\downarrow{}$ are described
below. We add $\mathbf{1}$ (the &quot;unit type&quot;) as a base type, with
only inhabitant $\mathtt{()}$
that we pronounce as &quot;unit&quot;.
Base types like $\mathtt{Int}$
or $\mathtt{String}$ would also be value types. All variables
have value type.&lt;&#x2F;p&gt;
&lt;p&gt;$$
\begin{prooftree}
\AxiomC{}
\RightLabel{$(1_I)$}
\UnaryInfC{$\cdot \vdash (): \mathbf{1}$}
\end{prooftree}
\quad
\quad
\begin{prooftree}
\AxiomC{$x : A^+ \in \Gamma$}
\RightLabel{(hyp)}
\UnaryInfC{$\Gamma \vdash x: A^+$}
\end{prooftree}
$$&lt;&#x2F;p&gt;
&lt;p&gt;The arrow type
forces arguments to be of value type and the result to be of
computation type. What matters most is the interplay
of $\lambda$-abstraction and application.
Here are the typing rules for these:&lt;&#x2F;p&gt;
&lt;p&gt;$$
\begin{prooftree}
\AxiomC{$\Gamma, x: A^+ \vdash M: B^-$}
\RightLabel{$(\to_I)$}
\UnaryInfC{$\Gamma \vdash (\lambda x: A^+. M):\, A^+ \rightarrow B^-$}
\end{prooftree}
\quad
\quad
\begin{prooftree}
\AxiomC{$\Gamma \vdash M:\, A^+ \rightarrow B^-$}
\AxiomC{$\Gamma \vdash V:\, A^+$}
\RightLabel{$(\to_E)$}
\BinaryInfC{$\Gamma \vdash (M\ V):\, B^-$}
\end{prooftree}
$$&lt;&#x2F;p&gt;
&lt;p&gt;In words, a $\lambda$-expression has an arrow type which is a computation (negative) type.
We can chain abstractions like $\lambda x:X^+. \lambda y:Y^+. M$ for some
term $M$ of computation type, but the argument types $X^+, Y^+$ are forced
to be be value (positive) types. Application yields a computation type.
This is where it may be useful to remember that filling the hole of a context
yields something that we can turn into a value (but it is not a value yet).&lt;&#x2F;p&gt;
&lt;p&gt;You may have noticed the $I$ and $E$ letters in the rule names.
In natural deduction, every logical connective comes
with an introduction and elimination rule. Even though we write
these like sequents of sequent calculus, there are a few differences.
In sequent calculus, there are left- and
right-(introduction)-rules, and a computation step corresponds to
the removal of detours (lemmas) via cut-elimination.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;shifts&quot;&gt;Shifts&lt;&#x2F;h3&gt;
&lt;p&gt;As any type discipline, the above rules make sure that certain programs
cannot be written anymore.
How can we return a value, though? Or write an identity computation? Or
pass a function as an argument to another function? Our calculus is
not yet complete.&lt;&#x2F;p&gt;
&lt;p&gt;First, we need a way to turn a value into a computation. More precisely,
we want to turn a term $V: A^+$ of value (positive) type into a term
of computation (negative) type.&lt;&#x2F;p&gt;
&lt;p&gt;Let us call this operation $\mathtt{return}\ p$. This is a &quot;shift&quot; between
value types and computation types and is made
explicit using a type operator $\uparrow\!{}A^+$. The notation requires
some decoding work since $\uparrow\!{}A^+$ is a computation (negative) type.&lt;&#x2F;p&gt;
&lt;p&gt;$$
\begin{prooftree}
\AxiomC{$\Gamma \vdash V: A^+$}
\RightLabel{$(\uparrow_I)$}
\UnaryInfC{$\Gamma \vdash \mathtt{return}\ V:\, \uparrow\!{}A^+$}
\end{prooftree}
\quad
\quad
\begin{prooftree}
\AxiomC{$\Gamma \vdash s:\, \uparrow\!{}A^+$}
\AxiomC{$\Gamma, x: A^+ \vdash M:\, B^-$}
\RightLabel{$(\uparrow_E)$}
\BinaryInfC{$\Gamma \vdash \mathtt{let\ val}\ x = M\ \mathtt{in}\ N:\, B^-$}
\end{prooftree}
$$&lt;&#x2F;p&gt;
&lt;p&gt;The corresponding elimination operation takes a suspended computation and yields
a value. We use a &quot;$\mathtt{let\ val}$&quot; declaration as source syntax. Note how the type
discipline forces the righthand-side to be a suspended computation and how this
imposes an order - we need to have the value before continuing. In turning the
the right-hand side into a value, we not only know where the actual computation
happens; we also bind the result to a local name.&lt;&#x2F;p&gt;
&lt;p&gt;This amounts to all intermediary results being named.&lt;&#x2F;p&gt;
&lt;p&gt;Next, we want to &quot;package&quot; a computation
into a value (&lt;em&gt;suspend&lt;&#x2F;em&gt; the computation). This will let us pass a $\lambda$-abstraction
as an argument to another $\lambda$-abstraction. We introduce an operator
$\mathtt{thunk}\ t$ that suspends a computation and an operator
$\mathtt{force}\ s$ that resumes a suspended computation.&lt;&#x2F;p&gt;
&lt;p&gt;$$
\begin{prooftree}
\AxiomC{$\Gamma \vdash M: B^-$}
\RightLabel{$(\downarrow_I)$}
\UnaryInfC{$\Gamma \vdash \mathtt{thunk}\ M:\, \downarrow\!{}B^-$}
\end{prooftree}
\quad
\quad
\begin{prooftree}
\AxiomC{$\Gamma \vdash V:\, \downarrow\!{}B^-$}
\RightLabel{$(\downarrow_E)$}
\UnaryInfC{$\Gamma \vdash \mathtt{force}\ V:\, B^-$}
\end{prooftree}
$$&lt;&#x2F;p&gt;
&lt;p&gt;Again, the shift operator indicates in the type that we
have a suspended computation which is a value. Thus,
$\downarrow$ shifts a negative to a positive type, and
$\downarrow\!A^-$ can be used in all places that
require a value type.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;example-programs&quot;&gt;Example programs&lt;&#x2F;h3&gt;
&lt;p&gt;Let&#x27;s look at examples, starting with the identity combinator
of plain $\lambda$-calculus. We want one of these at every type $I_A := \lambda x: A. x$ of type
$A \rightarrow A$. In the above polarized $\lambda$-calculus,
we get something close enough:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;for value types, there is: $\mathit{idval}_{A^+} := \lambda x: A^+. \mathtt{return}\,x$&lt;&#x2F;li&gt;
&lt;li&gt;for computation types, we have: $\mathit{idcmp}_{B^-} := \lambda x:\,\downarrow{B^-}. \mathtt{force}\ x$&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;(Exercise: what are the types of these? What kind of &quot;optimization&quot; would remove these?)&lt;&#x2F;p&gt;
&lt;!-- By looking at the rules, we can verify that this has type $A^+ \rightarrow\\,\uparrow\\!{}A^+$. --&gt;
&lt;!--
If we want to pass a computation requires suspending it via $\mathtt{thunk}\ \mathit{id}$. This
is the only way to turn it into a value type  $\downarrow(A^+ \rightarrow\\,\uparrow\\!{}A^+)$.
--&gt;
&lt;p&gt;Next, let us try a combinator $\mathit{twice}_A$ of type $(A \rightarrow A) \rightarrow A \rightarrow A$.
It takes a function $f$ and and argument $x$ and applies $f$ to $x$ twice.
In our polarized $\lambda$ calculus, we need to use the other shift
operation and end up with:&lt;&#x2F;p&gt;
&lt;!-- a term of type $\downarrow(A^+ \rightarrow\\,\uparrow\\!{}A^+) \rightarrow A^+ \rightarrow\\,\uparrow\\!A^-$: --&gt;
&lt;!--
$$\lambda f:\\~\\~\downarrow(A^+ \rightarrow\\, \uparrow\\!A^+). \lambda x:A^+.\ \ldots(\mathrm{exercise!})\ldots$$
--&gt;
&lt;p&gt;$$
\begin{array}{l}
\lambda f:\,\downarrow(A^+ \rightarrow\, \uparrow\!A^+). \lambda x:A^+. \\
\mathtt{let\ val}\ y\ =\ (\mathtt{force}\ f)\ x\ \mathtt{in} \\
\mathtt{return}\ (\mathtt{force}\ f)\ y
\end{array}
$$&lt;&#x2F;p&gt;
&lt;p&gt;Note how the intermediary result has a name $y$. (Exercise: what is the type
of this program? If we used an alternative term which didn&#x27;t use $\mathbf{return}$, what
changes?)&lt;&#x2F;p&gt;
&lt;h1 id=&quot;an-interpreter&quot;&gt;An interpreter&lt;&#x2F;h1&gt;
&lt;!--
The let declaration in rule $(\uparrow_E)$ is not merely a convenience for 
local declarations, it is a load-bearing construct of the calculus. In the CBPV book,
it is written $e_1\ \mathtt{to}\ x.\ e_2$. It is very clear that
$e_1$ has to be evaluated and bound to $x$ before any evaluation work
on $e_2$ can begin.

What is maybe less obvious is that instead of the high-level
substitution operation, we only bind and lookup variables. In
particular, there are never any name clashes.
--&gt;
&lt;p&gt;The logical reading of these typing rules is that we have set up a particular kind
of natural deduction calculus. A term that has a type derivation is a proof, and an
introduction followed by an elimitation is clearly a &quot;detour&quot;.
These detours can be removed and these proof normalization steps
correspond to computation steps.&lt;&#x2F;p&gt;
&lt;!--
$$ \mathtt{let\ val}\ x = \mathtt{return}\ s\ \mathtt{in}\ t \longrightarrow_\beta t[x\leftarrow s]$$
$$ \mathtt{force}\ (\mathtt{thunk}\ t) \longrightarrow_\beta t $$
--&gt;
&lt;p&gt;At this point, we can write out local reductions:&lt;&#x2F;p&gt;
&lt;p&gt;$$\begin{array}{ll}
\mathtt{let\ val}\ x\ =\ \mathtt{return}\ V\ \mathtt{in} \mathtt{M} &amp;amp;\rightsquigarrow M[x := V] \\
\mathtt{thunk}\ (\mathtt{force}\ M) &amp;amp;\rightsquigarrow M
\end{array}
$$&lt;&#x2F;p&gt;
&lt;p&gt;This is not what we were after though. Instead, we can define an &lt;em&gt;abstract machine&lt;&#x2F;em&gt;
that specifies exactly which rewriting steps to take when. What is special about
an abstract machine is that unlike an interpreter that recursively traverses
an expression, the machine always operates at a bounded depth from the top.&lt;&#x2F;p&gt;
&lt;p&gt;What follows are transitions rules of a CK machine. Here C stands for control and K is a stack of
contexts.
The source level $\mathbf{let\ val}\ x\ = \_ \ \mathbf{in}\ M$ expression is shortened to $(\_ \ \mathtt{to}\ x. M)$,
and an application where we are waiting for the operator to be evaluated is written $(\_\ V)$.
This gives a simple operational semantics, although a CK machine is still a rather high-level description since
we need to appeal to substitution in the definition.&lt;&#x2F;p&gt;
&lt;p&gt;$$
\begin{array}{llll}
C                                        &amp;amp; K &amp;amp; \rightsquigarrow &amp;amp; C&#x27; &amp;amp; K&#x27; \\
\mathtt{let\ val}\ x = M\ \mathtt{in}\ N &amp;amp; k &amp;amp;                 &amp;amp; M  &amp;amp; (\_ \ \mathtt{to}\ x. N) :: k \\
\mathtt{return}\ V                       &amp;amp; (\_\ \mathtt{to}\ x. M) :: k &amp;amp; &amp;amp; M[x := V] &amp;amp;  k  \\
\mathtt{force} (\mathtt{thunk}\ M)       &amp;amp; k   &amp;amp;   &amp;amp; M   &amp;amp;  k \\
M\ V                                     &amp;amp; k   &amp;amp;   &amp;amp; M   &amp;amp; (\_ \ V) :: k \\
\lambda x. M &amp;amp; (\_ \ V) :: k &amp;amp; &amp;amp; M[x := V] &amp;amp; k
\end{array}
$$&lt;&#x2F;p&gt;
&lt;p&gt;There is a simple idea behind all this which is worth restating: we statically (through the type system) know
that every application $(M\ V)$ comes with an operand that is a value. So:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;whenever we evaluate an application we start by pushing a value (the operand)&lt;&#x2F;li&gt;
&lt;li&gt;when we are done with evaluating the operator and obtain a $\lambda$-term, we can pop a value and continue&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;More precisely, what we push and pop is an application (evaluation context) with
hole in the operator place and an value as operand.
Even though this looks like call-by-value, this subsumes call-by-name because a suspended computation
can be treated as a value. The stack is a list of nested contexts. In a sense,
it is dual to an expression; this can be made precise but we won&#x27;t do this now.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;a-preview-of-the-continuation&quot;&gt;A preview of the continuation&lt;&#x2F;h1&gt;
&lt;p&gt;We started from a natural deduction calculus, which is used for formal logical reasoning, and ended up with an abstract machine.
Unlike rewriting, we have made a step towards a more mechanical, low-level way of normalizing expressions. The fact that the
CK machine is still using substitutions makes it look like we are playing a formal game of symbol manipulation, but if
we could continue from here towards a CEK machine which replaces substitutions with environments.&lt;&#x2F;p&gt;
&lt;p&gt;On the logical side, since we did not discuss products and sums, we are missing conjunction and disjunction. We did not
discuss polarization much. We did not explore classical reasoning, negation, sequent calculus.&lt;&#x2F;p&gt;
&lt;p&gt;We did not talk about effects yet. CBPV gives us a handle on computational effects, similar to monads but different.
It should be obvious how a lean way to specifying evaluation order helps with describing effects.&lt;&#x2F;p&gt;
&lt;p&gt;This is a good time to pause and reflect, before we go to the next round and shed light on some of these topics. In
the meantime, here are some pointers to learn more:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Frank Pfenning&#x27;s 2016 &lt;a href=&quot;https:&#x2F;&#x2F;www.cs.cmu.edu&#x2F;~fp&#x2F;courses&#x2F;15816-f16&#x2F;schedule.html&quot;&gt;lecture notes on substructual logic&lt;&#x2F;a&gt; has a chapter on CBPV.
It ends not with a CK machine, but a specification of operational semantics in an ordered logic
formalism.&lt;&#x2F;li&gt;
&lt;li&gt;CBPV is described in the book &quot;Call-by-Push-Value: A Functional Imperative Synthesis&quot; by Paul Blain Levy. A minor difference is that
we spell out the application context with the value here while in Levy&#x27;s stack only the value gets pushed.&lt;&#x2F;li&gt;
&lt;li&gt;Matthias Felleisen&#x27;s &lt;a href=&quot;https:&#x2F;&#x2F;felleisen.org&#x2F;matthias&#x2F;4400-s20&#x2F;lecture23.html&quot;&gt;lecture notes&lt;&#x2F;a&gt; have a discussion of CK, CEK, CESK machines.
The introduction of environments lets us get rid of substitutions and replace them with environment lookups. This is not yet an
efficient language implementation, but it closes the gap. There is discussion about treating the environment more like a call stack, including
popping unused values. And (for the CESK) there is a discussion on allocating structures.&lt;&#x2F;li&gt;
&lt;li&gt;Bob Harper&#x27;s post on &lt;a href=&quot;https:&#x2F;&#x2F;existentialtype.wordpress.com&#x2F;2012&#x2F;08&#x2F;25&#x2F;polarity-in-type-theory&#x2F;&quot;&gt;polarity in type theory&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Zena M. Ariola, Aaron Bohannon, Amr Sabry. &lt;a href=&quot;https:&#x2F;&#x2F;legacy.cs.indiana.edu&#x2F;~sabry&#x2F;papers&#x2F;sequent.pdf&quot;&gt;Sequent calculi and abstract machines&lt;&#x2F;a&gt; has a
thorough discussion of natural deduction.&lt;&#x2F;li&gt;
&lt;li&gt;Nick Benton, Gavin Bierman, Valeria de Paiva, Martin Hyland. &lt;a href=&quot;https:&#x2F;&#x2F;www.researchgate.net&#x2F;publication&#x2F;2648556_Term_Assignment_for_Intuitionistic_Linear_Logic_Preliminary_Report&quot;&gt;Term Assignment for Intuitionistic Linear Logic&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;!--
Natural deduction as introduced by Gentzen has a normalization theorem: a proof derivation
can be rewritten in a way that it contains no detours. This result is analogous to
cut-elimination result for sequent calculus, but the correspondence is subtle. While
in sequent calculus, we interpret the cut-rule as computation steps, in natural deduction
we have local reductions.

We could also have predefined constants like $\mathtt{plus}: Int^+ \rightarrow Int^+ \rightarrow Int^-$.

Since we are talking about programs, we want to compose computations, that is, build larger computations out of smaller ones.
--&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>about this site and author</title>
        <published>2023-06-12T00:00:00+00:00</published>
        <updated>2023-06-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://burakemir.ch/about/"/>
        <id>https://burakemir.ch/about/</id>
        
        <content type="html" xml:base="https://burakemir.ch/about/">&lt;h3 id=&quot;about-me&quot;&gt;about me&lt;&#x2F;h3&gt;
&lt;p&gt;This is Burak Emir and you are looking at my homepage and blog. I mainly write
about programming languages.  I live in Zurich, Switzerland with my wife and two daughters,
and work at Google as &lt;em&gt;Alchemist of Happiness&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;My professional life started earlier, somewhere during my PhD in Martin Odersky&#x27;s group at EPFL
Lausanne where I worked on Scala and translating pattern matching. At Google, I worked as
engineer and manager on various systems and teams, building backends, distributed systems, middleware.
I then started getting back to programming language related things, and a few years later
joined the org responsible for compilers and language-related infrastructure.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;about-this-site&quot;&gt;about this site&lt;&#x2F;h3&gt;
&lt;p&gt;I am interested in languages, types, logic, systems where one can bridge theory and practice.
Occasionally I write things up. You could call it research, but outside any academic institution.
This site is a place where I keep some notes.&lt;&#x2F;p&gt;
&lt;p&gt;The posts are a way to share what I learnt on programming methods, programming
language technology and occasionally some other topics, like knowledge management
or cybersecurity.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;reach-out&quot;&gt;reach out&lt;&#x2F;h3&gt;
&lt;p&gt;email: first.last@gmail.com&lt;&#x2F;p&gt;
&lt;p&gt;mastodon: &lt;a href=&quot;https:&#x2F;&#x2F;discuss.systems&#x2F;@burakemir&quot; rel=&quot;me&quot;&gt;@burakemir@discuss.systems&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;twitter: @burakemir (dormant)&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>artifacts</title>
        <published>2023-06-12T00:00:00+00:00</published>
        <updated>2023-06-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://burakemir.ch/pages/artifacts/"/>
        <id>https://burakemir.ch/pages/artifacts/</id>
        
        <content type="html" xml:base="https://burakemir.ch/pages/artifacts/">&lt;p&gt;Here are some snapshots from the journey &lt;a href=&quot;https:&#x2F;&#x2F;dblp.uni-trier.de&#x2F;pers&#x2F;hd&#x2F;e&#x2F;Emir:Burak&quot;&gt;(dblp)&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Pattern Matching&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Burak Emir. &lt;a href=&quot;https:&#x2F;&#x2F;infoscience.epfl.ch&#x2F;record&#x2F;109881&quot;&gt;Object-oriented pattern matching.&lt;&#x2F;a&gt;. Thesis, EPFL Lausanne, 2007.&lt;&#x2F;li&gt;
&lt;li&gt;Burak Emir, Martin Odersky, John Williams. &lt;a href=&quot;https:&#x2F;&#x2F;infoscience.epfl.ch&#x2F;record&#x2F;98468&quot;&gt;Matching objects with patterns.&lt;&#x2F;a&gt; ECOOP 2007.&lt;&#x2F;li&gt;
&lt;li&gt;Burak Emir, Qin Ma, Martin Odersky. &lt;a href=&quot;https:&#x2F;&#x2F;infoscience.epfl.ch&#x2F;record&#x2F;108817?ln=en&quot;&gt;Translation Correctness for First-Order Object-Oriented Pattern Matching.&lt;&#x2F;a&gt; APLAS 2007&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Constrained Generics (Universal Polymorphism)&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Burak Emir, Andrew Kennedy, Claudio Russo, Dachuan Yu. &lt;a href=&quot;https:&#x2F;&#x2F;www.microsoft.com&#x2F;en-us&#x2F;research&#x2F;publication&#x2F;variance-and-generalized-constraints-for-c-generics&#x2F;&quot;&gt;Variance and Generalized Constraints for C# generics.&lt;&#x2F;a&gt; ECOOP 2006. I think variance annotations made it to C# 4.0 later.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;arrow-logo&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;I did a few programming courses for kids using LOGO and wrote an interpreter &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;google&#x2F;arrow-logo&quot;&gt;arrow-logo&lt;&#x2F;a&gt; that runs in the browser. Some thoughts on &lt;a href=&quot;https:&#x2F;&#x2F;blog.burakemir.ch&#x2F;2015&#x2F;03&#x2F;educational-programming-environments.html&quot;&gt;educational programming environments for kids&lt;&#x2F;a&gt; on my old blog.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Datalog and Logic Programming&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;I develop and maintain a language called &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;google&#x2F;mangle&quot;&gt;Mangle&lt;&#x2F;a&gt; and its implementation, open-sourced it (Nov 2022). More people need to know datalog.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;&#x2F;mangle-point-in-time-01&quot;&gt;Mangle Point in Time 01&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;&#x2F;mangle-point-in-time-02&quot;&gt;Mangle Point in Time 02&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;odersky-fest-23&quot;&gt;Odersky Fest 2023&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;posts-on-the-old-blog&quot;&gt;posts on the old blog&lt;&#x2F;h3&gt;
&lt;p&gt;The old blog is at &lt;a href=&quot;https:&#x2F;&#x2F;bq9.blogspot.com&quot;&gt;bq9.blogspot.com&lt;&#x2F;a&gt;. Some posts you can find over there:&lt;&#x2F;p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;blog.burakemir.ch&#x2F;2021&#x2F;12&#x2F;worked-example-of-automata-runs-as.html&quot;&gt;(2021) Worked example of automata runs as sheaves&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
  &lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;blog.burakemir.ch&#x2F;2021&#x2F;01&#x2F;what-are-commuting-conversions.html&quot;&gt;(2021) What are Commuting Conversions&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
  &lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;blog.burakemir.ch&#x2F;2020&#x2F;07&#x2F;relating-partial-evaluation-multi-stage.html&quot;&gt;(2020)Relating partial evaluation, multi-stage programming and macros&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
  &lt;li&gt;(2020) Intuitionistic Logic:
  &lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;blog.burakemir.ch&#x2F;2020&#x2F;05&#x2F;intuitionistic-propositional-logic-and.html&quot;&gt;Intuitionistic Propositional Logic and Natural Deduction&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;blog.burakemir.ch&#x2F;2020&#x2F;06&#x2F;kripke-semantics-and-tableaux-for.html&quot;&gt;Kripke semantics and Tableaux for Intuitionistic Logic&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;&lt;&#x2F;ul&gt;&lt;&#x2F;li&gt;
  &lt;li&gt;(2020) Higher-order Logic:
  &lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;blog.burakemir.ch&#x2F;2020&#x2F;04&#x2F;higher-order-logic-and-equality.html&quot;&gt;Higher-order Logic and Equality&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;blog.burakemir.ch&#x2F;2020&#x2F;09&#x2F;intuitionistic-higher-order-logic-and.html&quot;&gt;Intuitionistic Higher-Order Logic and Equality&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;&lt;&#x2F;ul&gt;&lt;&#x2F;li&gt;
  &lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;blog.burakemir.ch&#x2F;2010&#x2F;12&#x2F;yacc-is-of-living-dead.html&quot;&gt;(2010) Yacc is of the Living Dead&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;&lt;&#x2F;ul&gt;&lt;&#x2F;p&gt;
  &lt;&#x2F;root&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>First post</title>
        <published>2023-06-12T00:00:00+00:00</published>
        <updated>2023-06-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://burakemir.ch/post/first-post/"/>
        <id>https://burakemir.ch/post/first-post/</id>
        
        <content type="html" xml:base="https://burakemir.ch/post/first-post/">&lt;h3 id=&quot;a-fresh-start&quot;&gt;a fresh start&lt;&#x2F;h3&gt;
&lt;p&gt;I had to redo these pages. Using &lt;a href=&quot;https:&#x2F;&#x2F;getzola.com&quot;&gt;zola&lt;&#x2F;a&gt; now. Rust, lean, a theme I like, mathjax. My old blog posts are still at &lt;a href=&quot;https:&#x2F;&#x2F;bq9.blogspot.com&quot;&gt;bq9.blogspot.com&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I wanted to like racket and pollen, but kept on forgetting everything absolutely everything.&lt;&#x2F;p&gt;
&lt;p&gt;All I want is to keep some standalone note pages, and some posts, with math and code. Goodness.&lt;&#x2F;p&gt;
&lt;p&gt;$e^{i\pi }+1=0$&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#383838;color:#e6e1dc;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;trait &lt;&#x2F;span&gt;&lt;span&gt;Foo {
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;foo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cc7833;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#6e9cbe;&quot;&gt;Self&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; Bar
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;$$
\begin{prooftree}
\AxiomC{$P$}
\AxiomC{$P\to Q$}
\RightLabel{$(\to_E)$}
\BinaryInfC{$Q$}
\end{prooftree}
$$&lt;&#x2F;p&gt;
</content>
        
    </entry>
</feed>
