<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Gophernment</title>
    <description>The latest articles on DEV Community by Gophernment (@gophernment).</description>
    <link>https://dev.to/gophernment</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4007831%2Fe66b819e-eb2d-4214-91f0-fa9c1204b592.png</url>
      <title>DEV Community: Gophernment</title>
      <link>https://dev.to/gophernment</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gophernment"/>
    <language>en</language>
    <item>
      <title>tmux: เปลี่ยน terminal จอเดียวให้เป็นหลายจอ งานยาว ๆ ก็ไม่หายเมื่อ SSH หลุด</title>
      <dc:creator>Gophernment</dc:creator>
      <pubDate>Fri, 04 Sep 2026 23:20:04 +0000</pubDate>
      <link>https://dev.to/gophernment/tmux-epliiyn-terminal-cchediiywaihepnhlaaycch-ngaanyaaw-kaimhaayemuue-ssh-hlud-1e4p</link>
      <guid>https://dev.to/gophernment/tmux-epliiyn-terminal-cchediiywaihepnhlaaycch-ngaanyaaw-kaimhaayemuue-ssh-hlud-1e4p</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;📅 เขียนเมื่อ: กันยายน 2026 | อ้างอิง tmux 3.7 (stable ตั้งแต่ มิ.ย. 2026)&lt;br&gt;
⚠️ คำสั่งหลักไม่เปลี่ยนมานานหลายปี แต่เช็คเวอร์ชันตัวเองก่อนได้ด้วย &lt;code&gt;tmux -V&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  เรื่องเริ่มจาก SSH หลุดกลางคัน
&lt;/h2&gt;

&lt;p&gt;เคยไหม — นั่ง SSH เข้า server เพื่อรันงานที่กินเวลานาน เช่น build โปรเจกต์, เท database, รันเทสทั้งชุด, หรือ train โมเดล พอเรากด Enter แล้วงานมันวิ่ง... เราก็ทำอย่างอื่นต่อ เผลอตัวไป 10 นาที กลับมาดูอีกทีเจอข้อความประมาณนี้&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Connection to server closed by remote host.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;SSH หลุดตอนไหนไม่รู้ งานที่รันอยู่ตายไปกับมันด้วย เพราะต้องเริ่มใหม่ตั้งแต่ต้น นั่งเฝ้าจอไม่กล้าขยับก็ไม่ได้เรื่อง ไหนจะเวลาทำงานปกติที่ต้องเปิด terminal ทีละหลายจอ — จอหนึ่งไว้แก้โค้ด อีกจอไว้ดู log อีกจอไว้รัน test แล้วก็สลับไปมาไม่ทัน&lt;/p&gt;

&lt;p&gt;สองปัญหานี้มีทางออกตัวเดียว: &lt;strong&gt;tmux&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  tmux คืออะไร กันแน่
&lt;/h2&gt;

&lt;p&gt;tmux (อ่านว่า ti-mux) ย่อมาจาก &lt;strong&gt;terminal multiplexer&lt;/strong&gt; — โปรแกรมที่ทำให้ terminal จอเดียวของคุณกลายเป็น "หลาย terminal" ได้ในตัวเดียว เป็นโปรเจกต์ open source ที่ Nicholas Marriott สร้างและปล่อยครั้งแรกเมื่อปี 2007 แล้วดูแลกันมาเรื่อย ๆ ถึงทุกวันนี้ที่ &lt;a href="https://github.com/tmux/tmux" rel="noopener noreferrer"&gt;github.com/tmux/tmux&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;หลักการทำงานมันประมาณนี้: พอคุณสั่ง &lt;code&gt;tmux&lt;/code&gt; ครั้งแรก มันจะรัน &lt;strong&gt;server&lt;/strong&gt; ตัวหนึ่งขึ้นมาคอยดูแล "หน้าจอ" ทั้งหมดของคุณ โดย server ตัวนี้ &lt;strong&gt;ไม่ได้ผูกติดกับ terminal ที่คุณเปิดอยู่&lt;/strong&gt; — มันรันอยู่เบื้องหลังของเครื่องนั้น ๆ&lt;/p&gt;

&lt;p&gt;นี่คือกุญแจสำคัญของเรื่องทั้งหมด: ใน terminal ปกติ พอ SSH หลุด หรือเราปิดหน้าต่าง terminal กระบวนการที่รันอยู่ในนั้นก็โดนฆ่าตามไปด้วย เพราะมันเป็นลูกของ terminal นั้น แต่กับ tmux พอ SSH หลุด แค่ "จอที่เราใช้ดู" หลุดไป — server กับงานในนั้นยังรันต่อเงียบ ๆ พอ SSH กลับมาใหม่ เราก็แค่ "ต่อจอ" เข้าไปดูงานเดิมที่ยังวิ่งอยู่&lt;/p&gt;

&lt;p&gt;ฟังดูดีใช่ไหม ต่อไปมาดูของใน tmux กันว่ามันแบ่งหน้าจอยังไง&lt;/p&gt;

&lt;h2&gt;
  
  
  session, window, pane — สามชั้นที่ซ้อนกัน
&lt;/h2&gt;

&lt;p&gt;tmux มีโครงสร้าง 3 เลเยอร์ซ้อนกัน:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;session&lt;/strong&gt; — กลุ่มงานหนึ่ง ๆ เช่น session ชื่อ &lt;code&gt;dev-project-a&lt;/code&gt; กับอีก session ชื่อ &lt;code&gt;ops-server&lt;/code&gt; คุณมีกี่ session ก็ได้ แต่ละ session แยกกันเป็นอิสระ&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;window&lt;/strong&gt; — หน้าจอภายใน session เปรียบเหมือนแท็บใน browser: session หนึ่งมีได้หลาย window แล้วสลับไปมา&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;pane&lt;/strong&gt; — การแบ่ง window ออกเป็นช่อง ๆ ให้เห็นพร้อมกันหลายจอ
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─ tmux ────────────────────────────────────────────────┐
│  Session: "dev"  (กลุ่มงานทั้งหมด)                     │
│  ┌─ Window 0: code ─────────┐ ┌─ Window 1: server ──┐ │
│  │  pane 0: vim main.go     │ │  pane 0: ssh prod   │ │
│  │  ─────────────────────── │ └─────────────────────┘ │
│  │  pane 1: go run .        │                          │
│  └──────────────────────────┘                          │
│  [dev] 0:code*  1:server                   14:32       │
└────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;แถบล่างสุดคือ &lt;strong&gt;status bar&lt;/strong&gt; — บอกว่าอยู่ session ไหน (&lt;code&gt;dev&lt;/code&gt;), มี window อะไรบ้าง (ตัวเลข &lt;code&gt;0:code*&lt;/code&gt; ที่มีดอกจันคือ window ที่กำลังดูอยู่), และเวลาปัจจุบัน&lt;/p&gt;

&lt;p&gt;จำง่าย ๆ ว่า &lt;strong&gt;session ใหญ่สุด ครอบ window ครอบ pane&lt;/strong&gt; — session คือ "ห้องทำงาน", window คือ "โต๊ะทำงาน" ที่สลับกันได้, pane คือ "เอกสารที่วางบนโต๊ะเดียวกัน" ให้เห็นพร้อมกัน&lt;/p&gt;

&lt;h2&gt;
  
  
  คำสั่งพื้นฐานที่ใช้จริงทุกวัน
&lt;/h2&gt;

&lt;p&gt;สามคำที่เพิ่งพูดถึง (session, window, pane) จะโผล่ในทุกคำสั่งด้านล่าง และก่อนอื่นต้องติดตั้งให้ได้ก่อน — macOS ใช้ Homebrew ส่วน Ubuntu/Debian (รวม Raspberry Pi OS) ใช้ apt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# macOS&lt;/span&gt;
brew &lt;span class="nb"&gt;install &lt;/span&gt;tmux

&lt;span class="c"&gt;# Ubuntu / Debian / Raspberry Pi OS&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;tmux

&lt;span class="c"&gt;# เช็คว่าได้เวอร์ชันอะไร&lt;/span&gt;
tmux &lt;span class="nt"&gt;-V&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  เริ่ม session แรก
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;tmux new &lt;span class="nt"&gt;-s&lt;/span&gt; dev          &lt;span class="c"&gt;# สร้าง session ใหม่ชื่อ dev แล้วเข้าไปเลย&lt;/span&gt;
tmux &lt;span class="nb"&gt;ls&lt;/span&gt;                  &lt;span class="c"&gt;# (รันนอก session) ดูว่ามี session ไหนรันอยู่บ้าง&lt;/span&gt;
tmux attach &lt;span class="nt"&gt;-t&lt;/span&gt; dev       &lt;span class="c"&gt;# กลับเข้า session ที่ชื่อ dev&lt;/span&gt;
tmux kill-session &lt;span class="nt"&gt;-t&lt;/span&gt; dev &lt;span class="c"&gt;# ปิด session dev ให้สิ้นซาก&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ถ้ารันแค่ &lt;code&gt;tmux&lt;/code&gt; เฉย ๆ ก็ได้ — มันจะตั้งชื่อ session ให้เองแบบสุ่ม แต่การตั้งชื่อเอง (&lt;code&gt;-s dev&lt;/code&gt;) จะทำให้จำง่ายเวลาเจอหลาย session พร้อมกัน&lt;/p&gt;

&lt;h3&gt;
  
  
  ปุ่ม "เรียก" ที่ชื่อ prefix
&lt;/h3&gt;

&lt;p&gt;นี่คือหัวใจของ tmux ที่มือใหม่งงที่สุด: การจะสั่งอะไรใน tmux คุณต้องกด &lt;strong&gt;prefix&lt;/strong&gt; ก่อนทุกครั้ง — ค่า default คือ &lt;code&gt;Ctrl-b&lt;/code&gt; แปลว่ากด &lt;code&gt;Ctrl&lt;/code&gt; ค้างไว้แล้วกด &lt;code&gt;b&lt;/code&gt; พร้อมกัน แล้วปล่อย ตามด้วยปุ่มคำสั่ง เช่น&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;กด &lt;code&gt;Ctrl-b&lt;/code&gt; แล้วกด &lt;code&gt;d&lt;/code&gt; → คำสั่ง &lt;strong&gt;detach&lt;/strong&gt; — หลุดออกจาก session แต่ session ยังรันต่อ&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ลองคิดว่า &lt;code&gt;Ctrl-b&lt;/code&gt; คือ "นี่ฉันจะสั่ง tmux นะ" แล้วปุ่มถัดไปคือ "สั่งอะไร" — เหมือนกด &lt;code&gt;⌘&lt;/code&gt; หรือ &lt;code&gt;Ctrl&lt;/code&gt; แล้วตามด้วยคีย์ลัดนั่นแหละ&lt;/p&gt;

&lt;p&gt;ชุดคำสั่งที่ใช้บ่อยจริง ๆ เก็บไว้แค่นี้:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Ctrl-b d    detach: หลุดออกจาก session แต่ session ยังรันต่อ
Ctrl-b c    สร้าง window ใหม่ (เหมือนเปิดแท็บใหม่)
Ctrl-b 0-9  สลับไป window ที่ 0-9
Ctrl-b ,    ตั้งชื่อ window ปัจจุบัน (เช่น "code", "log")
Ctrl-b %    แบ่ง pane ซ้าย-ขวา
Ctrl-b "    แบ่ง pane บน-ล่าง
Ctrl-b o    กระโดดไป pane ถัดไป
Ctrl-b [    เลื่อนดู history ที่เลื่อนผ่านไปแล้ว (กด q เพื่อออก)
Ctrl-b x    ฆ่า pane ปัจจุบัน
Ctrl-b &amp;amp;    ฆ่า window ปัจจุบัน
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;เทคนิคจำ &lt;code&gt;%&lt;/code&gt; กับ &lt;code&gt;"&lt;/code&gt; ให้ได้: เครื่องหมาย &lt;code&gt;%&lt;/code&gt; มีวงกลมสองวงอยู่ซ้าย-ขวา → ได้ pane ซ้าย-ขวา ส่วน &lt;code&gt;"&lt;/code&gt; เป็นขีดตรงสองขีดเรียงคู่กัน → ได้ pane บน-ล่าง (สังเกตว่าผมเขียนเป็น "ซ้าย-ขวา/บน-ล่าง" ตามผลที่ได้ ไม่ใช่ศัพท์ vertical/horizontal ในเอกสาร — เพราะคนส่วนใหญ่รวมถึงผมตอนแรก งงกับคำนี้ประจำ)&lt;/p&gt;

&lt;p&gt;และปุ่มที่ควรกดเป็นอย่างแรก ๆ คือ &lt;code&gt;Ctrl-b ?&lt;/code&gt; — มันจะโชว์ key binding ทั้งหมดให้ดู ใครลืมอะไรให้กดอันนี้ก่อน&lt;/p&gt;

&lt;h2&gt;
  
  
  สถานการณ์จริง: งานยาว + จอแบ่งครึ่ง
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. SSH รันงานยาว แล้วเดินออกจากจอได้สบาย ๆ
&lt;/h3&gt;

&lt;p&gt;ตัวอย่างจริงที่เจอทุกอาทิตย์ — เข้า server เพื่อรัน migration หรือ train โมเดลที่กินเวลาหลายชั่วโมง:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh user@server
tmux new &lt;span class="nt"&gt;-s&lt;/span&gt; train        &lt;span class="c"&gt;# เปิด session ชื่อ train&lt;/span&gt;
python train.py          &lt;span class="c"&gt;# รันงานยาว ๆ&lt;/span&gt;
Ctrl-b d                 &lt;span class="c"&gt;# detach กลับมาที่ shell ปกติ&lt;/span&gt;
&lt;span class="nb"&gt;logout&lt;/span&gt;                   &lt;span class="c"&gt;# ปิด SSH ได้เลย ไม่ต้องเฝ้า&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ทีนี้ปิด notebook ไปนอนได้เลย พอตื่นมา:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh user@server
tmux attach &lt;span class="nt"&gt;-t&lt;/span&gt; train     &lt;span class="c"&gt;# เห็น output ต่อจากบรรทัดเดิม งานยังวิ่งอยู่!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ความต่างจากเมื่อก่อนคือชัดเจน: ไม่ต้องนั่งเฝ้าจอ ไม่ต้องกลัว wifi หลุด — งานมันอยู่ใต้การดูแลของ tmux server ไม่ใช่ใต้ SSH connection ที่เปราะบางของคุณ&lt;/p&gt;

&lt;h3&gt;
  
  
  2. จอเดียว เห็นทั้งโค้ด ทั้ง log
&lt;/h3&gt;

&lt;p&gt;อีกสถานการณ์ที่ใช้ทุกวัน — แก้บั๊กที่ต้องดู log ประกอบ:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;tmux new &lt;span class="nt"&gt;-s&lt;/span&gt; fixbug       &lt;span class="c"&gt;# เปิด session&lt;/span&gt;
vim main.go              &lt;span class="c"&gt;# แก้โค้ด&lt;/span&gt;
Ctrl-b %                 &lt;span class="c"&gt;# แบ่งจอซ้าย-ขวา&lt;/span&gt;
&lt;span class="c"&gt;# พอ cursor ไปอยู่ฝั่งขวา:&lt;/span&gt;
&lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /var/log/app.log &lt;span class="c"&gt;# ดู log ไหลสด ๆ&lt;/span&gt;
Ctrl-b o                 &lt;span class="c"&gt;# กระโดดกลับไป pane ซ้าย แก้โค้ดต่อ&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ได้ผลลัพธ์แบบนี้ — ฝั่งซ้าย vim, ฝั่งขวา log ไหลสด แก้โค้ดปุ๊บเห็นผลปั๊บ ไม่ต้องสลับหน้าต่างไปมา:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─ pane 0: vim main.go ─────┬─ pane 1: tail -f log ────┐
│ func main() {             │ 14:31:02 request /login  │
│   server.Run()            │ 14:31:02 200 OK (42ms)   │
│ }                         │ 14:31:03 request /pay    │
│                           │ 14:31:03 500 ERROR!      │
└───────────────────────────┴──────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ถ้าอยากให้ pane ไหนเต็มจอชั่วคราว (เช่นอยากจดจ่อกับ vim) กด &lt;code&gt;Ctrl-b z&lt;/code&gt; เพื่อ zoom อีกทีก็กลับมาเป็นจอแบ่งเหมือนเดิม&lt;/p&gt;

&lt;h2&gt;
  
  
  ปรับ .tmux.conf ให้เข้ากับมือ
&lt;/h2&gt;

&lt;p&gt;ทุกครั้งที่เปิด tmux มันจะอ่าน config จากไฟล์ &lt;code&gt;~/.tmux.conf&lt;/code&gt; ที่บ้านคุณ — ไฟล์นี้จะยังไม่มีในเครื่องใหม่ สร้างเองได้เลย นี่คือชุดเริ่มต้นที่เพื่อน ๆ หลายคนใช้กัน (รวมถึงผม) พร้อมคำอธิบายทีละบรรทัด:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# เปลี่ยนปุ่ม "เรียก" จาก Ctrl-b เป็น Ctrl-a&lt;/span&gt;
&lt;span class="c"&gt;# (Ctrl-a อยู่แถว home row กดถนัดกว่า — แต่ถ้าไม่ชินก็ข้าม 3 บรรทัดนี้ไปได้)&lt;/span&gt;
unbind C-b
&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; prefix C-a
&lt;span class="nb"&gt;bind &lt;/span&gt;C-a send-prefix     &lt;span class="c"&gt;# กด Ctrl-a สองที = ส่ง Ctrl-a จริง ๆ ให้โปรแกรมข้างใน&lt;/span&gt;

&lt;span class="c"&gt;# เปิดโหมดเมาส์: คลิกเลือก pane, ลากขอบแบ่งขนาด, เลื่อนดู history เก่า&lt;/span&gt;
&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; mouse on

&lt;span class="c"&gt;# ให้ window และ pane เริ่มนับที่ 1 (เริ่มที่ 0 แล้วงงทุกที)&lt;/span&gt;
&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; base-index 1
setw &lt;span class="nt"&gt;-g&lt;/span&gt; pane-base-index 1

&lt;span class="c"&gt;# เพิ่ม buffer ให้เลื่อนดู history ได้ 5,000 บรรทัด (default 2,000)&lt;/span&gt;
&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; history-limit 5000

&lt;span class="c"&gt;# reload config โดยไม่ต้องออกจาก tmux: กด prefix แล้ว r&lt;/span&gt;
&lt;span class="nb"&gt;bind &lt;/span&gt;r source-file ~/.tmux.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ถ้าแก้ config ตอนที่ยังไม่ได้ bind &lt;code&gt;r&lt;/code&gt; (รอบแรก) ก็ reload มือได้: ใน tmux กด &lt;code&gt;Ctrl-b&lt;/code&gt; ตามด้วย &lt;code&gt;:&lt;/code&gt; พิมพ์ &lt;code&gt;source-file ~/.tmux.conf&lt;/code&gt; แล้ว Enter — หรือง่ายสุดคือออกแล้วเข้า tmux ใหม่ เพราะมันอ่าน config อัตโนมัติทุกครั้งที่เริ่ม&lt;/p&gt;

&lt;p&gt;ข้อควรจำ: ถ้าคุณเปลี่ยน prefix เป็น &lt;code&gt;Ctrl-a&lt;/code&gt; ตาม config ด้านบน คำสั่งทุกอันที่ผมยกตัวอย่างด้วย &lt;code&gt;Ctrl-b&lt;/code&gt; ข้างต้นก็ให้เปลี่ยนเป็น &lt;code&gt;Ctrl-a&lt;/code&gt; ตามไปด้วยทั้งหมด&lt;/p&gt;

&lt;h2&gt;
  
  
  สรุป: เริ่มจาก session เดียวก่อน
&lt;/h2&gt;

&lt;p&gt;tmux อาจดูน่ากลัวตอนแรกเพราะมีปุ่มลัดเยอะ แต่ความจริงคุณไม่ต้องจำทั้งหมด — จุดเริ่มต้นง่าย ๆ แค่เริ่ม session ด้วย &lt;code&gt;tmux new -s &amp;lt;ชื่อ&amp;gt;&lt;/code&gt; จำ &lt;code&gt;Ctrl-b d&lt;/code&gt; ไว้ตอนอยาก detach (งานไม่ตายแน่นอน) กลับมาทีหลังก็ &lt;code&gt;tmux attach -t &amp;lt;ชื่อ&amp;gt;&lt;/code&gt; และที่เหลือถ้าลืมเมื่อไหร่ มี &lt;code&gt;Ctrl-b ?&lt;/code&gt; ไว้เปิดดูคำสั่งทั้งหมดเสมอ&lt;/p&gt;

&lt;p&gt;พอคล่องแล้วค่อยเพิ่ม window, pane, แล้วค่อยปรับ &lt;code&gt;.tmux.conf&lt;/code&gt; — ส่วนผมตอนนี้ เปิด terminal ทีละสิบจอเป็นเรื่องของอดีตไปแล้ว และที่สำคัญกว่านั้น คืนไหนที่ต้องรันงานยาว SSH หลุดตอนไหนก็หลับได้สบาย&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;แหล่งอ้างอิง&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/tmux/tmux" rel="noopener noreferrer"&gt;tmux GitHub repository&lt;/a&gt; — release 3.7 (มิ.ย. 2026) และ CHANGES&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://man.archlinux.org/man/tmux.1" rel="noopener noreferrer"&gt;tmux manual page&lt;/a&gt; — รายละเอียดคำสั่งและ key binding ตามค่า default&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://tmux.info/docs/whats-new" rel="noopener noreferrer"&gt;What's New in tmux&lt;/a&gt; — สรุป feature ใหม่ตั้งแต่ 3.4 เป็นต้นมา&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>tmux</category>
      <category>terminal</category>
      <category>productivity</category>
      <category>linux</category>
    </item>
    <item>
      <title>Generic methods ใน Go 1.27: ฟีเจอร์ที่เคยถูกบอกว่า "ไม่มีทาง" แต่ community ผลักดันจนสำเร็จ</title>
      <dc:creator>Gophernment</dc:creator>
      <pubDate>Tue, 01 Sep 2026 23:14:27 +0000</pubDate>
      <link>https://dev.to/gophernment/generic-methods-ain-go-127-fiiecchrthiiekhythuukbkwaa-aimmiithaang-aet-community-phlakdancchnsamercch-omp</link>
      <guid>https://dev.to/gophernment/generic-methods-ain-go-127-fiiecchrthiiekhythuukbkwaa-aimmiithaang-aet-community-phlakdancchnsamercch-omp</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;📅 เขียนเมื่อ: กันยายน 2026 | Go 1.27&lt;br&gt;
⚠️ API/เวอร์ชันอาจเปลี่ยนแปลง — ตรวจสอบเอกสารล่าสุดก่อนใช้งาน&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;ปลายเดือนสิงหาคมที่ผ่านมา บัญชีทางการของ GoLand โพสต์คลิปวิดีโอสั้น ๆ ความยาว 36 วินาที ของ &lt;strong&gt;Robert Griesemer&lt;/strong&gt; (หนึ่งในผู้ร่วมสร้างภาษา Go) เล่าเบื้องหลังของฟีเจอร์หนึ่ง พร้อมคำถามชวนคิดว่า:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"ทำไมทีม Go ถึงข้าม generic methods ตอน 1.18 แล้วกลับมาใส่ใน 1.27?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;คำตอบสั้น ๆ คือมันเป็นเรื่องราวยาว 5 ปี ที่เริ่มจากทีมออกแบบบอกว่า "ทำไม่ได้/ไม่น่าจะทำ" ไปจนถึงวันที่ community ผลักดันจนฟีเจอร์นี้กลายเป็นจริง — บทความนี้จะเล่าเรื่องนั้นให้ฟัง พร้อมอธิบายว่า generic methods คืออะไร และทำไมมันถึงสำคัญ&lt;/p&gt;

&lt;h2&gt;
  
  
  เกริ่น: Go 1.18 เปิดตัว generics แต่ทิ้งช่องว่างไว้
&lt;/h2&gt;

&lt;p&gt;ย้อนไป &lt;strong&gt;กุมภาพันธ์ 2022&lt;/strong&gt; — Go 1.18 เปิดตัว &lt;strong&gt;generics&lt;/strong&gt; (type parameters) ซึ่งถือเป็นการเปลี่ยนแปลงภาษา Go ครั้งใหญ่ที่สุดครั้งหนึ่ง หลังรอคอยกันมานานหลายปี&lt;/p&gt;

&lt;p&gt;แต่ในดีไซน์นั้นมีข้อจำกัดหนึ่งที่หลายคนสังเกตเห็นทันที: &lt;strong&gt;method ประกาศ type parameters ของตัวเองไม่ได้&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;แปลง่าย ๆ ว่า generics ตอน 1.18 ใช้ได้กับ&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ฟังก์ชันระดับ package: &lt;code&gt;func Max[T cmp.Ordered](a, b T) T&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;และ type: &lt;code&gt;type List[T any] struct { ... }&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;แต่&lt;strong&gt;ใช้กับ method ไม่ได้&lt;/strong&gt; — method ที่ผูกกับ receiver จะรับ type parameters เพิ่มเองไม่ได้ ต้องใช้ type parameters ของ type ต้นทางเท่านั้น&lt;/p&gt;

&lt;h2&gt;
  
  
  Generic methods คืออะไร
&lt;/h2&gt;

&lt;p&gt;ขอทำให้เห็นภาพด้วยตัวอย่างคลาสสิก — สมมติมี &lt;code&gt;List[T]&lt;/code&gt; แล้วอยากได้ method &lt;code&gt;.Map&lt;/code&gt; ที่แปลง element จาก type &lt;code&gt;T&lt;/code&gt; เป็น type &lt;code&gt;U&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;ก่อน Go 1.27 เราทำแบบนี้ได้อย่างเดียว (เป็นฟังก์ชันระดับ package):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;U&lt;/span&gt; &lt;span class="n"&gt;any&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;U&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;U&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;U&lt;/span&gt;&lt;span class="p"&gt;]{}&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// ใช้แบบนี้ — อ่านแล้วต้องไล่จากขวาไปซ้าย&lt;/span&gt;
&lt;span class="n"&gt;mapped&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;strconv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Itoa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ส่วนแบบที่หลายคนอยากได้ — เรียกเป็น method ต่อท้ายแบบ chain อย่างนี้ — &lt;strong&gt;เขียนไม่ได้&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// ❌ ก่อน Go 1.27: method ประกาศ type parameter U เองไม่ได้&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;U&lt;/span&gt; &lt;span class="n"&gt;any&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;U&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;U&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Go 1.27 ทำให้แบบหลังนี้เป็นจริงแล้ว — method ประกาศ type parameters ของตัวเองได้ ซึ่งทำให้เขียน DSL และ chain ของ method ได้สะอาดขึ้นมาก (ตัวอย่างจริงใน standard library คือ &lt;code&gt;math/rand/v2&lt;/code&gt; ที่เปลี่ยนจาก generic function &lt;code&gt;N[Int intType](Int) Int&lt;/code&gt; มาเป็น generic method &lt;code&gt;(*Rand).N[Int intType](Int) Int&lt;/code&gt;)&lt;/p&gt;

&lt;h2&gt;
  
  
  ทำไมตอน 1.18 ถึงข้ามไป
&lt;/h2&gt;

&lt;p&gt;เหตุผลหลักคือ&lt;strong&gt;ความซับซ้อนในการ implement&lt;/strong&gt; ไม่ใช่ "ไม่อยากทำ"&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;เรื่อง dictionary&lt;/strong&gt; — Go implement generics ด้วยการส่ง "type dictionary" ตามไปกับค่า การให้ method มี type parameters เอง แปลว่า dictionary ต้องถูกส่งผ่าน &lt;em&gt;method value&lt;/em&gt; และ &lt;em&gt;interface&lt;/em&gt; ซึ่งซับซ้อนกว่าฟังก์ชันธรรมดามาก&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;คำถามเรื่อง interface&lt;/strong&gt; — ข้อถกเถียงที่ค้างมานาน: ถ้า method มี type parameters แล้วมันจะ "implement interface" ได้ไหม? ถ้าได้ จะตรวจ type ยังไง? ถ้าไม่ได้ แล้วทำไมไม่ใช้ฟังก์ชันธรรมดาแทน?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ประเด็นนี้ชัดเจนจากคอมเมนต์ของ &lt;strong&gt;Ian Lance Taylor&lt;/strong&gt; (ผู้ร่วมออกแบบ generics) ใน proposal วันที่ 21 ตุลาคม 2021:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"This proposal is a non-starter unless someone can explain how to implement it."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;และที่น่าจำคือตอนนั้น &lt;strong&gt;Go FAQ&lt;/strong&gt; ถึงกับเขียนไว้ว่า:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"We do not anticipate that Go will ever add generic methods."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  แล้ว community เปลี่ยนเกมยังไง
&lt;/h2&gt;

&lt;p&gt;แต่สิ่งที่ทีมออกแบบประเมินไว้ต่ำไป คือ&lt;strong&gt;แรงกดดันจากคนใช้งาน&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;proposal ตัวนี้ (golang/go &lt;strong&gt;#49085&lt;/strong&gt;) ถูกเปิดไว้ตั้งแต่วันที่ &lt;strong&gt;20 ตุลาคม 2021&lt;/strong&gt; — สองสามเดือนก่อน Go 1.18 จะออกด้วยซ้ำ — และสะสมความเห็นจากชุมชนไปเรื่อย ๆ จนมี &lt;strong&gt;👍 กว่า 906 ครั้ง&lt;/strong&gt; (ตัวเลขที่สูงมากสำหรับ proposal ภาษา Go)&lt;/p&gt;

&lt;p&gt;use case ที่คนเอามาโชว์กันส่วนใหญ่เป็นเรื่องจริงจัง ไม่ใช่แค่ "อยากได้":&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;DSL สำหรับ stream processing&lt;/strong&gt; — &lt;code&gt;.Map(...).Filter(...)&lt;/code&gt; ต่อเป็น chain แบบที่ไลบรารีด้าน data pipeline ใช้กัน&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DSL สำหรับ testing&lt;/strong&gt; — &lt;code&gt;Assert(actual).ToBe(expected)&lt;/code&gt; อ่านเป็นประโยคได้&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DSL สำหรับ mocking&lt;/strong&gt; — &lt;code&gt;On(obj.Sum).WithArgs(7, 8).ThenReturn(15)&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ทั้งหมดนี้เขียนด้วย method chaining ได้สวย แต่ถ้าไม่มี generic methods จะต้องถอยกลับไปเขียนเป็นฟังก์ชันระดับ package ซึ่งอ่านย้อนหลังและอุ้ยอ้ายกว่า&lt;/p&gt;

&lt;p&gt;เมื่อเวลาผ่านไป 5 ปี คำตอบของคำถามเชิงเทคนิคก็ค่อย ๆ ชัดขึ้น จนในที่สุด &lt;strong&gt;Go 1.27 (สิงหาคม 2026)&lt;/strong&gt; ก็ประกาศรองรับ generic methods อย่างเป็นทางการ — โดยปิด proposal #49085 เดิมเป็น "duplicate" ของ issue &lt;strong&gt;#77273&lt;/strong&gt; ที่ implement จริง&lt;/p&gt;

&lt;p&gt;นี่คือจังหวะที่ Robert Griesemer เล่าในวิดีโอ — ว่าจุดเปลี่ยนจริง ๆ คือ&lt;strong&gt;เสียงตอบรับจาก community&lt;/strong&gt; ที่ยืนกรานว่า use case พวกนี้ "จำเป็น" ไม่ใช่ "ของเล่น"&lt;/p&gt;

&lt;h2&gt;
  
  
  ข้อจำกัดที่ยังเหลือ (สำคัญ)
&lt;/h2&gt;

&lt;p&gt;อย่าเพิ่งดีใจจนลืมอ่าน footnote ใน release notes — Go 1.27 ระบุชัดว่า:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;method ของ &lt;strong&gt;interface&lt;/strong&gt; ยังประกาศ type parameters ไม่ได้&lt;/li&gt;
&lt;li&gt;และ generic method &lt;strong&gt;ไม่สามารถ&lt;/strong&gt; ไป implement interface method ได้&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;แปลว่า generic methods ใช้ได้กับ concrete type (struct ฯลฯ) แต่ยังแตะเรื่อง "generic interface method" ไม่ได้ — นี่คือขอบเขตที่ทีม Go ตั้งใจจำกัดไว้ให้ออกแบบต่อได้ในอนาคต&lt;/p&gt;

&lt;h2&gt;
  
  
  สรุป
&lt;/h2&gt;

&lt;p&gt;เรื่องนี้เป็นกรณีศึกษาที่ดีมากของวิธีที่ Go (ในฐานะภาษา open source) รับมือกับฟีเจอร์ที่ขอเข้ามามาก:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;ตอน 1.18 ทีมออกแบบ&lt;strong&gt;ตัด generic methods ออกอย่างจงใจ&lt;/strong&gt; เพราะ implement ไม่ลงตัวและคำถามเรื่อง interface ยังค้าง&lt;/li&gt;
&lt;li&gt;ชุมชนเปิด proposal (#49085) ยื่น use case จริง และกด 👍 กันเป็นพัน&lt;/li&gt;
&lt;li&gt;ทีมตั้งท่าไว้ก่อน ("non-starter", FAQ บอก "ไม่มีทาง") แต่ก็ไม่ได้ปิดประตูถาวร&lt;/li&gt;
&lt;li&gt;5 ปีต่อมา ปมเชิงเทคนิคถูกแก้ได้จริง → &lt;strong&gt;Go 1.27 ใส่ generic methods เข้ามา&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;ข้อคิดสำหรับคนเขียน Go: ฟีเจอร์ที่ทีมเคยบอกว่า "ไม่น่ามี" ก็มีวันเป็นจริงได้ ถ้า use case มัน "จริง" พอ — และตอนนี้ generic methods ก็พร้อมให้ใช้แล้วใน Go 1.27&lt;/p&gt;




&lt;h3&gt;
  
  
  แหล่งอ้างอิง
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;วิดีโอต้นเรื่อง (GoLand / Robert Griesemer) — &lt;a href="https://x.com/GoLandIDE/status/2094810876565987652" rel="noopener noreferrer"&gt;https://x.com/GoLandIDE/status/2094810876565987652&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Go 1.27 Release Notes (generic methods, issue #77273) — &lt;a href="https://go.dev/doc/go1.27" rel="noopener noreferrer"&gt;https://go.dev/doc/go1.27&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Proposal #49085: allow type parameters in methods — &lt;a href="https://github.com/golang/go/issues/49085" rel="noopener noreferrer"&gt;https://github.com/golang/go/issues/49085&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Type Parameters design doc (no parameterized methods) — &lt;a href="https://go.googlesource.com/proposal/+/refs/heads/master/design/43651-type-parameters.md" rel="noopener noreferrer"&gt;https://go.googlesource.com/proposal/+/refs/heads/master/design/43651-type-parameters.md&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>go</category>
      <category>programming</category>
      <category>generics</category>
    </item>
    <item>
      <title>Aider: AI pair programming ใน terminal — เทียบหมัดต่อหมัดกับคู่แข่ง 5 ตัว</title>
      <dc:creator>Gophernment</dc:creator>
      <pubDate>Sat, 29 Aug 2026 01:25:14 +0000</pubDate>
      <link>https://dev.to/gophernment/aider-ai-pair-programming-ain-terminal-ethiiybhmadthmadkabkhuuaekhng-5-taw-442i</link>
      <guid>https://dev.to/gophernment/aider-ai-pair-programming-ain-terminal-ethiiybhmadthmadkabkhuuaekhng-5-taw-442i</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;📅 เขียนเมื่อ: สิงหาคม 2026 | Aider 0.86.x, Claude Code 2.1.x, OpenAI Codex 0.150.x&lt;br&gt;
⚠️ API/เวอร์ชันอาจเปลี่ยนแปลง — ตรวจสอบเอกสารล่าสุดก่อนใช้งาน&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;ถ้าคุณใช้ AI ช่วยเขียนโค้ดอยู่ตอนนี้ โฟลว์ของหลายคน (รวมถึงผมก่อนหน้านี้) คือเปิดเว็บแชตของ Claude หรือ GPT แล้วก็... ก๊อปโค้ดจาก editor แปะไป ถามว่า "ช่วยแก้บั๊กนี้หน่อย" รอคำตอบ แล้วก็ก๊อปโค้ดกลับมาแปะใน editor วนไปวนมา&lt;/p&gt;

&lt;p&gt;โค้ดยาว ๆ แค่ไฟล์เดียว บางทีต้องก๊อปแปะเป็นสิบรอบ แถม AI ยังไม่เห็น context ของทั้งโปรเจกต์ มันเลยเดาเอาเองว่าไฟล์อื่น ๆ หน้าตาเป็นยังไง แล้วก็ให้โค้ดที่ไม่ตรงกับโค้ดจริงของเรามา&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Aider&lt;/strong&gt; เป็นหนึ่งในเครื่องมือที่แก้ปัญหานี้ — ให้ AI มา "จับคู่เขียนโค้ด" (pair programming) กับคุณ&lt;strong&gt;ใน terminal&lt;/strong&gt; ตรง ๆ บทความนี้จะพาไปรู้จัก Aider แบบละเอียด แล้วปิดท้ายด้วยการเทียบหมัดต่อหมัดกับคู่แข่งสำคัญ 5 ตัว&lt;/p&gt;

&lt;h2&gt;
  
  
  Aider คืออะไร
&lt;/h2&gt;

&lt;p&gt;Aider เป็นโปรแกรม command line ที่คุณเปิดในโฟลเดอร์โปรเจกต์ แล้วแชตกับ AI เพื่อสั่งให้มันแก้โค้ด ความต่างจากเว็บแชตคือ AI จะ&lt;strong&gt;อ่านโค้ดจริงในเครื่องคุณ&lt;/strong&gt; แก้ไฟล์จริง แล้วใช้ git commit การเปลี่ยนแปลงให้ด้วย message ที่สมเหตุสมผล&lt;/p&gt;

&lt;p&gt;ตัวเลขที่ทางโปรเจกต์รายงานไว้: ดาวบน GitHub ราว 44,000 ดวง ติดตั้งไปแล้วกว่า 6.8 ล้านครั้ง ทำงานกับภาษาโปรแกรมได้มากกว่า 100 ภาษา (Python, JavaScript, Go, Rust, Ruby, PHP และอื่น ๆ)&lt;/p&gt;

&lt;h2&gt;
  
  
  เริ่มใช้งานง่าย ๆ
&lt;/h2&gt;

&lt;p&gt;ติดตั้งแค่สองคำสั่ง ตัวแรกติดตั้ง installer แล้วตัวที่สองรันมันเพื่อ setup&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; pip &lt;span class="nb"&gt;install &lt;/span&gt;aider-install
aider-install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ติดตั้งเสร็จ เข้าไปในโฟลเดอร์โปรเจกต์ แล้วเปิด Aider พร้อมระบุโมเดลกับคีย์ API&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /to/your/project

&lt;span class="c"&gt;# ใช้ DeepSeek&lt;/span&gt;
aider &lt;span class="nt"&gt;--model&lt;/span&gt; deepseek &lt;span class="nt"&gt;--api-key&lt;/span&gt; &lt;span class="nv"&gt;deepseek&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;key&amp;gt;

&lt;span class="c"&gt;# ใช้ Claude 3.7 Sonnet&lt;/span&gt;
aider &lt;span class="nt"&gt;--model&lt;/span&gt; sonnet &lt;span class="nt"&gt;--api-key&lt;/span&gt; &lt;span class="nv"&gt;anthropic&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;key&amp;gt;

&lt;span class="c"&gt;# ใช้ o3-mini&lt;/span&gt;
aider &lt;span class="nt"&gt;--model&lt;/span&gt; o3-mini &lt;span class="nt"&gt;--api-key&lt;/span&gt; &lt;span class="nv"&gt;openai&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;key&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;เปิดแล้วจะเข้าสู่หน้าจอแชตใน terminal พิมพ์สั่งงานภาษาไทยหรืออังกฤษก็ได้ เช่น "เพิ่มฟังก์ชัน validate email ในไฟล์นี้" แล้ว Aider จะแก้ไฟล์ให้ พร้อมโชว์ diff ของสิ่งที่เปลี่ยน&lt;/p&gt;

&lt;h2&gt;
  
  
  จุดเด่นของ Aider
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;หนึ่ง — เห็นทั้ง codebase&lt;/strong&gt; Aider สร้าง "แผนที่" ของโปรเจกต์ทั้งก้อน ทำให้มันรู้ว่าไฟล์ไหนเรียกไฟล์ไหน จึงทำงานในโปรเจกต์ใหญ่ได้ดีกว่าการก๊อปโค้ดบางไฟล์ไปให้ AI เดา&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;สอง — git integration&lt;/strong&gt; ทุกครั้งที่ Aider แก้โค้ด มันจะ commit ให้อัตโนมัติด้วย message ที่สมเหตุสมผล ใช้ &lt;code&gt;git diff&lt;/code&gt; หรือ &lt;code&gt;git log&lt;/code&gt; ตรวจย้อนได้เลย&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;สาม — เชื่อม LLM ได้เกือบทุกตัว&lt;/strong&gt; จุดนี้คือสิ่งที่ทำให้ Aider ต่างจากคู่แข่งหลายตัว — มันไม่ผูกกับค่ายใดค่ายหนึ่ง ใช้ Claude, DeepSeek, OpenAI หรือแม้แต่ local model ผ่าน Ollama ก็ได้ เลือกเองตามงานและงบ&lt;/p&gt;

&lt;h2&gt;
  
  
  ข้อควรรู้ก่อนใช้จริง
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;ค่าใช้จ่าย&lt;/strong&gt; — Aider เรียก LLM API โดยตรง ค่ายิง API ตกเป็นของคุณ (เลือกโมเดลให้เหมาะกับงาน)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ตรวจ diff ก่อนเสมอ&lt;/strong&gt; — AI แก้โค้ดเก่งแต่ก็พลาดได้ ดู &lt;code&gt;git diff&lt;/code&gt; ทุกครั้งก่อนปล่อยไป&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;เรื่อง privacy&lt;/strong&gt; — ใช้โมเดล cloud โค้ดจะถูกส่งไปยังผู้ให้บริการนั้น ๆ ถ้ากังวลใช้ local model แทน&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  เทียบหมัดต่อหมัดกับคู่แข่ง 5 ตัว
&lt;/h2&gt;

&lt;p&gt;ทีนี้มาดูภาพรวมตลาด — Aider อยู่ตรงไหนเมื่อเทียบกับตัวเด่น ๆ ทั้ง 5 ตัว&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;มิติ&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Aider&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;Claude Code&lt;/th&gt;
&lt;th&gt;OpenAI Codex&lt;/th&gt;
&lt;th&gt;Cursor&lt;/th&gt;
&lt;th&gt;GitHub Copilot&lt;/th&gt;
&lt;th&gt;Cline&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;รูปแบบ&lt;/td&gt;
&lt;td&gt;terminal CLI&lt;/td&gt;
&lt;td&gt;terminal CLI&lt;/td&gt;
&lt;td&gt;CLI + IDE + web&lt;/td&gt;
&lt;td&gt;AI editor (VS Code fork)&lt;/td&gt;
&lt;td&gt;IDE extension + CLI&lt;/td&gt;
&lt;td&gt;SDK + extension + CLI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;โอเพนซอร์ส&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LLM&lt;/td&gt;
&lt;td&gt;อิสระ (เกือบทุกตัว)&lt;/td&gt;
&lt;td&gt;Claude เป็นหลัก&lt;/td&gt;
&lt;td&gt;OpenAI เป็นหลัก&lt;/td&gt;
&lt;td&gt;หลายค่าย&lt;/td&gt;
&lt;td&gt;GPT + Claude&lt;/td&gt;
&lt;td&gt;อิสระ (พกคีย์มาเอง)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Git commit&lt;/td&gt;
&lt;td&gt;✅ อัตโนมัติ&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅ (ผ่าน editor)&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ติดตั้ง&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pip install aider-install&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;npm i -g @anthropic-ai/claude-code&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;npm i -g @openai/codex&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;โหลด app&lt;/td&gt;
&lt;td&gt;ลง extension&lt;/td&gt;
&lt;td&gt;marketplace / SDK&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ราคา&lt;/td&gt;
&lt;td&gt;ฟรี (จ่าย API เอง)&lt;/td&gt;
&lt;td&gt;subscription / API&lt;/td&gt;
&lt;td&gt;subscription / API&lt;/td&gt;
&lt;td&gt;subscription&lt;/td&gt;
&lt;td&gt;subscription&lt;/td&gt;
&lt;td&gt;ฟรี (จ่าย API เอง)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;เหมาะกับ&lt;/td&gt;
&lt;td&gt;สาย terminal + อยากเลือก LLM เอง&lt;/td&gt;
&lt;td&gt;สาย Claude ล้วน&lt;/td&gt;
&lt;td&gt;สาย OpenAI ล้วน&lt;/td&gt;
&lt;td&gt;อยากได้ editor ทั้งตัว&lt;/td&gt;
&lt;td&gt;ใช้ editor เดิม เสริม AI&lt;/td&gt;
&lt;td&gt;อยากปรับแต่งได้เต็มที่&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;อ่านตารางแล้วจะเห็นภาพชัด: &lt;strong&gt;จุดยืนของ Aider คือ "ตัวเดียวที่ทั้งโอเพนซอร์สและไม่ผูก LLM"&lt;/strong&gt; ข้อดีคืออิสระและโปร่งใส ข้อเสียคือไม่มี editor UI สวย ๆ มาให้ (คุณต้องมี editor เอง) และต้อง setup คีย์ API เอง&lt;/p&gt;

&lt;p&gt;เทียบแบบรวบรัด:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Claude Code&lt;/strong&gt; — แรงและฉลาดมาก แต่ผูกกับ Claude และไม่โอเพนซอร์ส&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OpenAI Codex&lt;/strong&gt; — ระบบนิเวศ OpenAI แน่น แต่ก็ผูก OpenAI เช่นกัน&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cursor&lt;/strong&gt; — ประสบการณ์ editor ดีที่สุด แต่เป็น closed source และเก็บค่าบริการรายเดือน&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Copilot&lt;/strong&gt; — ใช้กับ editor ที่มีอยู่แล้วสะดวก แต่จ่าย subscription และปรับแต่ง LLM ไม่ได้อิสระ&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cline&lt;/strong&gt; — โอเพนซอร์สและยืดหยุ่นพอ ๆ กับ Aider แต่เป็น extension (ไม่ใช่ pure terminal) และพึ่งพา VS Code มากกว่า&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  เลือกยังไง
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;สาย terminal + อยากเลือก LLM เอง + ชอบโอเพนซอร์ส&lt;/strong&gt; → Aider (หรือ Cline ถ้าอยากได้แบบมี UI ใน editor)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ใช้ Claude/OpenAI เจ้าเดียวอยู่แล้ว&lt;/strong&gt; → Claude Code / Codex ตามค่ายที่ใช้&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;อยากได้ editor อัจฉริยะทั้งตัว&lt;/strong&gt; → Cursor&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ใช้ editor เดิม อยากเติม AI แบบไม่ต้องย้ายที่&lt;/strong&gt; → GitHub Copilot&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ไม่มีตัวไหน "ดีที่สุด" แบบสัมบูรณ์ — มันขึ้นกับว่าโฟลว์ของคุณอยู่ที่ไหนอยู่แล้ว และยอมผูกกับค่ายไหนได้แค่ไหน&lt;/p&gt;




&lt;h3&gt;
  
  
  แหล่งอ้างอิง
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Aider — &lt;a href="https://aider.chat/" rel="noopener noreferrer"&gt;https://aider.chat/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Aider Getting Started — &lt;a href="https://aider.chat/#getting-started" rel="noopener noreferrer"&gt;https://aider.chat/#getting-started&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Claude Code — &lt;a href="https://www.anthropic.com/claude-code" rel="noopener noreferrer"&gt;https://www.anthropic.com/claude-code&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;OpenAI Codex — &lt;a href="https://openai.com/codex" rel="noopener noreferrer"&gt;https://openai.com/codex&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Cursor — &lt;a href="https://cursor.com" rel="noopener noreferrer"&gt;https://cursor.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GitHub Copilot — &lt;a href="https://github.com/features/copilot" rel="noopener noreferrer"&gt;https://github.com/features/copilot&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Cline — &lt;a href="https://github.com/cline/cline" rel="noopener noreferrer"&gt;https://github.com/cline/cline&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>AI เขียน Go โบราณตลอด — JetBrains เลยทำ "กติกาการเขียน Go สมัยใหม่" ให้ agent แล้ว</title>
      <dc:creator>Gophernment</dc:creator>
      <pubDate>Wed, 26 Aug 2026 05:52:28 +0000</pubDate>
      <link>https://dev.to/gophernment/ai-ekhiiyn-go-obraantld-jetbrains-elytham-ktikaakaarekhiiyn-go-smayaihm-aih-agent-aelw-2pid</link>
      <guid>https://dev.to/gophernment/ai-ekhiiyn-go-obraantld-jetbrains-elytham-ktikaakaarekhiiyn-go-smayaihm-aih-agent-aelw-2pid</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;📅 เขียนเมื่อ: สิงหาคม 2026 | ครอบคลุม Go 1.0–1.27&lt;br&gt;
⚠️ ข้อมูลอัปเดต ณ วันที่เขียน — เวอร์ชัน/ฟีเจอร์อาจเปลี่ยนตามรอบ release ของ Go&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;ถ้าคุณเคยให้ AI coding agent เขียนโค้ด Go ให้ ลองสังเกตดูว่ามันเขียนออกมาเป็นยังไง ส่วนใหญ่แล้วมันจะเขียนแบบ "รุ่นพ่อ" ออกมา — ใช้ &lt;code&gt;if a &amp;gt; b { return a }&lt;/code&gt; แทนที่จะใช้ &lt;code&gt;max(a, b)&lt;/code&gt;, เขียน loop หา element ทีละตัวแทน &lt;code&gt;slices.Contains&lt;/code&gt;, หรือประกาศตัวแปรชั่วคราวเพื่อเอา pointer แทนที่จะใช้ &lt;code&gt;new(...)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;โค้ดแบบนี้รันได้นะ ไม่ผิดด้วย แต่มันไม่ใช่ Go แบบที่เราเขียนกันในปี 2026 แล้ว และนี่คือปัญหาที่ทีม JetBrains มองเห็น แล้วทำของชิ้นหนึ่งออกมาแก้ตรงจุด — ชื่อว่า &lt;strong&gt;go-modern-guidelines&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ทำไม AI ถึงเขียน Go เก่า ทั้งที่ Go ออกฟีเจอร์ใหม่ตลอด
&lt;/h2&gt;

&lt;p&gt;สาเหตุหลักมีสองอย่าง และมันซ้อนกันอยู่&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;อย่างแรก&lt;/strong&gt; โมเดลภาษาเรียนรู้จากโค้ดบนโลก ซึ่งส่วนใหญ่เขียนขึ้นมาในช่วงหลายปีที่ผ่านมา โค้ด Go เก่า ๆ ที่วนอยู่ใน internet มหาศาลล้วนเป็นสไตล์ "ก่อนจะมีฟีเจอร์ใหม่" ทั้งนั้น โมเดลเลยจับ pattern แบบเก่ามาเป็น default&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;อย่างที่สอง&lt;/strong&gt; Go ออกเวอร์ชันใหม่ทุก ๆ หกเดือน และแต่ละรอบก็มีของเล่นชิ้นเล็ก ๆ เข้ามาเรื่อย ๆ — &lt;code&gt;min&lt;/code&gt;/&lt;code&gt;max&lt;/code&gt; เข้ามาใน Go 1.21, &lt;code&gt;for i := range n&lt;/code&gt; ใน Go 1.22, &lt;code&gt;slices.Collect&lt;/code&gt; ใน 1.23, &lt;code&gt;t.Context()&lt;/code&gt; ใน 1.24, &lt;code&gt;errors.AsType&lt;/code&gt; ใน 1.26, และ &lt;code&gt;encoding/json/v2&lt;/code&gt; ใน 1.27 จังหวะมันไวกว่าที่โมเดลจะตามทัน&lt;/p&gt;

&lt;p&gt;ผลลัพธ์คือ agent เขียนโค้ดที่ "ถูกแต่เชย" แล้วเราก็ต้องมาแก้ทีหลัง — ซึ่งก็คือสิ่งที่ Go team เองก็เห็นเหมือนกัน ถึงขั้นทำ analyzer ชื่อ &lt;code&gt;modernize&lt;/code&gt; เอาไว้ auto-update โค้ดเก่าให้เป็น idiom ใหม่&lt;/p&gt;

&lt;h2&gt;
  
  
  แล้ว JetBrains แก้ยังไง
&lt;/h2&gt;

&lt;p&gt;แทนที่จะรอให้โมเดลฉลาดขึ้นเอง ทีม JetBrains ทำสิ่งที่ตรงไปตรงมากว่ามาก คือเขียน&lt;strong&gt;กติกา&lt;/strong&gt;ให้ agent อ่านแล้วทำตาม&lt;/p&gt;

&lt;p&gt;&lt;code&gt;go-modern-guidelines&lt;/code&gt; เป็น repository ที่รวบรวม guideline 57 ข้อ ครอบคลุมตั้งแต่ Go 1.0 ยัน Go 1.27 แต่ละข้อประกอบด้วย "เขียนแบบนี้ ไม่ใช่แบบนี้" พร้อมโค้ดตัวอย่าง before/after ครบชุด แนวคิดง่าย ๆ คือให้ agent มี reference ที่ชัดเจนแทนที่จะเดาเอาเอง&lt;/p&gt;

&lt;p&gt;ที่สำคัญคือมัน&lt;strong&gt;ไม่ใช่แค่เอกสารอ่านเล่น&lt;/strong&gt; — ตัว guideline นี้ถูกแพ็กเป็น plugin/skill ให้ติดตั้งเข้าไปใน agent ได้ตรง ๆ รองรับทั้ง Junie, Claude Code, Codex, Cursor และ agent อื่น ๆ ผ่าน skills.sh พอติดตั้งแล้ว agent จะเรียกใช้ guideline นี้โดยอัตโนมัติตอนเจองานที่เกี่ยวกับ Go&lt;/p&gt;

&lt;h2&gt;
  
  
  ข้างในมีอะไรน่าสนใจบ้าง
&lt;/h2&gt;

&lt;p&gt;ผมขอหยิบตัวอย่างที่เห็นแล้ว "นี่แหละ ที่ agent มักพลาด" มาให้ดูสักสองสามตัว&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;min&lt;/code&gt; / &lt;code&gt;max&lt;/code&gt; แทนการเทียบเอง (Go 1.21)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// แบบเก่า&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;

&lt;span class="c"&gt;// แบบใหม่&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;slices.Contains&lt;/code&gt; แทน loop หา (Go 1.21)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// แบบเก่า&lt;/span&gt;
&lt;span class="n"&gt;found&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;found&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// แบบใหม่&lt;/span&gt;
&lt;span class="n"&gt;found&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;slices&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;for i := range n&lt;/code&gt; แทนการนับเอง (Go 1.22)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// แบบเก่า&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;doSomething&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// แบบใหม่&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;doSomething&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;errors.AsType&lt;/code&gt; แทน &lt;code&gt;errors.As&lt;/code&gt; แบบเก่า (Go 1.26)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// แบบเก่า&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;MyError&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;As&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// แบบใหม่ — ได้ตัวแปรตรง ๆ ไม่ต้องประกาศไว้ก่อน&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AsType&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;MyError&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;มีอีกเพียบ — &lt;code&gt;clear(m)&lt;/code&gt; ล้าง map, &lt;code&gt;maps.Clone&lt;/code&gt;/&lt;code&gt;maps.Copy&lt;/code&gt;, &lt;code&gt;slices.Sorted&lt;/code&gt; เรียงจาก iterator, &lt;code&gt;sync.OnceValue&lt;/code&gt; สำหรับ memoize, &lt;code&gt;context.AfterFunc&lt;/code&gt; สำหรับ cleanup ตอน cancel ไปจนถึงของใหม่สุดอย่าง generic methods และ &lt;code&gt;encoding/json/v2&lt;/code&gt; ที่เพิ่งเข้าใน Go 1.27&lt;/p&gt;

&lt;h2&gt;
  
  
  ลองใช้ดู
&lt;/h2&gt;

&lt;p&gt;เริ่มใช้งานง่าย ๆ — ถ้าใช้ Claude Code ก็สั่งติดตั้ง marketplace แล้วให้มันโหลด skill นี้เข้าไปได้เลย (คำสั่งติดตั้งครบอยู่ใน README ของ repo) หรือถ้าใช้ agent ตัวอื่นที่รองรับ skills.sh ก็แค่รัน&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx skills add JetBrains/go-modern-guidelines
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;แค่นี้ agent ของคุณก็จะรู้จัก idiom ใหม่ ๆ ของ Go แทนที่จะยึดติดกับสไตล์เก่า ๆ ที่มันจำมาจากโค้ดบน internet&lt;/p&gt;

&lt;h2&gt;
  
  
  สรุป
&lt;/h2&gt;

&lt;p&gt;ปัญหาที่ AI เขียน Go เชย ไม่ใช่เพราะโมเดลโง่ แต่เพราะข้อมูลเทรนเก่ากว่า release ล่าสุดของ Go ทางออกที่ JetBrains เสนอคือการยัด "ความรู้" เข้าไปใน context ของ agent ผ่าน guideline ที่ชัดเจน ซึ่งก็คือสิ่งที่ go-modern-guidelines ทำ — และมันไปทางเดียวกับ &lt;code&gt;modernize&lt;/code&gt; analyzer ของ Go team เป๊ะ&lt;/p&gt;

&lt;p&gt;สำหรับใครที่ปล่อยให้ AI เขียน Go บ่อย ๆ ผมว่านี่เป็น skill ที่คุ้มค่าติดไว้ ไม่ต่างจากใส่ style guide ให้ทีม dev เลย&lt;/p&gt;




&lt;h3&gt;
  
  
  แหล่งอ้างอิง
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;JetBrains/go-modern-guidelines — &lt;a href="https://github.com/JetBrains/go-modern-guidelines" rel="noopener noreferrer"&gt;https://github.com/JetBrains/go-modern-guidelines&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Go team — &lt;code&gt;modernize&lt;/code&gt; analyzer (เครื่องมือ auto-update โค้ด Go เก่าให้เป็น idiom ใหม่)&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>go</category>
      <category>ai</category>
      <category>programming</category>
    </item>
    <item>
      <title>จาก Vibe Coding สู่ Agentic Engineering — SDLC ใหม่ที่กำลังมาแทนที่</title>
      <dc:creator>Gophernment</dc:creator>
      <pubDate>Sun, 16 Aug 2026 11:19:12 +0000</pubDate>
      <link>https://dev.to/gophernment/cchaak-vibe-coding-suu-agentic-engineering-sdlc-aihmthiikamlangmaaaethnthii-4kg5</link>
      <guid>https://dev.to/gophernment/cchaak-vibe-coding-suu-agentic-engineering-sdlc-aihmthiikamlangmaaaethnthii-4kg5</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;📅 เขียนเมื่อ: สิงหาคม 2026 | อ้างอิง: Whitepaper "The New SDLC With Vibe Coding" (พ.ค. 2026)&lt;br&gt;
⚠️ ตัวเลขและเครื่องมือในบทความอาจเปลี่ยนตามเวลา&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;ลองนึกภาพตามนะครับ — เมื่อสิบปีก่อน ถ้าคุณจะเขียนฟีเจอร์ใหม่สักตัว คุณต้องนั่งไล่พิมพ์ syntax ให้ถูกต้องทีละบรรทัด ต้องรู้ว่าวงเล็บปิดตรงไหน semicolon อยู่ตรงไหน แล้วค่อยรันแล้วรอ error มาบอกว่าพิมพ์ผิดตรงไหนอีก&lt;/p&gt;

&lt;p&gt;ตอนนี้ภาพนั้นกำลังหายไปเร็วมาก&lt;/p&gt;

&lt;p&gt;มี whitepaper 51 หน้าเล่มหนึ่งชื่อ &lt;strong&gt;"The New SDLC With Vibe Coding"&lt;/strong&gt; เขียนโดย Addy Osmani, Shubham Saboo และ Sokratis Kartakis ตีพิมพ์บน Kaggle เมื่อเดือนพฤษภาคม 2026 มันพูดถึงเรื่องเดียวที่กำลังเขย่าวงการนักพัฒนา — &lt;strong&gt;การที่เราเปลี่ยนจาก "เขียนโค้ด" เป็น "เขียนเจตนา"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;ตัวเลขที่เปิดมาทีแรกก็ทำเอาสะดุ้ง: ต้นปี 2026 มีนักพัฒนามืออาชีพ &lt;strong&gt;85% ที่ใช้ AI coding agent เป็นประจำ&lt;/strong&gt; ครึ่งหนึ่งใช้ทุกวัน และประมาณ &lt;strong&gt;41% ของโค้ดใหม่ทั้งหมดถูก AI เขียนขึ้นมา&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;แล้วถ้าอยากเห็นภาพชัดที่สุดว่า "วงจรพัฒนาซอฟต์แวร์" (SDLC) เปลี่ยนไปยังไง ดูรูปนี้เลย — ฝั่งซ้ายคือวิธีที่เราทำงานกันมานับสิบปี ฝั่งขวาคือสิ่งที่กำลังมาแทนที่:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fib57rvg4lm3cjsx68pst.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fib57rvg4lm3cjsx68pst.png" alt="การเปรียบเทียบ SDLC แบบเดิม กับ SDLC ที่ขับเคลื่อนด้วย AI" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;เห็นความต่างไหมครับ — ฝั่งซ้ายมนุษย์ต้องทำทุกขั้นตอนเรียงกันไปทีละเฟส แต่ฝั่งขวาเหลือแค่สองจุดที่มนุษย์ต้องอยู่จริง ๆ คือตอน "กำหนดเจตนา" กับตอน "ตรวจสอบคุณภาพ" ส่วนตรงกลางปล่อยให้ AI วน loop ไปเองจนกว่าจะผ่าน&lt;/p&gt;

&lt;p&gt;แต่ก่อนจะไปต่อ ผมอยากให้เราเข้าใจคำหนึ่งให้ตรงกันก่อน เพราะมันเป็นหัวใจของเรื่องทั้งหมด&lt;/p&gt;




&lt;h2&gt;
  
  
  "vibe coding" คำนี้มาจากไหน
&lt;/h2&gt;

&lt;p&gt;เดือนกุมภาพันธ์ 2025 Andrej Karpathy เขียนบรรยายวิธีเขียนโปรแกรมแบบใหม่ที่เขาเรียกว่า vibe coding — แนวคิดคือคุณ "ยอมแพ้ต่อ vibe เต็มตัว แล้วลืมไปเลยว่าโค้ดมีอยู่จริง" คุณแค่บอกสิ่งที่อยากได้เป็นภาษาธรรมดา รับผลลัพธ์จาก AI มาใช้ และถ้ามันพังก็ copy ข้อความ error กลับไปให้ AI แก้ให้&lt;/p&gt;

&lt;p&gt;คำนี้ระเบิดขึ้นมาทันที เพราะมันไปแตะสิ่งที่คนทำกันอยู่เงียบ ๆ มานานแต่ไม่มีคำเรียก&lt;/p&gt;

&lt;p&gt;แต่พอมันดัง คำก็เลยถูกใช้จนความหมายเลอะเทอะ — senior engineer ที่ใช้ AI ช่วย implement ฟีเจอร์ที่ spec ครบถ้วน ก็ถูกเรียก "vibe coding" เหมือนกับคนที่ prompt มั่ว ๆ แล้วยัดโค้ดขึ้น production ไปดื้อ ๆ&lt;/p&gt;

&lt;p&gt;จนกระทั่งต้นปี 2026 Karpathy เองออกมายอมรับว่า framing เดิมมันแคบเกินไป และแนะนำคำใหม่คือ &lt;strong&gt;"agentic engineering"&lt;/strong&gt; สำหรับปลายทางสายที่มีวินัยมากกว่า&lt;/p&gt;




&lt;h2&gt;
  
  
  เส้นแบ่งจริง ๆ ไม่ใช่ "ใช้ AI หรือไม่" แต่อยู่ที่ "ตรวจสอบแค่ไหน"
&lt;/h2&gt;

&lt;p&gt;นี่คือประเด็นที่สำคัญที่สุดของ whitepaper — vibe coding กับ agentic engineering ไม่ใช่สองสิ่งที่แยกขาดจากกัน แต่อยู่บนเส้นเดียวกัน (spectrum) และสิ่งที่แยกสองปลายออกจากกันไม่ใช่เรื่องว่าใช้ AI หรือเปล่า แต่เป็นเรื่องว่า&lt;strong&gt;เราตรวจสอบผลลัพธ์จาก AI มากแค่ไหน&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;ลองไล่ดูทีละมิติ:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;การระบุเจตนา&lt;/strong&gt; — ฝั่ง vibe coding คือพิมพ์ prompt สบาย ๆ ไม่คิดเยอะ ฝั่ง agentic engineering คือมี spec, architecture doc และ memory file ครบถ้วน&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;การตรวจสอบ&lt;/strong&gt; — ฝั่งหนึ่งคือ "เอ๊ะ มันดูใช้ได้มั้ง" อีกฝั่งคือมี test suite, CI/CD gate และ LM judge คอยตรวจ&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;การแก้ error&lt;/strong&gt; — ฝั่งหนึ่ง copy error กลับไปให้ AI เฉย ๆ อีกฝั่งคือคนหาต้นตอให้เจอก่อน แล้วให้ AI implement ฟิกซ์&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;หัวใจจริง ๆ อยู่ที่กลไกตรวจสอบสองตัวที่ทำงานคู่กัน: &lt;strong&gt;tests&lt;/strong&gt; ตรวจส่วนที่ "กำหนดได้" (ฟังก์ชันรับ input นี้ต้องคืน output นั้น) ส่วน &lt;strong&gt;evals&lt;/strong&gt; ตรวจส่วนที่ "กำหนดไม่ได้" (agent เลือกเส้นทางถูกไหม ใช้ tool ถูกไหม ผลลัพธ์ถึงมาตรฐานไหม)&lt;/p&gt;

&lt;p&gt;whitepaper พูดตรง ๆ ว่า &lt;strong&gt;ถ้าไม่มีทั้ง tests และ evals — ต่อให้ prompt เก่งแค่ไหน มันก็ยังเป็น vibe coding อยู่ดี&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;แล้วเราควรยืนตรงไหนของเส้นนี้? คำตอบคือขึ้นกับ "เดิมพัน" ของงาน — prototype ในวันหยุดก็ vibe coding ได้เต็มที่ แต่ API ที่คุมธุรกรรมการเงินต้อง agentic engineering เท่านั้น งานจริงส่วนใหญ่อยู่ตรงกลาง และทักษะที่แท้จริงคือรู้ว่าจะขีดเส้นตรงไหนของแต่ละงาน&lt;/p&gt;




&lt;h2&gt;
  
  
  ทักษะที่แท้จริงไม่ใช่ "prompt" แต่เป็น "context"
&lt;/h2&gt;

&lt;p&gt;มี insight หนึ่งที่ whitepaper ย้ำหลายรอบ และผมว่ามันคือของขวัญที่ดีที่สุดในเล่ม: &lt;strong&gt;คุณภาพของโค้ดจาก AI ไม่ได้ขึ้นกับความฉลาดของ prompt แต่อยู่ที่คุณภาพของ context ที่เราป้อนให้มัน&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;นี่คือที่มาของคำว่า &lt;strong&gt;context engineering&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;ลองคิดแบบนี้ — ถ้าคุณจะให้สมาชิกใหม่มาช่วยเขียนโค้ดในโปรเจกต์ คุณจะไม่ยัดทุกอย่างให้เขารู้ในประโยคเดียว แต่คุณจะให้เขาอ่าน documentation ดู diagram รู้จัก convention ของทีม แล้วค่อยลงมือ&lt;/p&gt;

&lt;p&gt;กับ AI ก็เหมือนกัน มันไม่ได้ต้องการ "คำสั่งที่แต่งมาฉลาด ๆ" แต่มันต้องการ context แบบเดียวกับที่มนุษย์เก่ง ๆ ต้องการถึงจะทำงานดีได้&lt;/p&gt;

&lt;p&gt;context พวกนี้แบ่งเป็นสองชั้นที่สำคัญ:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Static context&lt;/strong&gt; — โหลดตลอดเวลา เช่น &lt;code&gt;AGENTS.md&lt;/code&gt;, &lt;code&gt;CLAUDE.md&lt;/code&gt;, memory ของโปรเจกต์ มันแพง เพราะทุก token อยู่ในทุก interaction ไม่ว่าจำเป็นหรือไม่&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dynamic context&lt;/strong&gt; — โหลดเฉพาะเมื่อต้องการ เช่น skill ที่ถูกเรียกเมื่อ task ตรง, เอกสารที่ดึงจาก RAG, ประวัติ session มันประหยัด เพราะจ่าย token เฉพาะตอนใช้&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;และกุญแจที่ทำให้จัดการสองชั้นนี้ได้คือ &lt;strong&gt;Agent Skills&lt;/strong&gt; — แพ็กเกจความรู้ที่ agent โหลดเฉพาะเมื่องานเรียกใช้ แทนที่จะยัดทุกอย่างลง system prompt ตั้งแต่วินาทีแรก&lt;/p&gt;

&lt;p&gt;ประโยคที่ผมชอบที่สุดในหัวข้อนี้คือ:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;คำถามไม่ใช่ "จะหลอก AI ให้เขียนโค้ดดี ๆ ได้ยังไง" แต่อยู่ที่ "ถ้าจะมีสมาชิกใหม่มาช่วยงาน เขาต้องรู้อะไรบ้าง แล้วเราจะ encode ความรู้นั้นให้ AI ใช้ยังไง"&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  model ไม่ใช่ทุกอย่าง — แนวคิด Harness ที่คนส่วนใหญ่เข้าใจผิด
&lt;/h2&gt;

&lt;p&gt;ตอนนี้ขอเปลี่ยนจังหวะหน่อย เพราะส่วนถัดไปคือจุดที่ผมเห็นคนเข้าใจผิดกันเยอะที่สุด&lt;/p&gt;

&lt;p&gt;เวลาคนใช้ AI coding agent แล้วผลออกมาแย่ สัญชาตญาณแรกของเราคือโทษ model — "model นี้โง่" "รุ่นใหม่ยังไม่เก่ง" แต่ whitepaper บอกว่านั่นคือ intuition ที่ผิด และมันพาเราลงทุนผิดทาง&lt;/p&gt;

&lt;p&gt;ความจริงคือ model เป็นแค่ "เครื่องยนต์" ตัวเดียวในโรงงาน — เครื่องยนต์อย่างเดียวผลิตรถออกมาไม่ได้ ต้องมีสายพาน เฟือง และเซนเซอร์ความปลอดภัยคอยประกอบ&lt;/p&gt;

&lt;p&gt;สิ่งที่ห่อหุ้ม model อยู่รอบ ๆ — prompt, tools, sandbox, sub-agent, observability, guardrails — เรียกรวมว่า &lt;strong&gt;Harness&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Agent = Model + Harness&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;หลักฐานที่ทำให้เรื่องนี้จับต้องได้จริง:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;บน &lt;strong&gt;Terminal Bench 2.0&lt;/strong&gt; มีทีมหนึ่งดัน coding agent จาก&lt;strong&gt;นอก Top 30 ขึ้นไป Top 5&lt;/strong&gt; ได้ โดยเปลี่ยนแค่ harness อย่างเดียว — ไม่เปลี่ยน model เลยแม้แต่ตัวเดียว&lt;/li&gt;
&lt;li&gt;งานวิจัยของ LangChain ยกคะแนน agent บน benchmark เดียวกันขึ้น &lt;strong&gt;13.7 คะแนน&lt;/strong&gt; ด้วยการปรับแค่ system prompt, tools และ middleware รอบ model ที่ fixed ไว้&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;สรุปเป็นประโยคที่ควรแปะไว้หน้ามอนิเตอร์: &lt;strong&gt;เมื่อ agent ทำพลาด อย่าเพิ่งโทษ model — ความจริงส่วนใหญ่คือ configuration ที่พลาด&lt;/strong&gt; ไม่ว่า tool จะหายไป กฎคลุมเครือ guardrail ไม่มี หรือ context เต็มไปด้วย noise&lt;/p&gt;




&lt;h2&gt;
  
  
  ปัญหา 80% — ทำไม AI ยังแทนเราไม่ได้ (และก็ไม่ควร)
&lt;/h2&gt;

&lt;p&gt;แล้วทำไมเราถึงยังต้องการคนอยู่ตรงกลาง? whitepaper เรียกมันว่า &lt;strong&gt;"80% problem"&lt;/strong&gt; — AI สร้างโค้ด 80% แรกของฟีเจอร์ได้เร็วมาก แต่ 20% ที่เหลือ ทั้ง edge case, error handling, จุด integration และ requirement ละเอียดอ่อน ต้องอาศัยความรู้เชิงลึกที่ model ยังไม่มี&lt;/p&gt;

&lt;p&gt;และที่น่ากังวลกว่าคือ nature ของ error มันเปลี่ยนไปแล้ว — จาก "พิมพ์ syntax ผิด" กลายเป็น "เข้าใจ business logic ผิด", "ไม่ถามตอน requirement คลุมเครือ", "พลาด edge case" หรือ "ตัดสินใจ architecture ที่สร้างหนี้ระยะยาว" ซึ่งตรวจจับยากมากเพราะ&lt;strong&gt;โค้ดมันดูถูก และอาจผ่าน test พื้นฐานด้วยซ้ำ&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;ตัวเลขที่หลายคนชอบอ้างว่า AI ทำให้เร็วขึ้น 25–39% ก็ต้องอ่านให้ละเอียด — งานวิจัยของ &lt;strong&gt;METR&lt;/strong&gt; พบว่านักพัฒนาที่มีประสบการณ์ใช้ AI แล้ว&lt;strong&gt;ช้าลง 19%&lt;/strong&gt; ในงานบางประเภท เพราะเวลาโดนกลืนไปกับการตรวจ แก้ และไล่บั๊กโค้ดที่ AI สร้าง&lt;/p&gt;

&lt;p&gt;คนที่ใช้ AI ได้เก่งที่สุดจึงไม่ใช่คนที่รับทุกอย่างที่ AI ยื่นให้ แต่คือคนที่รู้ว่าเมื่อไหร่ควรให้ AI ทำ (งานที่ spec ชัด) และเมื่อไหร่ควรเก็บสมาธิของตัวเองไว้ (requirement คลุมเครือ, trade-off ทาง architecture, การ verify ความถูกต้อง)&lt;/p&gt;




&lt;h2&gt;
  
  
  เงินที่ซ่อนอยู่ใต้ vibe coding
&lt;/h2&gt;

&lt;p&gt;ส่วนนี้สำคัญเป็นพิเศษสำหรับคนที่ต้องตัดสินใจในระดับทีมหรือองค์กร เพราะมันเปลี่ยนมุมมองจาก "เขียนได้เร็วแค่ไหน" เป็น &lt;strong&gt;"ต้นทุนรวมเท่าไหร่"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;vibe coding ดูถูกมากตอนเริ่ม — จ่าย subscription เดือนละไม่กี่ร้อย แล้ว prompt ไปเรื่อย ๆ แต่ whitepaper ชี้ให้เห็นว่ามันมี OpEx ที่แฝงตัวและทบต้นอยู่สามก้อน:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Token burn&lt;/strong&gt; — ยัดไฟล์ก้อนใหญ่แบบไม่มีโครงสร้างเข้า context แล้วให้ AI แก้ผิดซ้ำไปมา วน prompt เผา token เปลือง ๆ&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maintenance tax&lt;/strong&gt; — โค้ดที่เกิดจาก prompt มั่ว ๆ ไม่มีโครงสร้าง พอบั๊กโผล่ทีหลัง 6 เดือน คนต้องนั่ง reverse-engineer "โค้ดสปาเก็ตตี้" กันเป็นวัน ๆ&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security remediation&lt;/strong&gt; — ไม่มี eval harness คุม = สร้างโค้ดเร็ว = สร้างช่องโหว่เร็ว และค่าแก้ช่องโหว่ใน production แพงกว่าตอน design เป็นทวีคูณ&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;ฝั่ง agentic engineering กลับกัน — จ่าย upfront กับการออกแบบ API schema, เขียน test suite, จัดโครงสร้าง context ให้ดีตั้งแต่แรก ซึ่งแพงกว่าในตอนเริ่ม แต่ marginal cost ต่อฟีเจอร์ถัด ๆ ไปลดฮวบ เพราะ AI ทำงานอยู่ใน "โรงงาน" ที่มีกฎคุม output เลยมีโครงสร้าง ผ่าน test และตรง standard&lt;/p&gt;

&lt;p&gt;ส่วน context engineering เองก็กลายเป็นกลยุทธ์การเงินไปโดยปริยาย — LLM คิดเงินทุก token ที่เราส่งไป การยัด repo 100,000 token เข้าทุก prompt คือการเผาเงินแบบไม่จำเป็น และทางแก้คือ &lt;strong&gt;intelligent model routing&lt;/strong&gt;: ใช้ model ใหญ่แพงกับงานที่ซับซ้อน แต่ route งานง่าย ๆ (generate test, code review, CI/CD) ไปให้ model เล็กที่ถูกกว่ามาก&lt;/p&gt;




&lt;h2&gt;
  
  
  แล้วควรเริ่มยังไง
&lt;/h2&gt;

&lt;p&gt;whitepaper ปิดท้ายด้วย checklist ที่เอาไปใช้ได้จริง ผมสรุปเฉพาะตัวที่คิดว่าสำคัญสุดมาให้&lt;/p&gt;

&lt;p&gt;ถ้าคุณเป็น developer เริ่มจากสามอย่างนี้พอ:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ตั้ง &lt;code&gt;AGENTS.md&lt;/code&gt; ให้โปรเจกต์&lt;/strong&gt; — เริ่มจากสิบบรรทัด: stack, convention, กฎตายตัว, workflow แล้วค่อยเพิ่มกฎทุกครั้งที่ agent ทำสิ่งที่ไม่อยากให้ทำซ้ำ&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;เขียน tests + evals ก่อน generate โค้ด&lt;/strong&gt; — มันคือ "สัญญา" กับ AI สื่อเจตนาได้แม่นกว่า prompt ไหน ๆ&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;review ทุกบรรทัดที่จะ ship&lt;/strong&gt; — ระแวงโค้ดที่ "ฉลาดเกินไป" เช็ค import ว่าเป็นแพ็กเกจจริง ตรวจ error handling ให้ครบ&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ถ้าคุณเป็น leader เรื่องสำคัญสุดคือการยกระดับมาตรฐานของทีม:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ทำให้ context engineering เป็น practice ระดับทีม — &lt;code&gt;AGENTS.md&lt;/code&gt;, system prompt และ eval suite ต้องถูก review ใน PR, version กับโปรเจกต์ และมีคนรับผิดชอบชัดเจน&lt;/li&gt;
&lt;li&gt;ตั้งมาตรฐานที่ "eval" ไม่ใช่ "demo" — demo ผ่านแค่แปลว่าทำสำเร็จครั้งเดียว แต่ eval ผ่านแปลว่าทำสำเร็จทุกครั้ง&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ทิ้งท้าย
&lt;/h2&gt;

&lt;p&gt;ถ้าจะย่อ 51 หน้าให้เหลือบรรทัดเดียว ผมขอสรุปแบบนี้:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;เราไม่ได้เลิกเขียนโค้ด — เราแค่เปลี่ยนจาก "เขียน syntax" เป็น "เขียนเจตนา" แล้วปล่อยให้เครื่องจักรรับผิดชอบการ implement ส่วนมนุษย์เก็บงานที่เหลือไว้: การตัดสินใจ รสนิยม และการตรวจว่าของที่ออกมาดีจริง&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;และจุดแบ่งระหว่าง vibe coding ที่น่ากลัว กับ agentic engineering ที่เชื่อถือได้ ไม่ได้อยู่ที่ tool ที่เราเลือกใช้ แต่อยู่ที่ &lt;strong&gt;ว่าเราตั้ง harness รอบ ๆ AI ไว้แน่นแค่ไหน&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;📚 &lt;strong&gt;อ้างอิง:&lt;/strong&gt; The New SDLC With Vibe Coding — Addy Osmani, Shubham Saboo, Sokratis Kartakis (Kaggle, พฤษภาคม 2026)&lt;br&gt;
🔗 อ่านต้นฉบับ: &lt;a href="https://www.kaggle.com/whitepaper-the-new-SDLC-with-vibe-coding" rel="noopener noreferrer"&gt;https://www.kaggle.com/whitepaper-the-new-SDLC-with-vibe-coding&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>productivity</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Goish: พอร์ตรันไทม์ของ Go ทั้งตัวลงใน no_std Rust</title>
      <dc:creator>Gophernment</dc:creator>
      <pubDate>Sat, 15 Aug 2026 02:40:33 +0000</pubDate>
      <link>https://dev.to/gophernment/goish-phrtranaithmkhng-go-thangtawlngain-nostd-rust-4g0n</link>
      <guid>https://dev.to/gophernment/goish-phrtranaithmkhng-go-thangtawlngain-nostd-rust-4g0n</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;📅 เขียนเมื่อ: สิงหาคม 2026 | Goish (goish.cogentica.ai)&lt;br&gt;
⚠️ โปรเจกต์เพิ่งเปิดตัว — รายละเอียด/เวอร์ชันอาจเปลี่ยนแปลง ตรวจสอบจาก GitHub ก่อนใช้งาน&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;ถ้าคุณเขียน Go มาสักพัก คุณน่าจะเคยอยากได้สองอย่างพร้อมกัน — &lt;strong&gt;concurrency model ของ Go&lt;/strong&gt; (goroutine, channel, &lt;code&gt;select&lt;/code&gt;) กับ &lt;strong&gt;ความปลอดภัยด้าน memory ของ Rust&lt;/strong&gt; (ownership, ไม่มี GC) ปกติแล้วสองอย่างนี้อยู่คนละโลก: Go ให้ runtime มาให้แต่มี garbage collector, Rust ให้ ownership มาแต่ concurrency ต้องประกอบเองจาก async/futures&lt;/p&gt;

&lt;p&gt;มีคนพยายามเชื่อมสองโลกนี้เข้าด้วยกันแล้ว — ชื่อโปรเจกต์ว่า &lt;strong&gt;Goish&lt;/strong&gt; ผลงานของ &lt;strong&gt;Chanwit Kaewkasi&lt;/strong&gt; (@chanwit) วิศวกรชาวไทยจากโคราช ภายใต้บริษัท &lt;strong&gt;Cogentica AI&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Goish คืออะไร
&lt;/h2&gt;

&lt;p&gt;นิยามสั้น ๆ ที่เจ้าตัวเขียนไว้ในหน้าแรก: &lt;em&gt;"A Rust runtime for Go people"&lt;/em&gt; — รันไทม์ของ Go สำหรับคนที่เขียน Go&lt;/p&gt;

&lt;p&gt;ถ้าขยายให้ละเอียด: Goish คือการ&lt;strong&gt;พอร์ต standard library และ runtime ของ Go 1.25 ลงไปใน Rust แบบ &lt;code&gt;no_std&lt;/code&gt;&lt;/strong&gt; — ไม่พึ่ง glibc, ไม่พึ่ง std ของ Rust, ไม่พึ่ง Tokio, ไม่มี garbage collector มัน ship ทุกอย่างมาเองตั้งแต่ &lt;code&gt;_start&lt;/code&gt;, page allocator, size-class heap, M:N scheduler, channel, &lt;code&gt;select!&lt;/code&gt;, sync primitives, ไปจนถึง &lt;code&gt;net/http&lt;/code&gt; และ &lt;code&gt;crypto/tls&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;ผลลัพธ์คือ &lt;strong&gt;binary ไฟล์เดียวแบบ static&lt;/strong&gt; เหมือน Go — &lt;code&gt;ldd&lt;/code&gt; รันแล้วบอกว่า &lt;em&gt;"not a dynamic executable"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;แต่สิ่งที่ทำให้ Goish ต่างจากโปรเจกต์ "เขียน Go ให้เป็น Rust" ทั่วไป คือ&lt;strong&gt;วิธีที่มันให้เครดิตกับต้นทาง&lt;/strong&gt; — เรื่องนี้แหละคือหัวใจของที่มาที่ไป&lt;/p&gt;




&lt;h2&gt;
  
  
  ทำไมถึงคิดทำตัวนี้ (ที่มาที่ไป)
&lt;/h2&gt;

&lt;p&gt;แรงจูงใจหลักไม่ใช่ "อยากให้ Rust เขียนง่ายเหมือน Go" ธรรมดา ๆ แต่เป็นเรื่องของ &lt;strong&gt;compliance และ provenance&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;ลองนึกภาพ: ทีมคุณเขียน Go อยู่ แล้วต้องย้ายไป Rust (ด้วยเหตุผลเรื่อง memory safety หรือนโยบายบริษัท) ระหว่างทางคุณต้อง "พอร์ต" โค้ด — เอาโค้ดจาก Go มาเขียนใหม่เป็น Rust แล้วคำถามสำคัญก็ผุดขึ้น:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;AES-GCM ใน binary ตัวนี้ เป็น implementation ที่ Go review แล้ว หรือเป็นของที่เราเขียนประมาณเอา?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;เครื่องมือ supply-chain ยุคปัจจุบันอย่าง &lt;strong&gt;SLSA provenance&lt;/strong&gt; หรือ &lt;strong&gt;SBOM&lt;/strong&gt; ตอบคำถามนี้ไม่ได้ — มันอธิบายแค่ว่า binary ถูก build มาจากไหน (builder ไหน, commit อะไร, digest อะไร) แต่&lt;strong&gt;อธิบายไม่ได้ว่าโค้ดข้างในถูก port มาอย่างซื่อสัตย์แค่ไหน&lt;/strong&gt; SBOM จะบันทึกว่า "goish 0.1.0" แล้วจบ — มันแยกไม่ออกว่า crypto ในนั้นคือของจริงหรือของก๊อป&lt;/p&gt;

&lt;p&gt;Goish แก้ด้วยการ&lt;strong&gt;บันทึกที่มาเป็นฟังก์ชันต่อฟังก์ชัน&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// go: sdk 1.25.5 crypto/internal/fips140/aes/gcm/gcm.go:31-46 newGCM&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;บรรทัดนี้เขียนไว้เหนือ port แต่ละตัว — บอกว่าโค้ดตรงนี้ port มาจากไฟล์ไหน บรรทัดไหน ใน Go 1.25.5 และมี CI ที่&lt;strong&gt;เปิด Go tree ขึ้นมาเช็คทุก commit&lt;/strong&gt; ว่าตำแหน่งที่อ้างยังถูกต้องอยู่&lt;/p&gt;

&lt;p&gt;ทำไมเรื่องนี้ถึงสำคัญ&lt;strong&gt;ตอนนี้&lt;/strong&gt;? เพราะเส้นตายทางกฎหมายกำลังมา:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;วันที่&lt;/th&gt;
&lt;th&gt;เกิดอะไรขึ้น&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;11 ก.ย. 2026&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;EU CRA (Cyber Resilience Act) บังคับใช้ภาระการรายงาน — แจ้งเตือน 24 ชม. / แจ้งเต็ม 72 ชม. เมื่อเจอช่องโหว่ที่ถูกโจมตีจริง&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;21 ก.ย. 2026&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;ใบรับรอง FIPS 140-2 ย้ายเข้า "Historical List" — ใช้ต่อได้แต่ justify การจัดซื้อภาครัฐใหม่ไม่ได้&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;1 ม.ค. 2027&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;CNSA 2.0 กลายเป็นค่าเริ่มต้นสำหรับงาน NSS ของสหรัฐฯ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;11 ธ.ค. 2027&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;ข้อกำหนดสำคัญของ CRA รวมถึง mandate เรื่อง machine-readable SBOM&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;พูดง่าย ๆ: &lt;strong&gt;ถ้าสินค้าคุณต้องผ่าน compliance พวกนี้ คุณต้องพิสูจน์ได้ว่าโค้ดทุกบรรทัดมาจากไหน&lt;/strong&gt; — และสำหรับโค้ดที่ "แปล" มาจากที่อื่น การพิสูจน์นั้นต้องลงถึงระดับฟังก์ชัน ไม่ใช่ระดับ build&lt;/p&gt;

&lt;p&gt;นี่คือเหตุผลที่ Goish เกิด&lt;/p&gt;




&lt;h2&gt;
  
  
  ใช้เทคนิคอะไรบ้าง
&lt;/h2&gt;

&lt;p&gt;ส่วนนี้คือความเจ๋งทางวิศวกรรม — ถ้าไม่อยากอ่านเชิงลึก ข้ามไปหัวข้อถัดไปได้เลย&lt;/p&gt;

&lt;h3&gt;
  
  
  1. M:N Scheduler — พอร์ตแบบ verbatim จาก &lt;code&gt;runtime/proc.go&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Goish ไม่ได้ "เขียน scheduler ใหม่ให้คล้าย Go" — มัน&lt;strong&gt;แปล &lt;code&gt;runtime/proc.go&lt;/code&gt; ของ Go 1.25 มาทีละบรรทัด&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Per-P run queue แบบ lock-free SPMC (256 entry) + global overflow&lt;/li&gt;
&lt;li&gt;Work stealing แบบ coprime-permuted (&lt;code&gt;runqgrab&lt;/code&gt; / &lt;code&gt;runqsteal&lt;/code&gt; / &lt;code&gt;stealOrder&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Async preemption ผ่าน &lt;strong&gt;SIGURG&lt;/strong&gt; (เทคนิคเดียวกับที่ Go ใช้หยุด goroutine ที่รันนานเกิน)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;sysmon&lt;/code&gt; ตัวจัดการ timer heap + force-preempt&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;epoll netpoller แบบ per-P&lt;/strong&gt; (โมเดลเดียวกับ nginx) — เวลา goroutine รอ I/O มันจะ park goroutine ไม่ใช่ block thread&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Memory: page allocator + 67 size classes (แต่ไม่มี GC)
&lt;/h3&gt;

&lt;p&gt;Goish เอา&lt;strong&gt;โครงสร้าง allocator ของ Go&lt;/strong&gt; (mheap → mcentral → per-P mcache, 67 size classes) มาใช้ แต่&lt;strong&gt;ตัด garbage collector ออก&lt;/strong&gt; — ให้ Rust ownership เป็นคน reclaim แทน&lt;/p&gt;

&lt;p&gt;สำหรับ stack ของ goroutine มันใช้วิธีฉลาด: goroutine หนึ่งตัวได้ virtual reservation &lt;strong&gt;1 MiB&lt;/strong&gt; แบบ lazy-commit (kernel ค่อย commit หน้า 4 KiB เมื่อถูกแตะจริง) — แปลว่า goroutine ที่ทำงานตื้น ๆ เสีย memory จริงแค่ประมาณหนึ่ง page และถ้าอยากได้ความหนาแน่นสุดขีด ก็ใช้ &lt;code&gt;go!(stack(2*KB), …)&lt;/code&gt; เพื่อขอ stack ขนาด 2 KiB จาก stack pool&lt;/p&gt;

&lt;p&gt;ผลลัพธ์ตาม demo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ts  vmsize_kb  vmrss_kb  vmpeak_kb  vmhwm_kb  threads
 0s    1105148      44800    1108444      49024   13   ← baseline
 2s    3069660    2406528    3069660    2406528   13   ← 1M parked
30s    3069660    2406528    3069660    2406528   13   ← steady-state
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;goroutine หนึ่งล้านตัว บน OS thread แค่ 13 เธรด&lt;/strong&gt; — ~2.4 KiB RSS ต่อ goroutine&lt;/p&gt;

&lt;h3&gt;
  
  
  3. เขียนโค้ดที่ "อ่านแล้วเหมือน Go" แต่ compile ด้วย rustc
&lt;/h3&gt;

&lt;p&gt;จุดเด่นที่สุดสำหรับคนเขียน Go — public API ใช้ &lt;strong&gt;type ตัวพิมพ์เล็กแบบ Go&lt;/strong&gt; แทน type ของ Rust:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;http&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;Sprintf!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"get %s: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;io&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;ReadAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="py"&gt;.Body&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;io&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Closer&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="py"&gt;.Body&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="py"&gt;.StatusCode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="py"&gt;.Header&lt;/span&gt;&lt;span class="nf"&gt;.Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Content-Type"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;string&lt;/code&gt;, &lt;code&gt;int&lt;/code&gt;, multi-return, &lt;code&gt;if err != nil&lt;/code&gt; — ทั้งหมดคือ Rust จริง ๆ ที่ &lt;code&gt;rustc&lt;/code&gt; compile ได้ แต่&lt;strong&gt;อ่านแล้วแทบไม่ต่างจาก Go&lt;/strong&gt; และ &lt;code&gt;Vec&amp;lt;u8&amp;gt;&lt;/code&gt; กับ &lt;code&gt;&amp;amp;str&lt;/code&gt; ไม่โผล่ใน signature สาธารณะเลย&lt;/p&gt;

&lt;p&gt;นี่คือ philosophy หลัก: &lt;strong&gt;"Port first, get idiomatic later"&lt;/strong&gt; — พอร์ตโค้ด Go มาแบบเกือบ line-by-line ก่อน แล้วค่อย ๆ ปรับเป็น Rust idiom ทีละ module เมื่อทีมพร้อม&lt;/p&gt;

&lt;h3&gt;
  
  
  4. crypto/tls — พอร์ตครบ 100% พร้อมใบเสร็จทุกบรรทัด
&lt;/h3&gt;

&lt;p&gt;ส่วนที่ภาคภูมิใจที่สุดคือ &lt;code&gt;crypto/&lt;/code&gt; — &lt;strong&gt;ครบ 1722/1722 declarations (100%) ทั้ง 66 packages&lt;/strong&gt; รวมถึง &lt;code&gt;crypto/internal/fips140*&lt;/code&gt; ทั้ง 35 packages ที่เป็น code path ของ FIPS validation และ &lt;code&gt;net/http&lt;/code&gt; ครบ &lt;strong&gt;639/639 functions (100%)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;TLS 1.3 ที่รันจริงคือ &lt;code&gt;crypto/tls&lt;/code&gt; ที่ port มา verbatim — ไม่ใช่ implementation ใหม่ที่เขียนเลียนแบบ&lt;/p&gt;




&lt;h2&gt;
  
  
  ประโยชน์ที่ได้
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Binary เดียว ไม่มี libc ไม่มี ld.so&lt;/strong&gt; — ลด attack surface เหลือแค่ตัว binary เอง เหมาะกับ &lt;code&gt;scratch&lt;/code&gt;/distroless container, confidential VM, appliance image&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory safety + concurrency model ของ Go&lt;/strong&gt; — ได้ ownership ของ Rust (ไม่มี dangling pointer, ไม่มี data race) กับ goroutine/channel/select ของ Go ในตัวเดียว&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Provenance ถึงระดับฟังก์ชัน&lt;/strong&gt; — พิสูจน์ compliance (EU CRA, FIPS, CNSA) ได้ เพราะทุกฟังก์ชันมีที่มาอ้างอิง&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ไม่มี GC ให้ tune&lt;/strong&gt; — ไม่มี stop-the-world ไม่มี GC pause&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;เส้นทาง migrate จาก Go → Rust แบบค่อยเป็นค่อยไป&lt;/strong&gt; — ไม่ต้องหยุดทุกอย่างเพื่อ rewrite ใหม่หมด&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  วิธีเริ่มต้น
&lt;/h2&gt;

&lt;p&gt;ต้องการแค่ &lt;strong&gt;Rust 1.79+&lt;/strong&gt; และ &lt;strong&gt;Linux x86_64&lt;/strong&gt; (single-target ณ ตอนนี้)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/cogentica-ai/goish
&lt;span class="nb"&gt;cd &lt;/span&gt;goish

&lt;span class="c"&gt;# build library&lt;/span&gt;
cargo build &lt;span class="nt"&gt;--target&lt;/span&gt; x86_64-unknown-linux-gnu &lt;span class="nt"&gt;--release&lt;/span&gt;

&lt;span class="c"&gt;# demo: หนึ่งล้าน goroutine&lt;/span&gt;
cargo build &lt;span class="nt"&gt;--target&lt;/span&gt; x86_64-unknown-linux-gnu &lt;span class="nt"&gt;--release&lt;/span&gt; &lt;span class="nt"&gt;--example&lt;/span&gt; spawn_million
./examples/spawn_million.sh

&lt;span class="c"&gt;# goginx: nginx clone ที่เขียนด้วย goish&lt;/span&gt;
cargo build &lt;span class="nt"&gt;--target&lt;/span&gt; x86_64-unknown-linux-gnu &lt;span class="nt"&gt;--release&lt;/span&gt; &lt;span class="nt"&gt;--example&lt;/span&gt; goginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;โค้ด "Hello" แบบ Goish หน้าตาประมาณนี้:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;goish&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;go&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nd"&gt;#[goish::main]&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;go!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;move&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nn"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;Println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hello from a goroutine"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  ข้อจำกัด (บอกตรง ๆ)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ยังไม่ใช่ Go compiler&lt;/strong&gt; — คุณเขียน Rust ที่อ่านเหมือน Go ไม่ได้ compile ไฟล์ &lt;code&gt;.go&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Linux x86_64 เท่านั้น&lt;/strong&gt; — target อื่นยังไม่อยู่ใน scope&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ยังไม่ผ่าน security audit&lt;/strong&gt; — TLS stack port มาแบบ machine-checked แต่ยังไม่มี external review (ดู SECURITY.md ก่อนใช้จริง)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ยัง port ไม่ครบทั้ง Go&lt;/strong&gt; — &lt;code&gt;crypto/&lt;/code&gt; กับ &lt;code&gt;net/http&lt;/code&gt; เสร็จแล้ว แต่ &lt;code&gt;net&lt;/code&gt;, &lt;code&gt;encoding&lt;/code&gt;, &lt;code&gt;os&lt;/code&gt; ยังบางส่วน&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  สรุป
&lt;/h2&gt;

&lt;p&gt;Goish ไม่ได้เป็นแค่ "Go runtime ใน Rust" — มันเป็นความพยายามตอบคำถามที่ใหญ่กว่านั้น: &lt;strong&gt;เมื่อเราต้องย้ายภาษาในโลกที่มีกฎหมายบังคับเรื่องที่มาของโค้ด เราจะพิสูจน์ได้ยังไงว่าโค้ดทุกบรรทัดไว้ใจได้&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;คำตอบของ Chanwit คือการพอร์ต Go แบบมี "ใบเสร็จ" ทุกบรรทัด แล้วเอา ownership ของ Rust มาแทน GC — ได้ทั้งความคุ้นเคยของ Go, ความปลอดภัยของ Rust, และหลักฐาน compliance ที่ตรวจซ้ำได้&lt;/p&gt;

&lt;p&gt;โปรเจกต์นี้เพิ่งเปิด (สิงหาคม 2026) และยังพัฒนาอย่างต่อเนื่อง ถ้าสนใจเข้าไปดูได้ที่:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🌐 &lt;a href="https://goish.cogentica.ai" rel="noopener noreferrer"&gt;https://goish.cogentica.ai&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;💻 &lt;a href="https://github.com/cogentica-ai/goish" rel="noopener noreferrer"&gt;https://github.com/cogentica-ai/goish&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;เครดิต:&lt;/strong&gt; บทความนี้อ้างอิงข้อมูลจากเว็บไซต์ goish.cogentica.ai และ README ของ github.com/cogentica-ai/goish — โปรเจกต์โดย &lt;strong&gt;Chanwit Kaewkasi&lt;/strong&gt; (@chanwit) ภายใต้ &lt;strong&gt;Cogentica AI&lt;/strong&gt; (ประเทศไทย)&lt;/p&gt;

&lt;p&gt;⚠️ Goish ไม่เกี่ยวข้องกับ Google หรือ Go project — "Go" เป็นเครื่องหมายการค้าของ Google LLC&lt;/p&gt;

</description>
      <category>go</category>
      <category>rust</category>
      <category>concurrency</category>
      <category>opensource</category>
    </item>
    <item>
      <title>REPL — วิธีคุยกับคอมพิวเตอร์ที่ LISP สอนโลก</title>
      <dc:creator>Gophernment</dc:creator>
      <pubDate>Wed, 05 Aug 2026 10:14:29 +0000</pubDate>
      <link>https://dev.to/gophernment/repl-withiikhuykabkhmphiwetrthii-lisp-snolk-31dg</link>
      <guid>https://dev.to/gophernment/repl-withiikhuykabkhmphiwetrthii-lisp-snolk-31dg</guid>
      <description>&lt;p&gt;คุณเคยนึกไหมว่าก่อนที่จะมี &lt;code&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/code&gt; ใน Python,&lt;br&gt;
ก่อน &lt;code&gt;node&lt;/code&gt; console,&lt;br&gt;
ก่อน Chrome DevTools —&lt;/p&gt;

&lt;p&gt;การคุยกับคอมพิวเตอร์มันเป็นยังไง?&lt;/p&gt;

&lt;p&gt;คำตอบคือ... &lt;strong&gt;คุณไม่ได้คุยกับมัน&lt;/strong&gt; คุณเขียนโปรแกรมทั้งก้อนบน punch card, ยัดเข้าเครื่อง, รอ output ออกมา, แล้วค่อยรู้ว่ามี bug หรือเปล่า&lt;/p&gt;

&lt;p&gt;REPL เปลี่ยนทั้งหมดนั้น&lt;/p&gt;
&lt;h2&gt;
  
  
  READ → EVAL → PRINT → LOOP
&lt;/h2&gt;

&lt;p&gt;REPL ย่อมาจาก &lt;strong&gt;Read-Eval-Print Loop&lt;/strong&gt; — วงจรง่าย ๆ สี่ขั้นตอน:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. READ   — อ่านสิ่งที่คุณพิมพ์
2. EVAL   — ประมวลผลมัน
3. PRINT  — แสดงผลลัพธ์
4. LOOP   — กลับไปรอ input ถัดไป
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;วงจรนี้เกิดจาก LISP ในทศวรรษ 1960s — &lt;code&gt;read&lt;/code&gt;, &lt;code&gt;eval&lt;/code&gt;, และ &lt;code&gt;print&lt;/code&gt; คือ primitive function สามตัวของภาษา&lt;/p&gt;

&lt;p&gt;เวลาเราเฉลิมฉลอง LISP เรามักพูดถึง garbage collection, lambda, macro — แต่ REPL ต่างออกไป&lt;/p&gt;

&lt;p&gt;REPL ไม่ใช่ "feature"... มันคือ &lt;strong&gt;วิธีคิด&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ก่อน REPL: ยุคที่คอมพิวเตอร์ไม่คุยกับคุณ
&lt;/h2&gt;

&lt;p&gt;ลองนึกภาพ programmer ปี 1965:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;เขียนโค้ดบนกระดาษ&lt;/li&gt;
&lt;li&gt;เจาะ punch card&lt;/li&gt;
&lt;li&gt;ยื่นให้ operator&lt;/li&gt;
&lt;li&gt;รอคิว (อาจเป็นชั่วโมง หรือเป็นวัน)&lt;/li&gt;
&lt;li&gt;เครื่องรัน&lt;/li&gt;
&lt;li&gt;ได้ output&lt;/li&gt;
&lt;li&gt;เจอ bug — กลับไปข้อ 1&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;นี่คือ &lt;strong&gt;batch processing&lt;/strong&gt; — ทั้งวงการเป็นแบบนี้&lt;/p&gt;

&lt;p&gt;ลองเทียบกับวันนี้: คุณพิมพ์ &lt;code&gt;2 + 2&lt;/code&gt; → enter → &lt;code&gt;4&lt;/code&gt; ปรากฏในเสี้ยววินาที&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;REPL ทำให้วงจร feedback จาก "เป็นวัน" เหลือ "เป็นวินาที"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;นี่คือการเปลี่ยน paradigm ที่ใหญ่กว่า feature ใด ๆ ที่ LISP คิด — มันเปลี่ยนวิธีที่มนุษย์ interact กับคอมพิวเตอร์ จาก "สั่งแล้วรอ" เป็น "สนทนา"&lt;/p&gt;

&lt;h2&gt;
  
  
  กำเนิดในห้องแล็บ AI ของ MIT
&lt;/h2&gt;

&lt;p&gt;read-eval-print loop ไม่ได้เกิดจาก philosophy หรือ manifesto — มันเกิดจากความจำเป็น&lt;/p&gt;

&lt;p&gt;AI researchers ที่ MIT กำลังเขียนโปรแกรมที่ต้องลองผิดลองถูกตลอดเวลา เขียนโปรแกรมทั้งก้อนไม่ได้ — เพราะยังไม่รู้ด้วยซ้ำว่าอยากให้มันทำอะไร&lt;/p&gt;

&lt;p&gt;พวกเขาต้องการ &lt;strong&gt;ทดลองทีละ expression&lt;/strong&gt; — เห็นผลลัพธ์ทันที แล้วปรับสมมติฐาน&lt;/p&gt;

&lt;p&gt;LISP — ด้วยความที่ทุกอย่างเป็น expression, ทุก expression ให้ผลลัพธ์ — เหมาะกับวิธีนี้อย่างเป็นธรรมชาติ&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;คำว่า "read-eval-print loop" ปรากฏครั้งแรกใน MACLISP Reference Manual (1974, David Moon)&lt;br&gt;
แต่หลักการนี้ถูกใช้จริงมาตั้งแต่ LISP I system ในปี 1960 (LISP 1.5 Programmer's Manual ปี 1962 คือฉบับที่สมบูรณ์และแพร่หลายที่สุดในยุคนั้น)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  ทำไม REPL ถึงสำคัญกว่า "แค่ console"
&lt;/h2&gt;

&lt;p&gt;REPL ไม่ใช่แค่ terminal ที่พิมพ์คำสั่งได้ มันเปลี่ยนวิธีที่เรา:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;วิธีเก่า&lt;/th&gt;
&lt;th&gt;วิธี REPL&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;อ่าน documentation → ท่องจำ → เขียน&lt;/td&gt;
&lt;td&gt;ทดลอง → ดูผล → เข้าใจ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;รอ compile ทั้งโปรเจกต์&lt;/td&gt;
&lt;td&gt;ทดสอบทีละฟังก์ชัน&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;กลัวผิด เพราะแก้ยาก&lt;/td&gt;
&lt;td&gt;ผิดได้เร็ว แก้ได้เร็ว&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;code คือ artifacts สำเร็จรูป&lt;/td&gt;
&lt;td&gt;code คือ conversation&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;นี่คือรากฐานของ &lt;strong&gt;exploratory programming&lt;/strong&gt; — ปรัชญาที่บอกว่าเราไม่จำเป็นต้องรู้ทุกอย่างก่อนเริ่มเขียน เราเรียนรู้ระหว่างเขียนได้&lt;/p&gt;

&lt;h2&gt;
  
  
  การเดินทางของ REPL — จากห้องแล็บ AI มาถึงมือคุณ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1960s — LISP
&lt;/h3&gt;

&lt;p&gt;REPL ตัวแรกของโลก — &lt;code&gt;read&lt;/code&gt;, &lt;code&gt;eval&lt;/code&gt;, &lt;code&gt;print&lt;/code&gt; ในวงจรอนันต์&lt;/p&gt;

&lt;h3&gt;
  
  
  1990–1991 — Python
&lt;/h3&gt;

&lt;p&gt;Guido van Rossum เริ่มพัฒนา Python ปลายปี 1989 เปิดตัวสู่สาธารณะครั้งแรกในเดือนกุมภาพันธ์ 1991 — REPL (&lt;code&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/code&gt;) เป็นส่วนหนึ่งของภาษามาตั้งแต่แรก โดยเอาไอเดียมาจาก LISP และ ABC language (ภาษาที่ Guido ช่วยพัฒนาก่อนหน้านี้)&lt;/p&gt;

&lt;p&gt;สิ่งที่ Python เพิ่ม: readability — REPL ที่อ่านง่าย, error message ที่มนุษย์เข้าใจ, และ philosophy "มาเพื่อให้คนเขียน, ไม่ใช่ให้ compiler อ่าน"&lt;/p&gt;

&lt;h3&gt;
  
  
  1995 — Ruby IRB
&lt;/h3&gt;

&lt;p&gt;Matz สร้าง IRB (Interactive Ruby) — สำหรับคนที่อยากลอง Ruby แบบ real-time (Ruby มี DNA LISP — Matz บอกว่า "Ruby was a Lisp originally, in theory")&lt;/p&gt;

&lt;h3&gt;
  
  
  2006 — Firebug
&lt;/h3&gt;

&lt;p&gt;Joe Hewitt สร้าง Firebug extension สำหรับ Firefox — เป็นครั้งแรกที่ browser มี interactive console แบบ REPL: inspect DOM, ทดลอง JavaScript, ดู network request — ทั้งหมดใน browser โดยไม่ต้องเปิด terminal แยก วงการ frontend dev เปลี่ยนไปตลอดกาล&lt;/p&gt;

&lt;h3&gt;
  
  
  2009 — Node.js REPL
&lt;/h3&gt;

&lt;p&gt;Ryan Dahl ให้ JavaScript มี REPL นอก browser — frontend dev สามารถลอง JS แบบ interactive โดยไม่ต้องเปิด browser เลย&lt;/p&gt;

&lt;h3&gt;
  
  
  2011 — Chrome DevTools Console
&lt;/h3&gt;

&lt;p&gt;ทีม Chrome ของ Google ต่อยอดจาก WebKit Inspector (ต้นแบบของ Safari) สร้าง DevTools ที่มี Console ในตัว — แนวคิด interactive debugging ใน browser ที่ Firebug บุกเบิกไว้ กลายเป็น standard ในทุก browser หลังจากนั้น&lt;/p&gt;

&lt;h3&gt;
  
  
  2014 — IPython / Jupyter Notebook
&lt;/h3&gt;

&lt;p&gt;Fernando Pérez ต่อยอด REPL ของ Python ให้เป็น notebook — ผสมโค้ด, ผลลัพธ์, markdown, กราฟ ในหน้าเดียว นี่คือ REPL เวอร์ชันที่สมบูรณ์แบบที่สุดสำหรับ data science&lt;/p&gt;

&lt;h3&gt;
  
  
  2015 — Rust Playground
&lt;/h3&gt;

&lt;p&gt;Rust — ภาษาที่ compile ช้าเป็นชั่วโมง — มี playground ออนไลน์ที่ทำตัวเป็น REPL: เขียน → รัน → เห็นผล → ปรับ → รันใหม่ — ทั้งหมดใน browser&lt;/p&gt;

&lt;h2&gt;
  
  
  สิ่งที่ REPL สอนเรา
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Feedback loop ที่สั้นที่สุดคืออาวุธที่ทรงพลังที่สุด&lt;/strong&gt; — programmer ที่ทดลองเร็ว เรียนรู้เร็วกว่า programmer ที่รอ compile&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;ภาษาไม่ควร "ถูกต้องตั้งแต่ compile" ควร "เรียนรู้ระหว่างเขียน"&lt;/strong&gt; — REPL ทำให้ภาษากลายเป็นเครื่องมือคิด ไม่ใช่แค่เครื่องมือผลิต&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Simple ideas win&lt;/strong&gt; — read → eval → print → loop — 4 คำ, 4 ขั้นตอน, เปลี่ยนวิธีมนุษย์เขียนโค้ดไปตลอดกาล&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  อ่านเพิ่ม
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://dspace.mit.edu/handle/1721.1/6094" rel="noopener noreferrer"&gt;MACLISP Reference Manual (1974)&lt;/a&gt; — ที่มาของคำว่า "read-eval-print loop"&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://www.paulgraham.com/icad.html" rel="noopener noreferrer"&gt;Paul Graham — "Revenge of the Nerds"&lt;/a&gt; — "Lisp was the first language to have an interactive REPL"&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://vimeo.com/36579366" rel="noopener noreferrer"&gt;Bret Victor — "Inventing on Principle"&lt;/a&gt; — ทำไม feedback ที่ทันทีถึงเปลี่ยนวิธีเราคิด&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://jupyter.org/" rel="noopener noreferrer"&gt;Jupyter Project&lt;/a&gt; — REPL สำหรับ data science&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;📅 สิงหาคม 2026 | ⚠️ ตรวจสอบข้อมูล ณ วันที่เขียน&lt;/p&gt;

</description>
      <category>lisp</category>
      <category>history</category>
      <category>programming</category>
      <category>functional</category>
    </item>
    <item>
      <title>LISP — ภาษา 67 ปีก่อน ที่ยังมีชีวิตอยู่ในทุกภาษาที่คุณเขียน</title>
      <dc:creator>Gophernment</dc:creator>
      <pubDate>Tue, 04 Aug 2026 23:13:21 +0000</pubDate>
      <link>https://dev.to/gophernment/lisp-phaasaa-67-piikn-thiiyangmiichiiwityuuainthukphaasaathiikhunekhiiyn-1cfe</link>
      <guid>https://dev.to/gophernment/lisp-phaasaa-67-piikn-thiiyangmiichiiwityuuainthukphaasaathiikhunekhiiyn-1cfe</guid>
      <description>&lt;p&gt;คุณเขียน &lt;code&gt;if-else&lt;/code&gt; ทุกวัน&lt;br&gt;
คุณรัน code ใน terminal แล้ว REPL มันตอบกลับมา&lt;br&gt;
คุณ &lt;code&gt;lambda&lt;/code&gt; ใน Python, arrow function ใน JavaScript, closure ใน Rust&lt;/p&gt;

&lt;p&gt;— ทั้งหมดนี้ &lt;strong&gt;เกิดจากภาษา LISP&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;และที่น่าทึ่งคือ... LISP ไม่เคยถูก planned ให้เป็นภาษาโปรแกรมด้วยซ้ำ&lt;/p&gt;
&lt;h2&gt;
  
  
  กระดาษแผ่นเดียวที่เปลี่ยนโลก
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1958&lt;/strong&gt; — John McCarthy เริ่มพัฒนาแนวคิด LISP ที่ MIT&lt;br&gt;
&lt;strong&gt;เมษายน 1960&lt;/strong&gt; — McCarthy วัย 32 ตีพิมพ์ paper ใน Communications of the ACM (vol. 3, หน้า 184-195)&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Recursive Functions of Symbolic Expressions and Their Computation by Machine, Part I"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;ใน paper 12 หน้านี้ McCarthy เสนอไอเดียของภาษาโปรแกรมที่:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;จัดการกับสัญลักษณ์ (symbols) ไม่ใช่แค่ตัวเลข&lt;/li&gt;
&lt;li&gt;ใช้ recursion เป็นตัวควบคุมการทำงาน แทนการใช้ loop&lt;/li&gt;
&lt;li&gt;เก็บ function เป็น first-class citizen — ส่งต่อกันได้เหมือนข้อมูล&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;McCarthy เขียนมันขึ้นมาเป็น &lt;strong&gt;ทฤษฎีทางคณิตศาสตร์&lt;/strong&gt; — ไม่ได้ตั้งใจ implement&lt;/p&gt;

&lt;p&gt;แต่ก่อน paper จะตีพิมพ์ — ระหว่างปี 1958-59 Steve Russell นักศึกษา grad student อ่าน manuscript&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"I told him, 'Steve, why don't you program this eval?' and he said to me, 'Oh, I misread what you meant. I thought you meant I should implement the interpreter.'"&lt;/p&gt;

&lt;p&gt;— John McCarthy, ACM interview&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;นักศึกษา &lt;strong&gt;เขียน interpreter ให้ทฤษฎีของอาจารย์&lt;/strong&gt; — และภาษา LISP ก็เกิด&lt;/p&gt;

&lt;p&gt;code ตัวแรกที่ Russell เขียน ใช้เวลาแค่ 2-3 วัน (ตัว LISP 1.5 Programmer's Manual ฉบับเต็มออกตามมาทีหลัง ในปี 1962)&lt;/p&gt;
&lt;h2&gt;
  
  
  สิ่งที่ LISP สร้างไว้ (และเราใช้มันทุกวัน)
&lt;/h2&gt;
&lt;h3&gt;
  
  
  1. if-then-else
&lt;/h3&gt;

&lt;p&gt;ย้อนไปปี 1958 — ภาษาส่วนใหญ่มีแค่ &lt;code&gt;GOTO&lt;/code&gt; กับ branch แบบ assembly&lt;/p&gt;

&lt;p&gt;McCarthy ให้กำเนิด &lt;code&gt;cond&lt;/code&gt; (conditional expression) — จุดเริ่มต้นของ &lt;code&gt;if-else&lt;/code&gt; ที่เราเห็นแทบจะในทุกภาษา&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;cond&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nb"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ss"&gt;'negative&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nb"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ss"&gt;'zero&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;t&lt;/span&gt; &lt;span class="ss"&gt;'positive&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;C, Java, Python, JavaScript, Go, Rust — ภาษาเหล่านี้ได้รับมรดกนี้มาหมด Conditional branching ในทุกภาษาสมัยใหม่มีโครงสร้างแบบเดียวกับที่ McCarthy คิดไว้ตั้งแต่ก่อนมนุษย์ไปดวงจันทร์&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Garbage Collection
&lt;/h3&gt;

&lt;p&gt;ก่อน LISP — programmer จัดการ memory เอง 100% ทุกบรรทัดของ &lt;code&gt;malloc&lt;/code&gt; และ &lt;code&gt;free&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;LISP สร้าง garbage collection ตัวแรกของโลก — ต้นฉบับคือ &lt;strong&gt;mark-and-sweep&lt;/strong&gt; algorithm (implement โดย Daniel Edwards นักศึกษา MIT)&lt;/p&gt;

&lt;p&gt;ทุกวันนี้ GC คือ default ในเกือบทุกภาษา high-level — Java, Python, JavaScript, Go, C#, Ruby ล้วนใช้แนวคิดนี้ต่อยอด&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Lambda — function เป็นข้อมูล
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;*&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;LISP ทำให้ function เป็น &lt;strong&gt;first-class citizen&lt;/strong&gt; — ส่ง function เป็น parameter ได้, return function ได้, เก็บลง variable ได้เหมือนเป็น string หรือ integer&lt;/p&gt;

&lt;p&gt;นี่คือต้นทางของ:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;JavaScript&lt;/strong&gt; — arrow function &lt;code&gt;(x) =&amp;gt; x * x&lt;/code&gt; (Brendan Eich ถูกจ้างไป Netscape เพื่อทำ Scheme ใน browser — แต่ management เปลี่ยนใจให้ syntax เหมือน Java)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Python&lt;/strong&gt; — &lt;code&gt;lambda x: x * x&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ruby&lt;/strong&gt; — blocks, procs, lambdas (Matz บอกว่า "Ruby was a Lisp originally, in theory")&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Java&lt;/strong&gt; — lambda expressions (Java 8, 2014 — ใช้เวลา 19 ปีกว่าจะตามทัน)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C++&lt;/strong&gt; — lambda (C++11)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. REPL — ปรัชญา "คุยกับภาษา"
&lt;/h3&gt;

&lt;p&gt;Read-Eval-Print Loop — LISP ให้กำเนิดมันในทศวรรษ 1960s&lt;/p&gt;

&lt;p&gt;ก่อนหน้านั้น: เขียน code → compile → run → debug → repeat&lt;br&gt;
หลังจากนั้น: พิมพ์ expression → กด enter → เห็นผลทันที&lt;/p&gt;

&lt;p&gt;ทุกวันนี้ถ้าคุณเปิด Python REPL (&lt;code&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/code&gt;), Node.js console, Ruby IRB, Chrome DevTools, Rust Playground, หรือ Elixir IEx — คุณกำลังนั่งอยู่ในห้องเรียนเดียวกับ programmer LISP เมื่อ 60 ปีที่แล้ว&lt;/p&gt;
&lt;h3&gt;
  
  
  5. Homoiconicity — code = data
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;&lt;span class="o"&gt;'&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;          &lt;span class="c1"&gt;; ← นี่คือ list&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;eval&lt;/span&gt; &lt;span class="o"&gt;'&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;   &lt;span class="c1"&gt;; ← นี่คือ code ที่รัน list&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;LISP เขียนด้วย... LISP — code กับ data ใช้โครงสร้างเดียวกัน (S-expression)&lt;/p&gt;

&lt;p&gt;แปลว่า &lt;strong&gt;โปรแกรมแก้โปรแกรมตัวเองได้&lt;/strong&gt; — ไม่ต้องใช้ parser แยก AST, ไม่ต้องเขียน transformer&lt;/p&gt;

&lt;p&gt;นี่คือรากฐานของ &lt;strong&gt;macro system&lt;/strong&gt; ที่ทรงพลังที่สุดในสายภาษาโปรแกรม&lt;/p&gt;

&lt;p&gt;ไม่มีภาษาไหนทำได้เต็มระบบเท่า LISP — แต่แนวคิด "code as data" ไปอยู่ใน:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Elixir&lt;/strong&gt; — macro (รับ AST, คืน AST)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Julia&lt;/strong&gt; — macro + multiple dispatch ("We want a language that's homoiconic, with true macros like Lisp" — Julia manifesto, 2012)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rust&lt;/strong&gt; — macro system (proc macro)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clojure&lt;/strong&gt; — macro (ของ Clojure ก็คือ LISP dialect นั่นเอง)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  มรดกจาก LISP
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;LISP (1958)
├── Scheme (1975) — minimalist, lexical scoping
│   ├── JavaScript (1995) — Brendan Eich ตั้งใจทำ Scheme-like ใน browser
│   │   └── arrow functions, closure, first-class functions
│   └── Racket (1995) — ภาษาเพื่อการสอนและการวิจัย
├── Common Lisp (1984) — ภาคอุตสาหกรรม, pragmatic
│   └── Emacs Lisp (1985) — editor scripting (GNU Emacs)
├── Clojure (2007) — LISP บน JVM, immutable by default
│   └── จุดประกาย functional programming ในโลก enterprise
└── Python, Ruby, Elixir, Julia, Rust, Swift — ทุกภาษาเอาแนวคิด LISP ไปปรับใช้
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  ทำไม LISP ถึงไม่ใช่ภาษาหลักวันนี้
&lt;/h2&gt;

&lt;p&gt;ทั้งที่สร้างนวัตกรรมเกือบทุกอย่างที่เราใช้ — ทำไม LISP ถึงไม่ชนะ?&lt;/p&gt;

&lt;p&gt;Paul Graham (ผู้ก่อตั้ง Y Combinator, แฟนพันธุ์แท้ LISP) อธิบายไว้ใน essay "Beating the Averages":&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Syntax ต่างจากทุกอย่าง&lt;/strong&gt; — วงเล็บทำให้คนกลัว&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ไม่มี standard library ในยุคแรก&lt;/strong&gt; — Common Lisp มากอบกู้ในปี 1984 แต่ช้าไปแล้ว&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI Winter&lt;/strong&gt; — LISP ผูกกับ AI research; เมื่องบ AI หาย LISP ก็หายด้วย&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tooling&lt;/strong&gt; — compiler ช้า, IDE ห่วย (เทียบกับ Visual Studio ยุค 90s)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Graham ยืนยันว่า:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Lisp is a language that was discovered, not invented."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;ฝั่งนักวิจารณ์ LISP (รวมถึงคนที่เคยใช้ใน production แล้วเปลี่ยนไปภาษาอื่น) ชี้ปัญหาเพิ่มเติมที่ Graham ไม่พูดถึง:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Dynamic typing ในระบบใหญ่&lt;/strong&gt; — refactoring ยาก, compiler จับ error ได้น้อย, debugging ใช้เวลานานใน codebase ระดับแสนบรรทัด&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance จนถึงยุค 2000s&lt;/strong&gt; — ก่อน SBCL และ Chez Scheme, LISP runtime บน hardware ยุคนั้นช้ากว่า C/C++ มากโดยเฉพาะงาน numerical&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fragmentation&lt;/strong&gt; — Common Lisp กับ Scheme ไม่เคยตกลงกันได้; community แตกเป็นเสี่ยง ๆ แทนที่จะรวมพลัง&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;สรุป: ไม่มีสาเหตุเดียว — มันคือ &lt;strong&gt;perfect storm&lt;/strong&gt; ของ syntax ต่าง + เกิดผิดเวลา + community แตก + ไม่มี corporate sponsor (ต่างจาก Java ที่ Sun ทุ่ม, C# ที่ Microsoft ทุ่ม)&lt;/p&gt;
&lt;h2&gt;
  
  
  มรดกที่มองไม่เห็น
&lt;/h2&gt;

&lt;p&gt;บทความนี้ไม่ได้ตั้งใจจะบอกว่า "คุณควรเขียน LISP" &lt;/p&gt;

&lt;p&gt;แต่ทุกครั้งที่คุณ:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;numbers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;squared&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;active&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;squared&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.map&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.collect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;— คุณกำลังเขียน LISP โดยไม่รู้ตัว&lt;/p&gt;




&lt;h3&gt;
  
  
  อ่านเพิ่ม
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://dspace.mit.edu/handle/1721.1/6094" rel="noopener noreferrer"&gt;McCarthy's Original 1960 Paper&lt;/a&gt; — "Recursive Functions of Symbolic Expressions"&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.paulgraham.com/avg.html" rel="noopener noreferrer"&gt;Paul Graham — "Beating the Averages"&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.paulgraham.com/icad.html" rel="noopener noreferrer"&gt;Paul Graham — "Revenge of the Nerds"&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://mitpress.mit.edu/sites/default/files/sicp/index.html" rel="noopener noreferrer"&gt;Structure and Interpretation of Computer Programs (SICP)&lt;/a&gt; — ตำรา Scheme ในตำนานของ MIT&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.infoq.com/presentations/Simple-Made-Easy/" rel="noopener noreferrer"&gt;Rich Hickey — "Simple Made Easy"&lt;/a&gt; — ปรัชญาเบื้องหลัง Clojure&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;📅 สิงหาคม 2026 | ⚠️ ตรวจสอบข้อมูล ณ วันที่เขียน&lt;/p&gt;

</description>
      <category>lisp</category>
      <category>history</category>
      <category>programming</category>
      <category>functional</category>
    </item>
    <item>
      <title>GNU — จุดเริ่มต้นของ Linux ที่หลายคนไม่เคยรู้</title>
      <dc:creator>Gophernment</dc:creator>
      <pubDate>Tue, 04 Aug 2026 22:51:23 +0000</pubDate>
      <link>https://dev.to/gophernment/gnu-cchuderimtnkhng-linux-thiihlaaykhnaimekhyruu-4491</link>
      <guid>https://dev.to/gophernment/gnu-cchuderimtnkhng-linux-thiihlaaykhnaimekhyruu-4491</guid>
      <description>&lt;p&gt;เวลาเราเรียก Linux — เรามักนึกถึงระบบปฏิบัติการที่รันเซิร์ฟเวอร์ 99% ของโลก รัน Android รัน Raspberry Pi แต่สิ่งที่หลายคนไม่รู้คือ &lt;strong&gt;Linux ไม่ใช่ "ระบบปฏิบัติการที่สมบูรณ์" ตั้งแต่แรก&lt;/strong&gt; มันเป็นแค่ kernel — หัวใจที่คอยคุยกับฮาร์ดแวร์&lt;/p&gt;

&lt;p&gt;ส่วน shell, compiler, text editor, core utilities — ทั้งหมดนั่นมาจาก &lt;strong&gt;โครงการ GNU&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;เรื่องราวของ GNU และ Linux มันเริ่มจากการที่เครื่องพิมพ์เครื่องหนึ่ง... พัง&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;📌 &lt;strong&gt;ออกเสียงอย่างไร:&lt;/strong&gt; GNU อ่านว่า "กะ-นู" (hard g, พยางค์เดียว) — GNU's Not Unix&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  เรื่องเล่าจากเครื่องพิมพ์
&lt;/h2&gt;

&lt;p&gt;ปี 1980 Richard Stallman ทำงานที่ MIT AI Lab เครื่องพิมพ์ Xerox ในห้องแล็บ jam กระดาษบ่อยมาก เขาเลยอยากแก้ซอฟต์แวร์ให้มันแจ้งเตือนตอน jam แต่ Xerox ไม่ยอมให้ source code&lt;/p&gt;

&lt;p&gt;สำหรับคนยุค 2026 นี่คือเรื่องปกติ — บริษัทไม่ให้ source code ก็หาอันอื่นสิ&lt;/p&gt;

&lt;p&gt;แต่สำหรับ Stallman และวัฒนธรรม hacker ใน MIT AI Lab ยุค 1970s — &lt;strong&gt;นี่คือการทรยศ&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;เพื่อนบ้าน hack รั้วบ้านคุณ และคุณไม่มีสิทธิ์แม้แต่จะรู้ว่ารั้วมันสร้างยังไง&lt;/p&gt;

&lt;p&gt;Stallman เขียนไว้ในภายหลังว่า:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"ผมบอกตัวเองไม่ได้ว่า non-disclosure agreement มันไม่มีพิษมีภัย"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  กำเนิด GNU
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;27 กันยายน 1983&lt;/strong&gt; — Stallman โพสต์ประกาศโครงการ GNU บน Usenet ภายใต้หัวข้อ "new Unix implementation"&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"ผมเชื่อว่ากฎทอง (golden rule) กำหนดว่า ถ้าผมชอบโปรแกรมใด ผมต้องแบ่งปันมันกับคนอื่นที่ชอบมันด้วย ผมไม่สามารถเซ็นสัญญาไม่เปิดเผยข้อมูล (NDA) หรือสัญญาอนุญาตซอฟต์แวร์แบบปิด ด้วยจิตสำนึกที่ดีได้"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;— Richard Stallman, GNU Initial Announcement, 27 ก.ย. 1983&lt;/p&gt;

&lt;p&gt;เป้าหมาย: สร้างระบบปฏิบัติการแบบ Unix ที่ &lt;strong&gt;ทุกคนมีอิสระ&lt;/strong&gt; ในการใช้ แก้ไข และแชร์&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ฟรี ไม่ได้แปลว่า gratis (ของฟรี)
ฟรี แปลว่า libre (เสรีภาพ)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;— Free Software Foundation&lt;/p&gt;

&lt;p&gt;Stallman เริ่มเขียนทีละ component:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GNU Emacs&lt;/strong&gt; — text editor ในตำนาน (1985)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GCC&lt;/strong&gt; — GNU C Compiler (1987)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;glibc&lt;/strong&gt; — C library (1988)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bash&lt;/strong&gt; — shell ที่เราใช้กันมาจนถึงทุกวันนี้ (1989)&lt;/li&gt;
&lt;li&gt;Coreutils, binutils, gdb... ไล่เรียงไปเรื่อย ๆ&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ภายในปี 1990 — เกือบทั้งระบบปฏิบัติการพร้อมแล้ว &lt;strong&gt;ยกเว้น kernel&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Hurd — kernel ที่ไม่มีวันเสร็จ
&lt;/h2&gt;

&lt;p&gt;kernel ที่ GNU เลือกใช้คือ &lt;strong&gt;GNU Hurd&lt;/strong&gt; — ออกแบบด้วยสถาปัตยกรรม microkernel บน Mach (CMU) ที่ทะเยอทะยานเกินยุค&lt;/p&gt;

&lt;p&gt;ปัญหาคือ:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;รอ Mach เป็น free software&lt;/strong&gt; — CMU ล่าช้าในการปล่อย source code เพราะฝ่ายกฎหมาย&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multithreaded servers สื่อสารด้วย IPC&lt;/strong&gt; — "very hard to debug" (คำพูดของ Stallman เอง)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Perfect is the enemy of good&lt;/strong&gt; — ดีไซน์ซ้ำไปซ้ำมาเพื่อความ "สมบูรณ์แบบ" ทางทฤษฎี&lt;/li&gt;
&lt;li&gt;Hurd 0.1 ออกปี 1996 — 6 ปีหลังจากเริ่มพัฒนา&lt;/li&gt;
&lt;li&gt;Hurd 0.9 ออกธันวาคม 2016 — &lt;strong&gt;ล่าสุด และไม่เคยถึง 1.0&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Stallman พูดตรง ๆ:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"GNU Hurd ไม่เหมาะสำหรับ production use และเราไม่รู้ว่ามันจะเหมาะเมื่อไหร่"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  เด็กฟินแลนด์กับ kernel ของเขา
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;25 สิงหาคม 1991&lt;/strong&gt; — Linus Torvalds นักศึกษาปี 2 มหาวิทยาลัย Helsinki (อายุ 21 ปี) โพสต์บน Usenet group &lt;code&gt;comp.os.minix&lt;/code&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Hello everybody out there using minix -&lt;/p&gt;

&lt;p&gt;I'm doing a (free) operating system (just a hobby, won't be big and professional like gnu) for 386(486) AT clones.&lt;/p&gt;

&lt;p&gt;I've currently ported bash(1.08) and gcc(1.40), and things seem to work.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;สังเกตว่า Linus เองก็พอร์ต &lt;strong&gt;bash&lt;/strong&gt; และ &lt;strong&gt;gcc&lt;/strong&gt; — GNU tools — มาตั้งแต่วันแรก&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;17 กันยายน 1991&lt;/strong&gt; — Linux 0.01 ออกสู่สาธารณะ (คนที่ตั้งชื่อว่า "Linux" คือ Ari Lemmke ผู้ดูแล ftp.funet.fi — Linus อยากให้ชื่อ "Freax" แต่ Lemmke ไม่ชอบ)&lt;/p&gt;

&lt;p&gt;Linus เขียนใน release notes ของ 0.01:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Sadly, a kernel by itself gets you nowhere… Most of the tools used with linux are GNU software and are under the GNU copyleft."&lt;/p&gt;

&lt;p&gt;"น่าเศร้าที่ kernel อย่างเดียวมันไปไหนไม่ได้... เครื่องมือส่วนใหญ่ที่ใช้กับ linux คือซอฟต์แวร์ GNU"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  ทำไม Linux ถึงสำเร็จ
&lt;/h2&gt;

&lt;p&gt;ทั้งที่ Hurd มีคนเก่งกว่า มี philosophy ล้ำกว่า ทำไม Linux ถึงชนะ?&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;GNU Hurd&lt;/th&gt;
&lt;th&gt;Linux&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;สถาปัตยกรรม&lt;/td&gt;
&lt;td&gt;Microkernel&lt;/td&gt;
&lt;td&gt;Monolithic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ออกแบบโดย&lt;/td&gt;
&lt;td&gt;นักทฤษฎี OS&lt;/td&gt;
&lt;td&gt;"ค่าเทอมถูกกว่า Sun"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ปรัชญา&lt;/td&gt;
&lt;td&gt;Perfect from day 1&lt;/td&gt;
&lt;td&gt;Release early, release often&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ทีม&lt;/td&gt;
&lt;td&gt;อาสาสมัคร&lt;/td&gt;
&lt;td&gt;ชุมชน (Git แจกตั้งแต่ 2005)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;"Release early, release often"&lt;/strong&gt; — หลักการที่ Linus สอนโลก open source โดยไม่ตั้งใจ&lt;/p&gt;

&lt;p&gt;Linux 0.01 (ก.ย. 1991) — ~10,000 บรรทัด&lt;br&gt;
Linux 0.12 (ก.พ. 1992) — เปลี่ยนไปใช้ &lt;strong&gt;GPL&lt;/strong&gt; — นี่คือจุดเปลี่ยนสำคัญ&lt;br&gt;
Linux 1.0 (มี.ค. 1994) — 176,250 บรรทัด&lt;br&gt;
Linux 6.x (2024) — เกิน 30 ล้านบรรทัด&lt;/p&gt;
&lt;h2&gt;
  
  
  GNU + Linux = ?
&lt;/h2&gt;

&lt;p&gt;เมื่อ Linux ถือกำเนิด มันขาด userspace tools — shell, compiler, basic utilities&lt;/p&gt;

&lt;p&gt;GNU มีของทุกอย่าง — GCC compiler, Bash shell, coreutils&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Linux + GNU tools = ระบบปฏิบัติการที่สมบูรณ์&lt;/strong&gt; ครั้งแรกที่โลกมี free Unix ทั้งระบบ&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"It is due to Linux that we can actually run a version of the GNU system today."&lt;/p&gt;

&lt;p&gt;— Richard Stallman&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;MCC Interim Linux (กุมภาพันธ์ 1992)&lt;/strong&gt; — ผลงานของ Owen Le Blanc จาก Manchester Computing Centre — คือ distro แรกที่รวม Linux kernel กับ GNU userspace เข้าด้วยกัน ตามด้วย TAMU Linux และ &lt;strong&gt;SLS (Softlanding Linux System)&lt;/strong&gt; ในสิงหาคม 1992&lt;/p&gt;

&lt;p&gt;SLS เป็น distro แรกที่คนใช้กันเยอะ... แต่ package management ของมันพังไม่เป็นท่า จนทำให้ &lt;strong&gt;Ian Murdock&lt;/strong&gt; วัย 20 ปี ประกาศบน Usenet ในเดือนสิงหาคม 1993 ว่าจะสร้าง distro ใหม่ที่ "maintained openly, in the spirit of GNU" — distro นั้นคือ &lt;strong&gt;Debian&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;ตามมาด้วย &lt;strong&gt;Slackware&lt;/strong&gt; (กรกฎาคม 1993) ที่พัฒนาโดย Patrick Volkerding — เรียบง่าย ไม่มี dependency resolution แต่ stable จนกลายเป็น distro ที่เก่าแก่ที่สุดที่ยัง maintain อยู่จนถึงทุกวันนี้&lt;/p&gt;

&lt;p&gt;เมื่อ Debian เปลี่ยนชื่อเป็น &lt;strong&gt;"Debian GNU/Linux"&lt;/strong&gt; ในต้นปี 1994 ตามคำขอของ Stallman — การถกเถียงเรื่องชื่อก็เริ่มต้นขึ้น&lt;/p&gt;
&lt;h2&gt;
  
  
  GNU/Linux — การถกเถียงที่ยังไม่จบ
&lt;/h2&gt;

&lt;p&gt;Stallman ยืนกราน: เรียกมันว่า &lt;strong&gt;"GNU/Linux"&lt;/strong&gt; เพราะ:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GNU project เริ่มตั้งแต่ 1983 — 7-8 ปีก่อน Linux&lt;/li&gt;
&lt;li&gt;Stallman อ้างอิงตัวเลขจากงานวิจัยภายในของ Red Hat (2001) และ gNewSense (2008) ว่า ใน distro หนึ่ง ๆ: โค้ด GNU ≈ &lt;strong&gt;15-28%&lt;/strong&gt;, โค้ด Linux kernel ≈ &lt;strong&gt;1.5-3%&lt;/strong&gt; (ตัวเลขนี้เป็นที่ถกเถียงในชุมชน — วัดยังไงให้นับ "หน่วย" ของโค้ดอย่างเที่ยงตรง)&lt;/li&gt;
&lt;li&gt;ถ้าไม่มี GNU — Linus ต้องเขียน compiler, shell, utilities เองทั้งหมด&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Linus ตอบกลับ:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"It doesn't really matter what people call Linux, as long as credit is given where credit is due."&lt;br&gt;
— comp.os.linux.misc, 1996&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;และในหนังสารคดี &lt;em&gt;Revolution OS&lt;/em&gt; (2001):&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Calling Linux in general 'GNU Linux' I think is just ridiculous."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;แต่ Linus ก็ไม่ได้ดูถูก GNU — ในหนังสืออัตชีวประวัติ &lt;em&gt;Just for Fun&lt;/em&gt; (2001) เขาเขียนว่า:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Richard Stallman is the God of Free Software."&lt;/p&gt;

&lt;p&gt;"Stallman, who deserves a monument in his honor for giving birth to the GPL…"&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  มรดกที่เรายังใช้อยู่ทุกวันนี้
&lt;/h2&gt;

&lt;p&gt;ลองเปิด terminal แล้วพิมพ์:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;--version&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt;
&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;GNU coreutils&lt;span class="o"&gt;)&lt;/span&gt; 9.x

&lt;span class="nv"&gt;$ &lt;/span&gt;gcc &lt;span class="nt"&gt;--version&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt;
gcc &lt;span class="o"&gt;(&lt;/span&gt;GCC&lt;span class="o"&gt;)&lt;/span&gt; 14.x

&lt;span class="nv"&gt;$ &lt;/span&gt;bash &lt;span class="nt"&gt;--version&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt;
GNU bash, version 5.x
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;GNU คือวิญญาณของ Linux&lt;/strong&gt; — kernel คือหัวใจ แต่ shell, compiler, utilities ที่เราใช้ทุกวันนี้ คือ GNU&lt;/p&gt;

&lt;p&gt;ถ้าไม่มีโครงการ GNU: Linus ต้องเขียนทุกอย่างเองตั้งแต่ compiler, linker, shell... และ kernel "งานอดิเรก" ของเขาคงไม่รอด&lt;/p&gt;

&lt;p&gt;และถ้าไม่มี Linux: GNU มีเกือบทุกอย่างยกเว้น kernel ที่รันได้จริง — Hurd ก็ยังเป็น prototype มาจนถึงทุกวันนี้&lt;/p&gt;

&lt;p&gt;สองโครงการ — หนึ่งปรัชญา หนึ่ง pragmatic — มาบรรจบกันในเวลาที่เหมาะสมพอดี&lt;/p&gt;




&lt;h3&gt;
  
  
  สำหรับคนที่อยากอ่านเพิ่ม
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.gnu.org/gnu/manifesto.html" rel="noopener noreferrer"&gt;The GNU Manifesto (1985)&lt;/a&gt; — Stallman ต้นฉบับ&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.gnu.org/gnu/thegnuproject.html" rel="noopener noreferrer"&gt;The GNU Project&lt;/a&gt; — essay ของ Stallman&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://mirrors.edge.kernel.org/pub/linux/kernel/Historic/old-versions/RELNOTES-0.01" rel="noopener noreferrer"&gt;Linux 0.01 Release Notes&lt;/a&gt; — Torvalds, 1991&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://mirrors.edge.kernel.org/pub/linux/kernel/Historic/old-versions/RELNOTES-0.12" rel="noopener noreferrer"&gt;Linux 0.12 Release Notes (เปลี่ยนไปใช้ GPL)&lt;/a&gt; — Torvalds, ก.พ. 1992&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://web.archive.org/web/20130515160138/http://groups.google.com/group/comp.os.minix/msg/b813d52cbc5a044b" rel="noopener noreferrer"&gt;Linus โพสต์แรกบน Usenet (25 ส.ค. 1991)&lt;/a&gt; — เก็บใน Wayback Machine&lt;/li&gt;
&lt;li&gt;&lt;a href="https://archive.org/details/justforfun00linu" rel="noopener noreferrer"&gt;Just for Fun — Linus Torvalds autobiography (2001)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Revolution_OS" rel="noopener noreferrer"&gt;Revolution OS — หนังสารคดี open source&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;📅 สิงหาคม 2026 | ⚠️ ตรวจสอบข้อมูล ณ วันที่เขียน&lt;/p&gt;

</description>
      <category>linux</category>
      <category>history</category>
      <category>opensource</category>
      <category>gnu</category>
    </item>
    <item>
      <title>"iota ใน Go — อักษรกรีกตัวจิ๋วที่กลายเป็นเครื่องมือทรงพลัง"</title>
      <dc:creator>Gophernment</dc:creator>
      <pubDate>Sun, 02 Aug 2026 03:53:36 +0000</pubDate>
      <link>https://dev.to/gophernment/iota-ain-go-aksrkriiktawcchiwthiiklaayepnekhruuengmuuethrngphlang-213e</link>
      <guid>https://dev.to/gophernment/iota-ain-go-aksrkriiktawcchiwthiiklaayepnekhruuengmuuethrngphlang-213e</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;📅 เขียนเมื่อ: กรกฎาคม 2026&lt;br&gt;
⚠️ ตรวจสอบข้อมูลจาก Go Specification, APL documentation, และบันทึกของผู้พัฒนา&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;ถ้าคุณเขียน Go มาระยะหนึ่ง คุณคงเคยเห็น &lt;code&gt;iota&lt;/code&gt; — เจ้า identifier ประหลาดที่ไม่มีใครรู้ว่ามันคืออะไรตอนเจอครั้งแรก&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;Monday&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;iota&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;  &lt;span class="c"&gt;// 1&lt;/span&gt;
    &lt;span class="n"&gt;Tuesday&lt;/span&gt;            &lt;span class="c"&gt;// 2&lt;/span&gt;
    &lt;span class="n"&gt;Wednesday&lt;/span&gt;          &lt;span class="c"&gt;// 3&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;มันไม่ใช่ keyword, ไม่ใช่ type, ไม่ใช่ function — มันคืออะไรกันแน่?&lt;/p&gt;

&lt;p&gt;และที่สำคัญ — &lt;strong&gt;ทำไมต้องชื่อ &lt;code&gt;iota&lt;/code&gt;?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;คำตอบพาเราย้อนกลับไปถึงปี 1962 — ถึงนักคณิตศาสตร์ชาวแคนาดาคนหนึ่ง และภาษาโปรแกรมมิ่งที่เปลี่ยนโลก&lt;/p&gt;




&lt;h2&gt;
  
  
  iota คืออะไรใน Go
&lt;/h2&gt;

&lt;p&gt;ใน Go spec — &lt;code&gt;iota&lt;/code&gt; คือ &lt;strong&gt;predeclared identifier&lt;/strong&gt; ที่ใช้ &lt;strong&gt;เฉพาะใน &lt;code&gt;const&lt;/code&gt; declaration&lt;/strong&gt; เท่านั้น&lt;/p&gt;

&lt;p&gt;มันทำสิ่งเดียว: &lt;strong&gt;นับเลขให้อัตโนมัติ&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;iota&lt;/span&gt;          &lt;span class="c"&gt;// 0 (skip)&lt;/span&gt;
    &lt;span class="n"&gt;KB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="no"&gt;iota&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c"&gt;// 1 &amp;lt;&amp;lt; 10 = 1024&lt;/span&gt;
    &lt;span class="n"&gt;MB&lt;/span&gt;                    &lt;span class="c"&gt;// 1 &amp;lt;&amp;lt; 20 = 1,048,576&lt;/span&gt;
    &lt;span class="n"&gt;GB&lt;/span&gt;                    &lt;span class="c"&gt;// 1 &amp;lt;&amp;lt; 30&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ค่า &lt;code&gt;iota&lt;/code&gt; เริ่มที่ 0 และเพิ่มทีละ 1 ทุกครั้งที่เจอบรรทัดใหม่ใน &lt;code&gt;const&lt;/code&gt; block — แม้ว่าบรรทัดนั้นจะไม่ได้ใช้ &lt;code&gt;iota&lt;/code&gt; ก็ตาม&lt;/p&gt;

&lt;p&gt;สิ่งที่ทำให้ &lt;code&gt;iota&lt;/code&gt; ทรงพลังคือมันเป็น &lt;strong&gt;expression&lt;/strong&gt; (ไม่ใช่แค่ตัวเลข) — คุณเอาไปคูณ บวก ลบ shift ได้หมด&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;Read&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;iota&lt;/span&gt;  &lt;span class="c"&gt;// 1 &amp;lt;&amp;lt; 0 = 1&lt;/span&gt;
    &lt;span class="n"&gt;Write&lt;/span&gt;                 &lt;span class="c"&gt;// 1 &amp;lt;&amp;lt; 1 = 2&lt;/span&gt;
    &lt;span class="n"&gt;Execute&lt;/span&gt;               &lt;span class="c"&gt;// 1 &amp;lt;&amp;lt; 2 = 4&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;นี่คือวิธีมาตรฐานในการสร้าง enum, bitmask, และ constant series ใน Go — ทั้งหมดด้วย keyword เดียว&lt;/p&gt;




&lt;h2&gt;
  
  
  iota — อักษรกรีกตัวเล็กที่สุด
&lt;/h2&gt;

&lt;p&gt;ก่อนจะเป็นชื่อใน Go — &lt;code&gt;ιώτα&lt;/code&gt; (iota) คืออักษรตัวที่ 9 ของกรีกโบราณ: &lt;strong&gt;ι&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;มันคืออักษรที่ &lt;strong&gt;เล็กที่สุด&lt;/strong&gt; ในภาษากรีก — แค่เส้นตรงหนึ่งเส้น ไม่มีหาง ไม่มีขีด&lt;/p&gt;

&lt;p&gt;ในพระคัมภีร์ไบเบิล มีวลี famous: &lt;em&gt;"not one iota"&lt;/em&gt; — แปลว่า "ไม่แม้แต่นิดเดียว" — เพราะ iota คือสิ่งที่เล็กที่สุด&lt;/p&gt;

&lt;p&gt;และมันคือชื่อที่สมบูรณ์แบบสำหรับสิ่งที่ "เพิ่มทีละหนึ่ง"&lt;/p&gt;




&lt;h2&gt;
  
  
  จุดเริ่มต้น — APL และ Kenneth Iverson
&lt;/h2&gt;

&lt;h3&gt;
  
  
  นักคณิตศาสตร์ผู้สร้างภาษา
&lt;/h3&gt;

&lt;p&gt;ปี 1962 — Kenneth E. Iverson ตีพิมพ์หนังสือ &lt;em&gt;"A Programming Language"&lt;/em&gt; (ที่มาของชื่อ APL)&lt;/p&gt;

&lt;p&gt;Iverson เป็นนักคณิตศาสตร์ชาวแคนาดา (ต่อมาได้ Turing Award ปี 1979) — เขาไม่ได้แค่ออกแบบภาษาใหม่ แต่ปฏิวัติวิธีคิดเรื่อง programming&lt;/p&gt;

&lt;p&gt;แทนที่จะเขียน &lt;code&gt;for i = 1 to 10&lt;/code&gt; — Iverson คิดว่า programming ควรเหมือนคณิตศาสตร์: สั้น, สัญลักษณ์, และทรงพลัง&lt;/p&gt;

&lt;h3&gt;
  
  
  เกิดเป็น ⍳ (iota)
&lt;/h3&gt;

&lt;p&gt;ใน APL, Iverson สร้าง operator &lt;code&gt;⍳&lt;/code&gt; — เรียกว่า &lt;strong&gt;iota&lt;/strong&gt; — ที่ทำสิ่งเดียว: สร้างลำดับเลข&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight j"&gt;&lt;code&gt;&lt;span class="err"&gt;⍳&lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;    &lt;span class="err"&gt;→&lt;/span&gt;  &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;
&lt;span class="err"&gt;⍳&lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;   &lt;span class="err"&gt;→&lt;/span&gt;  &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt; &lt;span class="m"&gt;6&lt;/span&gt; &lt;span class="m"&gt;7&lt;/span&gt; &lt;span class="m"&gt;8&lt;/span&gt; &lt;span class="m"&gt;9&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(เชื่อกันว่าใน APL ดั้งเดิม ใช้ตัวอักษรกรีก &lt;code&gt;ι&lt;/code&gt; จริง ๆ — Iverson notation ยุค 1957 ใช้สัญลักษณ์คณิตศาสตร์แบบกรีก ก่อนที่ APL จะพัฒนาชุดอักขระเฉพาะของตัวเอง จนได้สัญลักษณ์ &lt;code&gt;⍳&lt;/code&gt; ที่เราเห็นใน APL สมัยใหม่)&lt;/p&gt;

&lt;p&gt;ทำไมต้องชื่อ iota? — Iverson เลือกเพราะมันคือ &lt;strong&gt;อักษรที่เล็กที่สุด&lt;/strong&gt; → เหมาะกับ operator ที่สร้าง "สิ่งที่เล็กที่สุด" (integer unit)&lt;/p&gt;

&lt;p&gt;ปรัชญาของ Iverson: โปรแกรมมิ่งคือภาษาสำหรับ &lt;strong&gt;คิด&lt;/strong&gt; — ไม่ใช่แค่ภาษาสำหรับ &lt;strong&gt;บอกคอมพิวเตอร์ให้ทำงาน&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;APL พิสูจน์ว่า: โค้ดหนึ่งบรรทัดที่เต็มไปด้วยสัญลักษณ์ประหลาด สามารถทำสิ่งที่ภาษาอื่นใช้ 50 บรรทัด&lt;/p&gt;

&lt;p&gt;และ &lt;code&gt;⍳&lt;/code&gt; (iota) คือหัวใจของแนวคิดนี้ — สร้างลำดับจากความว่างเปล่า ด้วยสัญลักษณ์เดียว&lt;/p&gt;

&lt;h3&gt;
  
  
  สิ่งที่ APL iota ทำได้ — มากกว่าแค่นับเลข
&lt;/h3&gt;

&lt;p&gt;APL iota ไม่ได้สร้างแค่ &lt;code&gt;1 2 3&lt;/code&gt; — มันสร้างได้ทุกมิติ:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight j"&gt;&lt;code&gt;&lt;span class="err"&gt;⍳&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;   &lt;span class="err"&gt;→&lt;/span&gt;  &lt;span class="n"&gt;matrix&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="err"&gt;×&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt; &lt;span class="err"&gt;ของเลข&lt;/span&gt; &lt;span class="m"&gt;1..9&lt;/span&gt;
&lt;span class="err"&gt;⍳&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt;  &lt;span class="n"&gt;array&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt; &lt;span class="err"&gt;มิติ&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;และเมื่อรวมกับ operator ตัวอื่นของ APL — &lt;code&gt;⍳&lt;/code&gt; กลายเป็นอาวุธที่ทรงพลังอย่างไม่น่าเชื่อ:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight j"&gt;&lt;code&gt;&lt;span class="nf"&gt;+&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="err"&gt;⍳&lt;/span&gt;&lt;span class="m"&gt;100&lt;/span&gt;   &lt;span class="err"&gt;→&lt;/span&gt;  &lt;span class="m"&gt;5050&lt;/span&gt;   &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;ผลรวม&lt;/span&gt; &lt;span class="m"&gt;1..100&lt;/span&gt; &lt;span class="err"&gt;—&lt;/span&gt; &lt;span class="err"&gt;ใน&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt; &lt;span class="err"&gt;ตัวอักษร&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;+/⍳100&lt;/code&gt; — สี่ตัวอักษร คำนวณผลรวม 1 ถึง 100 — โค้ดที่ภาษาอื่นต้องใช้ loop&lt;/p&gt;

&lt;p&gt;นี่คือเหตุผลที่ APL ถูกเรียกว่า "ภาษาโปรแกรมมิ่งที่ทรงพลังที่สุดต่อจำนวนตัวอักษร"&lt;/p&gt;




&lt;h2&gt;
  
  
  จาก APL สู่ Bell Labs — เส้นทางของ iota
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Ken Thompson กับ APL
&lt;/h3&gt;

&lt;p&gt;ช่วงปลายยุค 60 — Ken Thompson (ผู้สร้าง Unix) เป็นคนหนึ่งที่หลงรัก APL&lt;/p&gt;

&lt;p&gt;เขาเขียน APL interpreter ด้วยตัวเอง — เช่นเดียวกับสมาชิกทีม Go อีกสองคน (Rob Pike และ Robert Griesemer) ที่ต่างคนต่างเคยเขียน APL interpreter มาก่อนเช่นกัน นี่คือจุดร่วมสำคัญที่ทำให้ทั้งสามคน "พูดภาษาเดียวกัน" เมื่อถึงเวลาออกแบบ Go&lt;/p&gt;

&lt;p&gt;มีบันทึกว่า Thompson เคยพูดว่า APL เป็นหนึ่งในแรงบันดาลใจสำคัญในการออกแบบ Unix philosophy — "ทำสิ่งเดียวแต่ทำให้ดี"&lt;/p&gt;

&lt;p&gt;เขาไม่ได้เอา APL syntax มาใช้ (Unix กับ Go ต่างจาก APL คนละขั้ว) — แต่เขาเอา &lt;strong&gt;วิธีคิด&lt;/strong&gt; มา: abstraction ที่ทรงพลัง, ความกระชับ, และความงามทางคณิตศาสตร์&lt;/p&gt;

&lt;h3&gt;
  
  
  Bell Labs — แหล่งรวมคนที่รู้จัก iota
&lt;/h3&gt;

&lt;p&gt;Bell Labs ช่วงยุค 70-80 คือสถานที่ที่รวมตัวนักคณิตศาสตร์-โปรแกรมเมอร์ที่เข้าใจ APL:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ken Thompson — ผู้สร้าง Unix, เขียน APL interpreter เอง&lt;/li&gt;
&lt;li&gt;Rob Pike — โตมาในยุคที่ APL เป็นตำนาน, เขียน APL interpreter เอง&lt;/li&gt;
&lt;li&gt;Robert Griesemer — ผู้ร่วมสร้าง Go, ก็เขียน APL interpreter ด้วยตัวเองเช่นกัน&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;นี่คือเหตุผลที่แท้จริงที่ทำให้ชื่อ &lt;code&gt;iota&lt;/code&gt; รู้สึก "ใช่" สำหรับทั้งทีม — ไม่ใช่แค่คนใดคนหนึ่งเสนอแล้วคนอื่นพยักหน้าตาม แต่ทั้งสามคนเข้าใจว่ามันคืออะไรและมาจากไหน&lt;/p&gt;

&lt;p&gt;ทุกคนในทีมที่สร้าง Unix, Plan 9, และต่อมา Go — รู้ว่า &lt;code&gt;iota&lt;/code&gt; คืออะไรและมาจากไหน&lt;/p&gt;

&lt;h3&gt;
  
  
  แนวคิด "sequence generator" ในตระกูล Unix
&lt;/h3&gt;

&lt;p&gt;ระหว่างทางจาก APL สู่ Go — แนวคิด iota ไม่ได้หายไป:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;C language&lt;/strong&gt; (1972): &lt;code&gt;enum&lt;/code&gt; — สร้าง constant sequence ได้ แต่ต้องประกาศชื่อ&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Plan 9 C&lt;/strong&gt;: ปรับปรุง &lt;code&gt;enum&lt;/code&gt; ให้ cleaner ขึ้น&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Limbo&lt;/strong&gt; (Inferno OS): constant declaration ที่ใกล้เคียง Go มากขึ้น&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pike และทีมเห็นว่า — การสร้าง enum/constant series ใน C น่าเบื่อและ verbose — ต้องเขียนเลขเองทุกบรรทัด&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="c1"&gt;// C — ต้องเขียนเลขเอง&lt;/span&gt;
&lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;READ&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;WRITE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;EXEC&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;เมื่อถึงเวลาออกแบบ Go — Pike รู้ดีว่าต้องมีอะไรดีกว่านี้&lt;/p&gt;




&lt;h2&gt;
  
  
  iota ใน Go — เกิดได้ยังไง
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ปัญหาที่ต้องแก้
&lt;/h3&gt;

&lt;p&gt;ทีม Go (Pike, Thompson, Griesemer) เริ่มออกแบบ Go ในปี 2007 — หนึ่งในเป้าหมายคือ: &lt;strong&gt;"ทำทุกอย่างให้ง่ายกว่า C"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;constant declaration ใน C/C++ เป็นหนึ่งใน pain point:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;ต้องเขียนค่าให้ทุก constant — แม้มันจะ predictable&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;enum&lt;/code&gt; กับ &lt;code&gt;#define&lt;/code&gt; อยู่คนละโลก&lt;/li&gt;
&lt;li&gt;bitmask/enum pattern ทำซ้ำซาก&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;ทีมต้องการอะไรที่:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;กระชับ — ไม่ต้องเขียนเลขซ้ำ&lt;/li&gt;
&lt;li&gt;flexible — ใช้กับ expression ได้ ไม่ใช่แค่ +1&lt;/li&gt;
&lt;li&gt;ไม่ใช่ magic — อ่านแล้วเข้าใจทันทีว่าเกิดอะไรขึ้น&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ตัวเลือกที่ทีมไม่เอา
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Auto-increment แบบ &lt;code&gt;enum&lt;/code&gt;&lt;/strong&gt; — ใช้ได้แค่ +1, ทำ bitmask ไม่ได้&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Preprocessor macro&lt;/strong&gt; — Go ไม่มี preprocessor (ตั้งใจ)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code generation&lt;/strong&gt; — ซับซ้อนเกินสำหรับของง่าย ๆ&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  iota — ทางสายกลาง
&lt;/h3&gt;

&lt;p&gt;Pike เสนอ &lt;code&gt;iota&lt;/code&gt; — constant generator ที่:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Reset ทุก &lt;code&gt;const&lt;/code&gt; block&lt;/strong&gt; — scope ชัดเจน&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;เป็น expression&lt;/strong&gt; — เอาไปคำนวณต่อได้&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reset เมื่อมี &lt;code&gt;const&lt;/code&gt; keyword ใหม่&lt;/strong&gt; — predictable
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;_&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;iota&lt;/span&gt;             &lt;span class="c"&gt;// 0&lt;/span&gt;
    &lt;span class="n"&gt;KB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="no"&gt;iota&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c"&gt;// 1 &amp;lt;&amp;lt; 10 = 1024&lt;/span&gt;
    &lt;span class="n"&gt;MB&lt;/span&gt;                     &lt;span class="c"&gt;// 1 &amp;lt;&amp;lt; 20&lt;/span&gt;
    &lt;span class="n"&gt;GB&lt;/span&gt;                     &lt;span class="c"&gt;// 1 &amp;lt;&amp;lt; 30&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ส่วนชื่อ — ไม่ต้องคิดนาน: มันคือการยกย่อง (homage) ให้ APL — ภาษาที่สร้างแรงบันดาลใจให้กับคนสร้าง Unix, Plan 9, และ Go&lt;/p&gt;




&lt;h2&gt;
  
  
  วิธีใช้ iota แบบต่าง ๆ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Enum พื้นฐาน
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Season&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;

&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;Spring&lt;/span&gt; &lt;span class="n"&gt;Season&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;iota&lt;/span&gt;  &lt;span class="c"&gt;// 0&lt;/span&gt;
    &lt;span class="n"&gt;Summer&lt;/span&gt;                &lt;span class="c"&gt;// 1&lt;/span&gt;
    &lt;span class="n"&gt;Autumn&lt;/span&gt;                &lt;span class="c"&gt;// 2&lt;/span&gt;
    &lt;span class="n"&gt;Winter&lt;/span&gt;                &lt;span class="c"&gt;// 3&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Bitmask
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Permission&lt;/span&gt; &lt;span class="kt"&gt;uint8&lt;/span&gt;

&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;Read&lt;/span&gt;    &lt;span class="n"&gt;Permission&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;iota&lt;/span&gt;  &lt;span class="c"&gt;// 1&lt;/span&gt;
    &lt;span class="n"&gt;Write&lt;/span&gt;                           &lt;span class="c"&gt;// 2&lt;/span&gt;
    &lt;span class="n"&gt;Execute&lt;/span&gt;                         &lt;span class="c"&gt;// 4&lt;/span&gt;
    &lt;span class="n"&gt;Admin&lt;/span&gt;                           &lt;span class="c"&gt;// 8&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;// ใช้:&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;perm&lt;/span&gt; &lt;span class="n"&gt;Permission&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Read&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Write&lt;/span&gt;  &lt;span class="c"&gt;// 3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Skip values
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;iota&lt;/span&gt;          &lt;span class="c"&gt;// 0 (skip)&lt;/span&gt;
    &lt;span class="n"&gt;Monday&lt;/span&gt;            &lt;span class="c"&gt;// 1&lt;/span&gt;
    &lt;span class="n"&gt;Tuesday&lt;/span&gt;           &lt;span class="c"&gt;// 2&lt;/span&gt;
    &lt;span class="n"&gt;Wednesday&lt;/span&gt;         &lt;span class="c"&gt;// 3&lt;/span&gt;
    &lt;span class="n"&gt;Thursday&lt;/span&gt;          &lt;span class="c"&gt;// 4&lt;/span&gt;
    &lt;span class="n"&gt;Friday&lt;/span&gt;            &lt;span class="c"&gt;// 5&lt;/span&gt;
    &lt;span class="n"&gt;Saturday&lt;/span&gt;          &lt;span class="c"&gt;// 6&lt;/span&gt;
    &lt;span class="n"&gt;Sunday&lt;/span&gt;            &lt;span class="c"&gt;// 7&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Multiple expressions ในบรรทัดเดียวกัน
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;bit0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mask0&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;iota&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;iota&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;  &lt;span class="c"&gt;// 1, 0&lt;/span&gt;
    &lt;span class="n"&gt;bit1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mask1&lt;/span&gt;                           &lt;span class="c"&gt;// 2, 1&lt;/span&gt;
    &lt;span class="n"&gt;bit2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mask2&lt;/span&gt;                           &lt;span class="c"&gt;// 4, 3&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Jump pattern
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;iota&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;    &lt;span class="c"&gt;// 0&lt;/span&gt;
    &lt;span class="n"&gt;b&lt;/span&gt;               &lt;span class="c"&gt;// 2&lt;/span&gt;
    &lt;span class="n"&gt;c&lt;/span&gt;               &lt;span class="c"&gt;// 4&lt;/span&gt;
    &lt;span class="n"&gt;d&lt;/span&gt;               &lt;span class="c"&gt;// 6&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  ทำไม iota ถึง "ใช่" สำหรับ Go
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Philosophy match
&lt;/h3&gt;

&lt;p&gt;Go มีหลักการ "หนึ่งวิธีที่ดีที่สุด" (one way to do it) — ต่างจาก Python ("หลายวิธีก็ดี") และ C++ ("มีทุกวิธี")&lt;/p&gt;

&lt;p&gt;&lt;code&gt;iota&lt;/code&gt; คือ "หนึ่งวิธี" ในการสร้าง enum/constant series — ใน Go คุณไม่ต้องเลือกว่าจะใช้ &lt;code&gt;#define&lt;/code&gt;, &lt;code&gt;enum&lt;/code&gt;, หรือ &lt;code&gt;constexpr&lt;/code&gt; — มีแค่ &lt;code&gt;iota&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Zero cost abstraction
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;iota&lt;/code&gt; ไม่มี overhead — มันถูก resolve ตอน compile — runtime ไม่รู้ด้วยซ้ำว่ามี &lt;code&gt;iota&lt;/code&gt; อยู่&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Readability
&lt;/h3&gt;

&lt;p&gt;เมื่อคุณเห็น &lt;code&gt;iota&lt;/code&gt; — คุณรู้ทันทีว่า "อ๋อ ชุดนี้เป็นลำดับ"&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;Info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;iota&lt;/span&gt;
    &lt;span class="n"&gt;Warning&lt;/span&gt;
    &lt;span class="n"&gt;Error&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;vs C:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;INFO&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;WARNING&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;ERROR&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;น้อยกว่า — แต่บอกอะไรได้มากกว่า&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Connection to history
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;iota&lt;/code&gt; เป็นหนึ่งใน easter egg ที่สวยงามของ Go — มันเชื่อมต่อกับ:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;APL&lt;/strong&gt; (1962) — ต้นกำเนิด&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bell Labs&lt;/strong&gt; — สถานที่ที่ Thompson, Ritchie, Pike ทำงาน&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unix philosophy&lt;/strong&gt; — ทำสิ่งเดียวให้ดี&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  นอกเรื่องนิดหน่อย — iota ในภาษาอื่น
&lt;/h2&gt;

&lt;p&gt;หลังจาก Go ใช้ &lt;code&gt;iota&lt;/code&gt; — หลายภาษาเริ่ม implement concept คล้าย ๆ กัน:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Rust&lt;/strong&gt;: ไม่มี &lt;code&gt;iota&lt;/code&gt; โดยตรง แต่ &lt;code&gt;enum&lt;/code&gt; + &lt;code&gt;#[repr]&lt;/code&gt; + &lt;code&gt;strum&lt;/code&gt; crate ให้ความสามารถใกล้เคียง&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zig&lt;/strong&gt;: &lt;code&gt;enum&lt;/code&gt; มี auto-increment แต่ไม่ flexible เท่า &lt;code&gt;iota&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Swift&lt;/strong&gt;: &lt;code&gt;enum&lt;/code&gt; รองรับ raw value แต่ต้องระบุ type&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ไม่มีใครทำได้สะอาดเท่า Go — เพราะไม่มีใครกล้าใช้ชื่อ &lt;code&gt;iota&lt;/code&gt; (หรืออาจเพราะไม่มีใครรู้ว่ามันคืออะไร)&lt;/p&gt;




&lt;h2&gt;
  
  
  สิ่งที่ iota สอนเรา
&lt;/h2&gt;

&lt;p&gt;ชื่อดีเปลี่ยนทุกอย่าง&lt;/p&gt;

&lt;p&gt;&lt;code&gt;iota&lt;/code&gt; ใน Go ทำแค่ auto-increment — เหมือน &lt;code&gt;__COUNTER__&lt;/code&gt; ใน C, &lt;code&gt;enumerate&lt;/code&gt; ใน Python&lt;/p&gt;

&lt;p&gt;แต่เพราะชื่อมัน — &lt;code&gt;iota&lt;/code&gt; กลายเป็นมากกว่า feature: มันคือ &lt;strong&gt;เรื่องราว&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;ทุกครั้งที่โปรแกรมเมอร์ Go สงสัยว่า "iota คืออะไร" — พวกเขาย้อนกลับไปถึง APL, ถึง Kenneth Iverson, ถึง Bell Labs, ถึงประวัติศาสตร์ของภาษาโปรแกรมมิ่ง&lt;/p&gt;

&lt;p&gt;และนั่นคือสิ่งที่ภาษาโปรแกรมมิ่งที่ดีทำ — ไม่ใช่แค่แก้ปัญหา แต่ &lt;strong&gt;เล่าเรื่อง&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  สรุป
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;iota&lt;/code&gt; เริ่มจากอักษรกรีกตัวเล็กที่สุด → กลายเป็น operator ใน APL (1962) → ถูกจดจำโดยทีม Bell Labs → และมาอยู่ใน Go ในฐานะ homage ให้กับประวัติศาสตร์ของ programming&lt;/p&gt;

&lt;p&gt;มันใช้เวลา 50 ปี — จากแนวคิดทางคณิตศาสตร์ สู่ภาษาโปรแกรมมิ่งที่ใช้ใน production ทั่วโลก&lt;/p&gt;

&lt;p&gt;และทั้งหมดเริ่มจากสัญลักษณ์เดียว: &lt;strong&gt;ι&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// 50 ปีของการเดินทาง — ใน 4 บรรทัด&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;APL&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;iota&lt;/span&gt;  &lt;span class="c"&gt;// 1962&lt;/span&gt;
    &lt;span class="n"&gt;Unix&lt;/span&gt;           &lt;span class="c"&gt;// 1969&lt;/span&gt;
    &lt;span class="n"&gt;Go&lt;/span&gt;             &lt;span class="c"&gt;// 2009&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;em&gt;ที่มา: Go Language Specification, "A Programming Language" โดย Kenneth Iverson (1962), Rob Pike's talks on Go design, Bell Labs oral history, APL Wiki&lt;/em&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>programming</category>
      <category>history</category>
    </item>
    <item>
      <title>"Plan 9 — ระบบปฏิบัติการที่โลกลืม แต่เปลี่ยนวิธีคิดเรื่อง OS ไปตลอดกาล"</title>
      <dc:creator>Gophernment</dc:creator>
      <pubDate>Sun, 02 Aug 2026 03:38:26 +0000</pubDate>
      <link>https://dev.to/gophernment/plan-9-rabbptibatikaarthiiolkluuem-aetepliiynwithiikhideruueng-os-aiptldkaal-41o</link>
      <guid>https://dev.to/gophernment/plan-9-rabbptibatikaarthiiolkluuem-aetepliiynwithiikhideruueng-os-aiptldkaal-41o</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;📅 เขียนเมื่อ: กรกฎาคม 2026&lt;br&gt;
⚠️ อ้างอิงจากเอกสารต้นฉบับของ Bell Labs และบันทึกของผู้พัฒนา&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;ถ้าผมถามว่า "ระบบปฏิบัติการที่เจ๋งที่สุดในโลกคืออะไร" — คุณคงตอบ Linux, macOS, หรือ Windows&lt;/p&gt;

&lt;p&gt;แต่ถ้าถาม Ken Thompson และ Dennis Ritchie — สองคนที่สร้าง Unix ขึ้นมา — พวกเขาจะตอบว่า &lt;strong&gt;Plan 9&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Plan 9 คือระบบปฏิบัติการที่ Bell Labs สร้างขึ้นในช่วงปลายยุค 80 ถึงต้นยุค 90 โดยทีมเดียวกับที่สร้าง Unix แต่มันไม่ใช่แค่ "Unix เวอร์ชันใหม่" — มันคือการเริ่มต้นใหม่ทั้งหมด&lt;/p&gt;

&lt;p&gt;และถึงแม้วันนี้แทบไม่มีใครใช้ Plan 9 — แนวคิดของมันแทรกซึมอยู่ในทุกระบบปฏิบัติการที่คุณใช้อยู่&lt;/p&gt;




&lt;h2&gt;
  
  
  จุดเริ่มต้น — "Unix เริ่มแก่แล้ว"
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ปัญหาที่ Unix สะสมมา
&lt;/h3&gt;

&lt;p&gt;Unix เกิดในปี 1969 — ตอนนั้นคอมพิวเตอร์คือเครื่องเดียวที่มี terminal ต่อพ่วง&lt;/p&gt;

&lt;p&gt;พอยุค 80 มาถึง โลกเปลี่ยน — network กลายเป็นเรื่องปกติ, graphics เริ่มสำคัญ, distributed computing เริ่มเกิด&lt;/p&gt;

&lt;p&gt;แต่ Unix ไม่ได้ถูกออกแบบมาเพื่อสิ่งเหล่านี้ มันถูก patch, extend, retrofit — จนกลายเป็นระบบที่ซับซ้อนเกินกว่าที่ผู้สร้างจะภูมิใจ&lt;/p&gt;

&lt;p&gt;Ken Thompson เคยพูดประมาณว่า: "Unix เริ่มต้นด้วยความเรียบง่าย แต่มันค่อย ๆ สะสมความซับซ้อนเข้าไปเรื่อย ๆ — ถึงเวลาที่ต้องเริ่มใหม่"&lt;/p&gt;

&lt;h3&gt;
  
  
  ทำไมต้องชื่อ Plan 9
&lt;/h3&gt;

&lt;p&gt;ชื่อ "Plan 9" มาจากหนัง B-movie สุดคลาสสิกเรื่อง &lt;em&gt;"Plan 9 from Outer Space"&lt;/em&gt; (1959) ของ Ed Wood — ที่ได้ชื่อว่าเป็น "หนังที่แย่ที่สุดตลอดกาล"&lt;/p&gt;

&lt;p&gt;แต่ชื่อนี้ไม่ได้หมายความว่า OS นี้แย่ — มันคือมุกวงในของทีม Bell Labs ที่ชอบตั้งชื่อแปลก ๆ (Unix เองก็เป็นมุก — มันล้อ Multics)&lt;/p&gt;




&lt;h2&gt;
  
  
  หัวใจของ Plan 9 — "ทุกอย่างคือไฟล์" จริง ๆ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  จาก Unix สู่ Plan 9 — ทำให้สุดทาง
&lt;/h3&gt;

&lt;p&gt;Unix มีแนวคิด famous: &lt;strong&gt;"everything is a file"&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;filesystem เป็นไฟล์ → &lt;code&gt;/home/user/document.txt&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;devices เป็นไฟล์ → &lt;code&gt;/dev/sda&lt;/code&gt;, &lt;code&gt;/dev/tty&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;processes เป็นไฟล์ → &lt;code&gt;/proc/1234&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;แต่มันมีข้อยกเว้น — network sockets, graphics, window system — สิ่งเหล่านี้ไม่ใช่ไฟล์ใน Unix&lt;/p&gt;

&lt;p&gt;Plan 9 เอาแนวคิดนี้ไป &lt;strong&gt;สุดทาง&lt;/strong&gt; — ใน Plan 9, &lt;strong&gt;ทุกอย่างคือไฟล์ ไม่มีข้อยกเว้น&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  9P — โปรโตคอลเดียวที่เชื่อมทุกอย่าง
&lt;/h3&gt;

&lt;p&gt;หัวใจของ Plan 9 คือ &lt;strong&gt;9P&lt;/strong&gt; — โปรโตคอลที่ทำให้ทุกอย่างสื่อสารกันผ่าน filesystem&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;หน้าต่าง GUI → mount เป็นไฟล์
network connection → mount เป็นไฟล์  
เครื่องอื่นใน network → mount เป็นไฟล์
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ลองนึกภาพ: คุณ &lt;code&gt;ls&lt;/code&gt; ดูไฟล์ในเครื่องคนอื่นได้เหมือนกับเป็น local disk — โดยไม่ต้องใช้ NFS, Samba, หรืออะไรซับซ้อนเลย&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ตัวอย่างจริง:&lt;/strong&gt; ถ้าผมเปิดหน้าต่าง editor (acme) ใน Plan 9 — หน้าต่างนั้นคือไฟล์ใน &lt;code&gt;/mnt/acme/&lt;/code&gt; คุณสามารถ &lt;code&gt;echo "hello" &amp;gt; /mnt/acme/body&lt;/code&gt; แล้วข้อความก็จะไปโผล่ใน editor ทันที&lt;/p&gt;

&lt;p&gt;GUI ของ Plan 9 ไม่ใช่ "โปรแกรมที่วาดรูปบนจอ" — มันคือ "filesystem ที่บังเอิญแสดงผลเป็นกราฟิกได้"&lt;/p&gt;

&lt;h3&gt;
  
  
  Namespace — มุมมองส่วนตัวของทุก process
&lt;/h3&gt;

&lt;p&gt;ใน Linux, ทุก process มองเห็น filesystem เดียวกัน&lt;/p&gt;

&lt;p&gt;ใน Plan 9, &lt;strong&gt;แต่ละ process มี namespace ของตัวเอง&lt;/strong&gt; — คุณสามารถ mount, unmount, และจัดเรียง filesystem ใหม่ได้โดยไม่กระทบ process อื่น&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Process A: /bin → /usr/local/bin
Process B: /bin → /remote/machine/bin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;สอง process นี้เห็น filesystem คนละชุด — แต่รันอยู่บนเครื่องเดียวกัน&lt;/p&gt;

&lt;p&gt;แนวคิดนี้คือต้นกำเนิดของ Linux namespaces ที่ใช้ใน Docker และ container ทุกวันนี้&lt;/p&gt;




&lt;h2&gt;
  
  
  ชีวิตใน Plan 9 — หน้าตาเป็นยังไง
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Rio — หน้าต่างที่ไม่มี title bar
&lt;/h3&gt;

&lt;p&gt;Rio คือ window system ของ Plan 9 — และมัน minimal สุด ๆ&lt;/p&gt;

&lt;p&gt;ไม่มี taskbar, ไม่มี desktop icons, ไม่มี minimize button — มีแต่หน้าต่างที่คุณจัดการด้วยเมาส์ 3 ปุ่ม&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ปุ่มซ้าย&lt;/strong&gt; = เลือกข้อความ&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ปุ่มกลาง&lt;/strong&gt; = execute (รันข้อความที่เลือก)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ปุ่มขวา&lt;/strong&gt; = เมนู (New, Resize, Delete ฯลฯ)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ลองนึกภาพการใช้งานจริง:&lt;/p&gt;

&lt;p&gt;คุณเปิดหน้าต่าง terminal ขึ้นมา — พิมพ์ &lt;code&gt;ls -la&lt;/code&gt; — ผลลัพธ์โผล่ในหน้าต่าง คุณใช้ปุ่มซ้ายลากเลือกชื่อไฟล์ที่สนใจ → กดปุ่มกลาง → Plan 9 เอาไฟล์นั้นมาเป็น argument ให้คำสั่งถัดไปโดยอัตโนมัติ&lt;/p&gt;

&lt;p&gt;หรือใน editor: คุณพิมพ์ &lt;code&gt;man 9p&lt;/code&gt; ใน buffer → ลากคลุม → ปุ่มกลาง → หน้าต่าง man page โผล่ขึ้นมาทันที&lt;/p&gt;

&lt;p&gt;ไอเดียคือ: &lt;strong&gt;คุณไม่ต้อง copy-paste — คุณแค่เลือกแล้ว execute&lt;/strong&gt; ทุกอย่างที่เลือกคือ command ได้หมด&lt;/p&gt;

&lt;p&gt;นี่คือ UX ที่ต่างจากสิ่งที่เราใช้ทุกวันนี้โดยสิ้นเชิง — ไม่มี clipboard, ไม่มี Ctrl-C/Ctrl-V — แต่เมื่อคุณชินแล้ว มันเร็วและ natural กว่ามาก&lt;/p&gt;

&lt;h3&gt;
  
  
  Acme — editor ที่เป็นมากกว่า editor
&lt;/h3&gt;

&lt;p&gt;Acme คือ text editor ในตำนานที่ Rob Pike สร้าง — และมันก็คือ "หน้าต่างที่ควบคุมด้วยเมาส์แบบ hypertext"&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ทุกคำใน Acme เป็น clickable link&lt;/li&gt;
&lt;li&gt;คุณพิมพ์คำสั่ง shell ลงไปใน buffer แล้วคลิก execute ได้เลย&lt;/li&gt;
&lt;li&gt;ไฟล์ทุกไฟล์ที่เปิดอยู่คือหน้าต่างที่จัดการได้ด้วย mouse gesture&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Acme ดู primitive สำหรับยุคนี้ — แต่มันคือต้นแบบของ IDE สมัยใหม่: code + terminal + file browser อยู่ในหน้าต่างเดียวกัน&lt;/p&gt;

&lt;h3&gt;
  
  
  Plumbing — messsage bus ก่อนจะมี D-Bus
&lt;/h3&gt;

&lt;p&gt;Plumbing คือระบบส่งข้อความระหว่างโปรแกรมใน Plan 9&lt;/p&gt;

&lt;p&gt;คุณ click ที่ URL → มันส่งไปให้ browser&lt;br&gt;
คุณ click ที่ error message → มันเปิดไฟล์ไปที่บรรทัดนั้น&lt;/p&gt;

&lt;p&gt;ทุกอย่างเชื่อมกันด้วยไฟล์ — และ plumbing ก็คือไฟล์พิเศษที่อ่านเขียนข้อความได้&lt;/p&gt;


&lt;h2&gt;
  
  
  มรดกของ Plan 9 — สิ่งที่อยู่รอดมาจนถึงวันนี้
&lt;/h2&gt;
&lt;h3&gt;
  
  
  1. UTF-8 — เกิดบนกระดาษรองจานในร้านอาหารแห่งหนึ่ง
&lt;/h3&gt;

&lt;p&gt;คืนหนึ่งในปี 1992 — Ken Thompson กับ Rob Pike นั่งกินข้าวที่ร้านอาหารสไตล์ diner แห่งหนึ่งใน New Jersey&lt;/p&gt;

&lt;p&gt;พวกเขาคุยกันเรื่องปัญหาที่โลกคอมพิวเตอร์มี encoding เป็นร้อย ๆ แบบ — ASCII, Latin-1, Shift-JIS — แต่ละตัวใช้กับภาษาเดียว&lt;/p&gt;

&lt;p&gt;ทั้งคู่หยิบกระดาษรองจานขึ้นมา แล้วออกแบบ &lt;strong&gt;UTF-8&lt;/strong&gt; — encoding ที่ backward compatible กับ ASCII และรองรับทุกภาษาในโลก&lt;/p&gt;

&lt;p&gt;วันนี้ UTF-8 ใช้ใน &lt;strong&gt;98% ของเว็บทั้งโลก&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;และมันถูกออกแบบระหว่างการพัฒนา Plan 9 — โดยคนของ Plan 9&lt;/p&gt;
&lt;h3&gt;
  
  
  2. &lt;code&gt;/proc&lt;/code&gt; filesystem — เกิดใน Unix แต่ Plan 9 ทำให้มันเป็นอย่างที่เราใช้
&lt;/h3&gt;

&lt;p&gt;Linux users รู้จัก &lt;code&gt;/proc&lt;/code&gt; — filesystem ที่เก็บข้อมูล process:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; /proc/cpuinfo    &lt;span class="c"&gt;# ดู CPU&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /proc/meminfo    &lt;span class="c"&gt;# ดูหน่วยความจำ&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;/proc&lt;/code&gt; เกิดครั้งแรกใน &lt;strong&gt;Unix รุ่น 8 (1984)&lt;/strong&gt; โดย Tom Killian — ผู้เขียน paper "Processes as Files" ที่นำเสนอใน USENIX เดือนมิถุนายน 1984 ซึ่งเกิดก่อน Plan 9 จะเริ่มพัฒนาด้วยซ้ำ&lt;/p&gt;

&lt;p&gt;แต่ &lt;code&gt;/proc&lt;/code&gt; ใน Unix 8 เป็นแบบ flat — หนึ่ง process = หนึ่งไฟล์&lt;/p&gt;

&lt;p&gt;Plan 9 คือคนที่พัฒนาแนวคิดนี้ต่อไป — ทำให้แต่ละ process เป็น &lt;strong&gt;directory&lt;/strong&gt; ที่มีหลายไฟล์ย่อย (ใช้ &lt;code&gt;ls&lt;/code&gt; ดู, &lt;code&gt;cat&lt;/code&gt; อ่านค่าต่าง ๆ ได้) — กลายเป็น hierarchical &lt;code&gt;/proc&lt;/code&gt; แบบที่เราใช้กันทุกวันนี้&lt;/p&gt;

&lt;p&gt;Linux สืบทอด hierarchical model นี้มาจาก Plan 9 — และทุกวันนี้ &lt;code&gt;/proc&lt;/code&gt; กลายเป็นมาตรฐาน&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Linux Namespaces — Container ทั้งหมดมีรากจาก Plan 9
&lt;/h3&gt;

&lt;p&gt;Docker, Kubernetes, container ทั้งหมด — ใช้ Linux namespaces ในการแยก process&lt;/p&gt;

&lt;p&gt;แนวคิด "แต่ละ process มีมุมมองของระบบที่แตกต่างกัน" — เกิดใน Plan 9&lt;/p&gt;

&lt;p&gt;พูดให้เห็นภาพ: Plan 9 คิดเรื่อง per-process namespace ตั้งแต่ปลายยุค 80 — ส่วน Linux namespaces ที่เป็นรากฐานของ Docker และ container ทั้งหมด เพิ่งมาใน kernel ราวปี 2008 หรือเกือบ 20 ปีให้หลัง&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Go — ภาษาโปรแกรมที่สืบทอด DNA จาก Plan 9
&lt;/h3&gt;

&lt;p&gt;Go ถูกสร้างโดย Rob Pike, Ken Thompson, และ Robert Griesemer — สามคนที่เคยทำงานบน Plan 9&lt;/p&gt;

&lt;p&gt;และ Go ก็เต็มไปด้วยแนวคิดจาก Plan 9:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Goroutines&lt;/strong&gt; — lightweight threads → ต้นแบบคือ lightweight processes ของ Plan 9&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Channels&lt;/strong&gt; — สื่อสารด้วยการส่งข้อความ → ต้นแบบคือ 9P และ plumbing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gofmt&lt;/strong&gt; — ทุกคนเขียนโค้ดหน้าตาเหมือนกัน → ต้นแบบคือ philosophy "หนึ่งวิธีที่ดีที่สุด" ของ Plan 9&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Static binary&lt;/strong&gt; — compile เป็นไฟล์เดียว → ต้นแบบคือ Plan 9 binaries&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Go คือ Plan 9 ในร่างของภาษาโปรแกรม&lt;/p&gt;




&lt;h2&gt;
  
  
  ทำไม Plan 9 ถึงไม่รุ่ง
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ปัญหาที่แก้ไม่ได้
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Chicken-and-egg problem&lt;/strong&gt; — ไม่มี applications เพราะไม่มี users → ไม่มี users เพราะไม่มี applications&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Licensing&lt;/strong&gt; — ยุค 90 Bell Labs ถูกขายต่อหลายมือ (AT&amp;amp;T → Lucent → ...) ทำให้ license ของ Plan 9 ซับซ้อน&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Linux ชนะไปแล้ว&lt;/strong&gt; — ตอน Plan 9 เริ่ม stable (กลางยุค 90), Linux กำลังโตเร็วและมี ecosystem ใหญ่กว่า&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hardware support&lt;/strong&gt; — Plan 9 รองรับ hardware น้อยมาก เทียบกับ Linux/Windows&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;แต่ปัญหาหลักคือ: &lt;strong&gt;Plan 9 ไม่ได้พยายามจะ "ดีกว่า Unix นิดหน่อย" — มันพยายามจะ "ใหม่หมด"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;และโลกไม่พร้อมจะเปลี่ยน OS ทั้งระบบเพื่อไอเดียใหม่ ๆ — ถึงแม้ไอเดียเหล่านั้นจะดีกว่า&lt;/p&gt;




&lt;h2&gt;
  
  
  Plan 9 ในปี 2026
&lt;/h2&gt;

&lt;p&gt;Plan 9 ยังมีชีวิตอยู่ — ในรูปแบบของ &lt;strong&gt;9front&lt;/strong&gt; (community fork) และ &lt;strong&gt;Plan 9 from User Space&lt;/strong&gt; (port ของ tools บน Linux/macOS)&lt;/p&gt;

&lt;p&gt;มีกลุ่ม enthusiasts ที่ใช้ Plan 9 เป็น daily driver — เล็ก แต่บ้าพลัง&lt;/p&gt;

&lt;p&gt;และทุก concept ที่ Plan 9 เคยคิด — ถูก implement ใหม่ใน Linux ในอีก 20 ปีต่อมา&lt;/p&gt;




&lt;h2&gt;
  
  
  สิ่งที่ Plan 9 สอนเรา
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;"แนวคิดที่ดีไม่ได้แปลว่าจะชนะ — แต่มันจะถูกขโมย"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Plan 9 ล้มเหลวในฐานะผลิตภัณฑ์ — แต่ชนะในฐานะแนวคิด&lt;/p&gt;

&lt;p&gt;ทุก container ที่รันอยู่บน Kubernetes...&lt;br&gt;
ทุก UTF-8 byte ที่ส่งผ่าน network...&lt;br&gt;
ทุก Go routine ที่ทำงานอยู่บน cloud...&lt;/p&gt;

&lt;p&gt;ทั้งหมดมี DNA ของ Plan 9 อยู่ในนั้น&lt;/p&gt;




&lt;p&gt;&lt;em&gt;ที่มา: Bell Labs Technical Journal, Plan 9 manual pages, Rob Pike's personal blog (herpolhode.com), 9fans.net, Wikipedia&lt;/em&gt;&lt;/p&gt;

</description>
      <category>plan9</category>
      <category>os</category>
      <category>history</category>
      <category>unix</category>
    </item>
    <item>
      <title>Russ Cox — คนที่ทำให้ Go เป็น ecosystem ไม่ใช่แค่ภาษา</title>
      <dc:creator>Gophernment</dc:creator>
      <pubDate>Fri, 31 Jul 2026 03:09:23 +0000</pubDate>
      <link>https://dev.to/gophernment/russ-cox-khnthiithamaih-go-epn-ecosystem-aimaichaekhphaasaa-295c</link>
      <guid>https://dev.to/gophernment/russ-cox-khnthiithamaih-go-epn-ecosystem-aimaichaekhphaasaa-295c</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;📅 กรกฎาคม 2026&lt;br&gt;
⚠️ อ้างอิงจากแหล่งปฐมภูมิ ตรวจสอบแล้ว — แต่เช็คข้อมูลล่าสุดก่อนแชร์&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;ถ้า Pike, Thompson, และ Griesemer คือคนสร้าง Go&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Russ Cox&lt;/strong&gt; คือคนที่ทำให้ Go โตจากภาษาใน Google เป็น ecosystem ที่คนทั้งโลกใช้ เขาเป็นคนเขียน &lt;code&gt;gofmt&lt;/code&gt; คนออกแบบ Go modules คนคิด Minimal Version Selection algorithm คนเขียน compatibility promise และปัจจุบันเป็น &lt;strong&gt;Go tech lead&lt;/strong&gt; — คนที่ตัดสินใจว่า Go จะไปทางไหนต่อ&lt;/p&gt;

&lt;p&gt;ทุกครั้งที่คุณพิมพ์ &lt;code&gt;go build&lt;/code&gt; แล้วมันทำงานในไม่กี่วินาที นั่นคือ Cox&lt;/p&gt;




&lt;h2&gt;
  
  
  เด็ก Plan 9 จาก MIT
&lt;/h2&gt;

&lt;p&gt;ตอนที่เพื่อนวัยเดียวกันใช้ Windows หรือ Mac Russ Cox ใช้ &lt;strong&gt;Plan 9&lt;/strong&gt; — ระบบปฏิบัติการที่ Rob Pike, Ken Thompson, และ Dennis Ritchie สร้างที่ Bell Labs&lt;/p&gt;

&lt;p&gt;เขาใช้มันเป็นระบบปฏิบัติการหลักทุกวัน&lt;/p&gt;

&lt;p&gt;ตอนเรียน MIT Cox ทำงานกับ Pike โดยตรงในโปรเจกต์ Plan 9 ร่วมเขียน paper "Security in Plan 9" (USENIX 2002) ทั้งที่ยังเป็นนักศึกษา&lt;/p&gt;

&lt;p&gt;แต่พอเว็บเริ่มสำคัญ Plan 9 ไม่มีเว็บเบราว์เซอร์ที่ใช้งานได้&lt;/p&gt;

&lt;p&gt;แทนที่จะย้ายไปใช้ OS อื่น Cox ทำสิ่งที่ programmer ดี ๆ จะทำ: &lt;strong&gt;port Plan 9 ทั้งระบบมาที่ Unix&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;plan9port คือ Plan 9 userspace ที่รันบน Linux และ macOS คุณสามารถใช้ &lt;code&gt;acme&lt;/code&gt; editor, &lt;code&gt;sam&lt;/code&gt; editor, &lt;code&gt;rc&lt;/code&gt; shell, &lt;code&gt;plumber&lt;/code&gt; — เครื่องมือทั้งหมดของ Plan 9 — บนเครื่องธรรมดา&lt;/p&gt;

&lt;p&gt;Cox ใช้ Acme เป็น editor หลักทุกวัน มาจนถึงทุกวันนี้&lt;/p&gt;

&lt;p&gt;นี่คือจุดที่ Pike สังเกตเห็นเขา "เด็กคนนี้เข้าใจ Plan 9 ดีพอที่จะ port มันมาทั้งระบบ"&lt;/p&gt;




&lt;h2&gt;
  
  
  Google Code Search และ RE2
&lt;/h2&gt;

&lt;p&gt;Cox ฝึกงานที่ Google ระหว่างเรียนปริญญาเอกที่ MIT&lt;/p&gt;

&lt;p&gt;งานที่ทำให้เขาเป็นที่รู้จักคือ &lt;strong&gt;RE2&lt;/strong&gt; — regular expression engine ที่เขาเขียนให้ Google Code Search&lt;/p&gt;

&lt;p&gt;ปัญหาของ regex engine ทั่วไปคือ catastrophic backtracking: บาง pattern ใช้เวลาค้นหาเป็นนาที, ชั่วโมง, หรือพังเลย เพราะ algorithm แบบ backtracking มี worst-case ที่ exponential&lt;/p&gt;

&lt;p&gt;Cox ใช้ automata theory จากงานวิจัยของเขา ออกแบบ RE2 ที่การันตี &lt;strong&gt;linear time&lt;/strong&gt; เสมอ ไม่ว่า pattern จะซับซ้อนแค่ไหน&lt;/p&gt;

&lt;p&gt;RE2 ถูกใช้ใน production ที่ Google ตั้งแต่ปี 2006 — Google Code Search, Google Sheets, และต่อมาเป็น &lt;code&gt;regexp&lt;/code&gt; package ใน Go standard library&lt;/p&gt;

&lt;p&gt;เขาเขียนบทความสามตอนที่กลายเป็น reference ของวงการ regex: "Regular Expression Matching Can Be Simple And Fast", "Regular Expression Matching: the Virtual Machine Approach", "Regular Expression Matching in the Wild"&lt;/p&gt;




&lt;h2&gt;
  
  
  2008 — Pike ชวนเข้าร่วมทีม Go
&lt;/h2&gt;

&lt;p&gt;Cox กำลังจะจบปริญญาเอกที่ MIT (วิทยานิพนธ์ "An Extension-Oriented Compiler") ตอนที่ Pike มาชวน&lt;/p&gt;

&lt;p&gt;Pike พูดว่า: "เราพยายามเอาทุกอย่างที่เรารักเกี่ยวกับการพัฒนา software บน Plan 9 มาทำให้มันใช้ได้กับการเขียน software ที่เราอยากเขียนที่ Google นายอยากช่วยไหม"&lt;/p&gt;

&lt;p&gt;Cox ตอบ: "Yeah, of course"&lt;/p&gt;

&lt;p&gt;เขากลายเป็น member คนที่ 4 ของทีม Go — ต่อจาก Pike, Thompson, Griesemer&lt;/p&gt;




&lt;h2&gt;
  
  
  gofmt — โปรเจกต์แรก
&lt;/h2&gt;

&lt;p&gt;งานแรกของ Cox ในทีม Go คือ &lt;strong&gt;gofmt&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;ธันวาคม 2009 เขาเขียน blog post ประกาศ gofmt — เครื่องมือที่ format โค้ด Go ให้หน้าตาเหมือนกันหมดโดยอัตโนมัติ&lt;/p&gt;

&lt;p&gt;ฟังดูเป็นเรื่องเล็ก แต่ gofmt คือหนึ่งในการตัดสินใจที่ฉลาดที่สุดในประวัติศาสตร์ Go&lt;/p&gt;

&lt;p&gt;ก่อน gofmt ทีม Go เสียเวลาเถียงกันเรื่อง style ว่า bracket ควรอยู่บรรทัดเดียวกับ if หรือบรรทัดใหม่ indent ควรเป็น tab หรือ space ควรเว้นวรรคหลัง comma ไหม&lt;/p&gt;

&lt;p&gt;หลัง gofmt ปัญหานี้หายไปตลอดกาล&lt;/p&gt;

&lt;p&gt;ทุกวันนี้ทุกโปรเจกต์ Go ในโลกหน้าตาเหมือนกัน ไม่ว่าคุณจะอ่านโค้ดของ Google, ของ startup, หรือของ open source contributor&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;code&gt;go&lt;/code&gt; command — คุณใช้มันทุกวันโดยไม่เคยคิดถึงมัน
&lt;/h2&gt;

&lt;p&gt;Cox เป็นคนออกแบบ &lt;code&gt;go&lt;/code&gt; command — &lt;code&gt;go build&lt;/code&gt;, &lt;code&gt;go test&lt;/code&gt;, &lt;code&gt;go get&lt;/code&gt; — ทั้งหมดที่คุณพิมพ์ทุกวัน&lt;/p&gt;

&lt;p&gt;แต่ผลงานที่เปลี่ยน Go ไปตลอดกาลคือ &lt;strong&gt;Go modules&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Go Modules — จุดเปลี่ยนของ Go ecosystem
&lt;/h2&gt;

&lt;p&gt;ก่อน Go 1.11 การจัดการ dependency ใน Go คือหายนะ&lt;/p&gt;

&lt;p&gt;&lt;code&gt;go get&lt;/code&gt; ดึงโค้ดจาก version control โดยตรง ไม่มี versioning ไม่มี lock file Dependency ของโปรเจกต์หนึ่งอาจ silently upgrade แล้วพังโปรเจกต์อีกโปรเจกต์&lt;/p&gt;

&lt;p&gt;กุมภาพันธ์ 2018 Cox เปิดตัว &lt;strong&gt;vgo&lt;/strong&gt; — prototype ของ Go modules ที่เขาเขียนคนเดียว&lt;/p&gt;

&lt;p&gt;แล้วเขาก็ทำสิ่งที่แทบไม่มีใครทำ: เขียน blog post 10 ตอนอธิบายการตัดสินใจทุกอย่าง&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ทำไมต้อง semantic import versioning&lt;/li&gt;
&lt;li&gt;Minimal Version Selection คืออะไร และทำไมมันดีกว่า SAT solving แบบ npm&lt;/li&gt;
&lt;li&gt; reproducible builds ทำงานยังไง&lt;/li&gt;
&lt;li&gt;หลักการของ versioning ใน Go&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Minimal Version Selection (MVS) เป็น algorithm ที่ Cox คิดขึ้นมาเอง แทนที่จะพยายามหา "best possible combination" ของ dependency versions แบบ npm (ซึ่งใช้ SAT solver และใช้เวลานานมาก) MVS เลือก version ต่ำสุดที่ satisfy requirement ของทุก module&lt;/p&gt;

&lt;p&gt;ผลลัพธ์: &lt;code&gt;go mod tidy&lt;/code&gt; ทำงานใน 2 วินาที แทนที่จะ resolve dependency tree เป็นนาที&lt;/p&gt;

&lt;p&gt;Go modules กลายเป็นมาตรฐานใน Go 1.13 และเป็น default ใน Go 1.16&lt;/p&gt;




&lt;h2&gt;
  
  
  Go Compatibility Promise — โค้ด 10 ปี compile ได้
&lt;/h2&gt;

&lt;p&gt;สิงหาคม 2023 Cox เขียน blog post "Backward Compatibility, Go 1.21, and Go 2"&lt;/p&gt;

&lt;p&gt;ประโยคเปิดของ post นั้นกลายเป็นคำขวัญของ Go:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Boring is good. Boring is stable. Boring means being able to focus on your work, not on what's different about Go."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Cox เป็นคน maintain compatibility promise ของ Go review ทุก change ที่อาจ break backward compatibility&lt;/p&gt;

&lt;p&gt;ลองนึกถึงภาษาอื่นที่โค้ดปี 2012 ไม่สามารถ compile ด้วย compiler ปี 2026 ได้โดยไม่ต้องแก้&lt;/p&gt;

&lt;p&gt;Go ทำได้ เพราะ Cox และทีมทุ่มเทให้ compatibility เป็นพระเจ้า&lt;/p&gt;




&lt;h2&gt;
  
  
  Transparent Decision-Making
&lt;/h2&gt;

&lt;p&gt;สิ่งที่ Cox เปลี่ยนวิธีทำงานของทีม Go ไม่ใช่แค่โค้ด แต่คือ &lt;strong&gt;กระบวนการ&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;เขาเป็นคนออกแบบ Go proposal process — ทุกการเปลี่ยนแปลงใหญ่ต้องผ่าน proposal สาธารณะบน GitHub พร้อม design doc ที่อธิบายปัญหา, ทางเลือก, และเหตุผล&lt;/p&gt;

&lt;p&gt;เขาเขียน blog post 6 ตอนอธิบายกระบวนการนี้: "Clarity &amp;amp; Transparency", "Large Changes", "Scaling Discussions" "Enabling Experiments", "Representation"&lt;/p&gt;

&lt;p&gt;ไม่มี "คนเก่งที่สุดในห้องตัดสินใจ" ทุกการตัดสินใจของ Go ตั้งแต่ Go 1.0 ถึงวันนี้ถูกบันทึกไว้เป็นลายลักษณ์อักษร&lt;/p&gt;

&lt;p&gt;นี่คือสิ่งที่ Cox เรียกว่า "language design in the service of software engineering" — การออกแบบภาษาไม่ใช่ศิลปะของอัจฉริยะ แต่เป็นวิศวกรรมที่มีกระบวนการ มีเหตุผล มีบันทึก&lt;/p&gt;




&lt;h2&gt;
  
  
  ปรัชญา
&lt;/h2&gt;

&lt;p&gt;GitHub bio ของ Cox เขียนว่า: &lt;strong&gt;"Go Hacker. Mistake maker."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;เขาไม่เคยแกล้งทำเป็นรู้ทุกอย่าง และนั่นคือสิ่งที่น่านับถือที่สุด&lt;/p&gt;

&lt;p&gt;ตอนให้สัมภาษณ์ GoTime ปี 2018 เขาพูดถึงความคาดหวังตอนแรก:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"My hope was that maybe a few people would notice, and ideally whatever the next big language to come along would steal the concurrency and the interface ideas from Go, and that would be our tiny little contribution to making programming a little bit better. Obviously, that didn't happen, but I'm okay with how it turned out instead."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;"หวังว่าไม่กี่คนจะสังเกตเห็น" — แล้ว Go ก็กลายเป็นภาษาที่ใช้ใน production ทั่วโลก&lt;/p&gt;




&lt;h2&gt;
  
  
  อีกด้านของ Cox — นักคณิตศาสตร์
&lt;/h2&gt;

&lt;p&gt;Cox ไม่ใช่แค่วิศวกร Go&lt;/p&gt;

&lt;p&gt;เขาเป็น &lt;strong&gt;President ของ OEIS Foundation&lt;/strong&gt; (Online Encyclopedia of Integer Sequences) — ฐานข้อมูลลำดับจำนวนเต็มที่ใหญ่ที่สุดในโลก นักคณิตศาสตร์และนักวิทยาศาสตร์คอมพิวเตอร์ใช้ OEIS เป็น reference มาตั้งแต่ปี 1964&lt;/p&gt;

&lt;p&gt;ผลงานล่าสุดบน blog ของเขา (2024-2026) ส่วนใหญ่เป็นเรื่อง floating-point formatting — ลงลึกถึงระดับ "Pull a New Proof from Knuth's Fixed-Point Printer" และ "Fast Unrounded Scaling: Proof by Ivy"&lt;/p&gt;

&lt;p&gt;เขาใช้ Ivy ภาษา calculator แนว APL ที่ Rob Pike เขียน พิสูจน์ความถูกต้องของ algorithm เชิงคณิตศาสตร์&lt;/p&gt;

&lt;p&gt;นี่คือคนที่วันหนึ่งออกแบบ Go modules, อีกวันใช้ formal proof พิสูจน์ว่า floating-point formatter ทำงานถูกต้อง&lt;/p&gt;




&lt;h2&gt;
  
  
  ผลงานอื่น ๆ
&lt;/h2&gt;

&lt;p&gt;ก่อน Go, Cox มีผลงานอีกมาก:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Vx32&lt;/strong&gt; sandboxing system (USENIX 2008)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vivaldi&lt;/strong&gt; network coordinate system (SIGCOMM 2004) — ใช้หา latency ระหว่าง node ใน distributed system โดยไม่ต้องวัดทุกคู่&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Xoc&lt;/strong&gt; extensible compiler (ASPLOS 2008)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;หลัง Go:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Go Memory Model&lt;/strong&gt; — เขียนบทความอธิบาย memory model ของ Go และ hardware memory models (2021-2022)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transparent Telemetry&lt;/strong&gt; — ระบบเก็บข้อมูลการใช้งาน Go toolchain แบบโปร่งใส (2022)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Coroutines for Go&lt;/strong&gt; — proposal สำหรับ coroutine ใน Go (กรกฎาคม 2023)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;xz backdoor analysis&lt;/strong&gt; — วิเคราะห์ timeline ของ backdoor ใน xz library (2024)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ทุกวันนี้
&lt;/h2&gt;

&lt;p&gt;Cox ยังเป็น Go tech lead ทำงานที่ Google Cambridge, MA ใช้ Acme editor ทุกวัน&lt;/p&gt;

&lt;p&gt;เขียน blog ที่ research.swtch.com อย่างสม่ำเสมอ 150+ บทความและยังเพิ่มขึ้นเรื่อย ๆ&lt;/p&gt;

&lt;p&gt;2024-2026: เขียนเรื่อง Go Changes, Go Testing By Example, floating-point formatting series, hash-based bisect debugging, differential coverage&lt;/p&gt;

&lt;p&gt;เขาไม่ได้เป็น keynote speaker ที่มีคนดูเป็นหมื่น แต่ทุกครั้งที่เขาเขียนอะไร คนในทีม Go และ community อ่าน&lt;/p&gt;




&lt;h2&gt;
  
  
  Cox กับโปรแกรมเมอร์ไทย
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;go mod tidy&lt;/code&gt; ที่ทำงานใน 2 วินาที คือ Cox&lt;/p&gt;

&lt;p&gt;&lt;code&gt;gofmt&lt;/code&gt; ที่ทำให้โค้ดทุกโปรเจกต์หน้าตาเหมือนกัน คือ Cox&lt;/p&gt;

&lt;p&gt;Compatibility promise ที่ทำให้โค้ด Go ปี 2012 ยัง compile ได้ในปี 2026 คือ Cox&lt;/p&gt;

&lt;p&gt;และวัฒนธรรม "ตัดสินใจแบบโปร่งใส เขียนเหตุผลให้อ่านได้" ที่กลายเป็น DNA ของ Go community&lt;/p&gt;

&lt;p&gt;คือสิ่งที่ Cox สร้าง&lt;/p&gt;




&lt;h2&gt;
  
  
  สรุป
&lt;/h2&gt;

&lt;p&gt;Rob Pike, Ken Thompson, Robert Griesemer คือคนสร้าง Go&lt;/p&gt;

&lt;p&gt;แต่ Russ Cox คือคนที่ทำให้มันอยู่รอด&lt;/p&gt;




&lt;p&gt;&lt;em&gt;ที่มา: swtch.com/~rsc, research.swtch.com, go.dev/blog, GoTime #77, github.com/rsc, github.com/google/re2, pdos.csail.mit.edu/~rsc&lt;/em&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>history</category>
      <category>softwareengineering</category>
    </item>
  </channel>
</rss>
