2 คะแนน โดย GN⁺ 2023-07-18 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • Forth เริ่มต้นจาก อินเทอร์พรีเตอร์ขนาดเล็ก ที่ Chuck Moore สร้างขึ้นเพื่อลดขั้นตอนการคอมไพล์และการใช้ punch card ที่ยาวซับซ้อน ก่อนจะเติบโตเป็นระบบที่ดูดรวมทั้งตัวแก้ไขข้อความ ระบบปฏิบัติการ และคอมไพเลอร์เข้าไว้ด้วยกัน
  • รูปแบบการเขียนแบบ postfix (RPN), data stack และ word (dictionary) ไม่ใช่ไวยากรณ์ประหลาด แต่เป็นการออกแบบเพื่อลดความสิ้นเปลืองและงานซ้ำบน ฮาร์ดแวร์ที่มีข้อจำกัดสูง
  • แก่นของ Forth อยู่ที่ โครงสร้างที่บูตสแตรปได้ ซึ่งทำให้สามารถนิยามและนิยามใหม่ได้จากภายในภาษาเอง แม้แต่ส่วนประกอบอย่าง :, ;, IF, คอมเมนต์ และตัวแปร
  • อิมพลีเมนเทชันอย่าง JonesForth, nasmjf, PlanckForth และ sectorforth แสดงให้เห็นว่า Forth สามารถเริ่มต้นจากขนาดเพียงหลักสิบถึงหลักร้อยไบต์ หรือจาก primitive เพียงไม่กี่ตัว แล้วขยายไปเป็นอินเทอร์พรีเตอร์ คอมไพเลอร์ แอสเซมเบลอร์ และ DSL ได้
  • กรณีของยานอวกาศ, Open Firmware, Jupiter Ace, Canon Cat, Harris RTX2010 และ GreenArrays แสดงให้เห็นว่า Forth สอดคล้องอย่างมากกับ การพัฒนาแบบอินเทอร์แอ็กทีฟ, โค้ดขนาดเล็ก, ความเป็นมิตรต่อฮาร์ดแวร์ และการประมวลผลพลังงานต่ำ

จุดเริ่มต้นจากตำนาน Usenet สู่การสำรวจ Forth

  • Dave Gauer ได้เรียบเรียงการเดินทางส่วนตัวในการค้นพบ Forth และวางมันไว้ในบริบทของประวัติศาสตร์คอมพิวเตอร์ โดยหน้านี้ดัดแปลงมาจากสไลด์การบรรยายสั้น
  • ในยุค 1990 กลุ่ม comp.* บน Usenet โดยเฉพาะ comp.lang.* เป็นพื้นที่สำคัญสำหรับการเรียนรู้และถกเถียงเรื่องการเขียนโปรแกรม
    • มีการยกตัวอย่างว่าประกาศเปิดตัว Linux ครั้งแรกของ Linus Torvalds ก็ถูกโพสต์บน comp.os.minix ในปี 1991
    • ช่วงปลายทศวรรษ 1990 Perl มีบทบาทสูงมากบนเว็บยุคแรกในฐานะภาษาสำหรับหน้าแบบไดนามิกและการประมวลผลฟอร์มผ่าน CGI
  • ตำนานที่พบในยุค Usenet เช่นภาษาในตระกูล Lisp, Y combinator, The Little Schemer และ The Story of Mel นำไปสู่ความสนใจใน Forth
  • ในตอนแรก Forth ปรากฏขึ้นผ่านเรื่องเล่าว่าเป็น “ภาษาที่ยืดหยุ่นพอจะเปลี่ยนค่าของจำนวนเต็มได้” และ Chuck Moore ก็ถูกจดจำเหมือน “mad wizard” ที่สามารถเขียนโปรแกรมอะไรก็ได้ด้วยโค้ดเพียงไม่กี่หน้าจอ
  • ซีรีส์บล็อก programming in the twenty-first century ของ James Hague กลายเป็นแรงกระตุ้นสุดท้ายให้เริ่มสำรวจ Forth

RPN และสแต็กเป็นเพียงจุดเริ่มต้น

  • ความประทับใจแรกของ Forth คือ รูปแบบการเขียนแบบ postfix หรือ Reverse Polish Notation (RPN)
    • ต่างจากรูปแบบ infix ทั่วไปอย่าง 3 + 4 Forth วางตัวดำเนินการไว้หลังตัวถูกดำเนินการ เช่น 3 4 +
    • ตัวอย่างใน Forth 3 4 * 5 6 * + . จะแสดงผล 42
    • ใน dc การคำนวณเดียวกันเขียนได้เป็น 3 4 * 5 6 * + p
  • RPN ทำให้สามารถคำนวณนิพจน์ที่ซ้อนกันได้ตามลำดับที่ต้องการโดยไม่ต้องใช้วงเล็บ
    • 3 4 * ให้ค่า 12, 5 6 * ให้ค่า 30 และ + ตัวสุดท้ายทำให้ได้ 42
    • ใน Forth . จะดึงค่าออกจากสแต็กแล้วพิมพ์ออกมา
  • เครื่องคิดเลข HP-35 เป็นตัวอย่างสำคัญทางประวัติศาสตร์ที่ทำให้ RPN เป็นที่รู้จักนอกวงการวิทยาการคอมพิวเตอร์
    • ช่วงต้นทศวรรษ 1970 HP มีเครื่องคิดเลขตั้งโต๊ะที่ทรงพลังอยู่แล้ว และ HP-35 ถูกยกเป็นตัวอย่างของการนำความสามารถนั้นมาใส่ไว้ในเครื่องคิดเลข “shirt pocket”
    • เครื่องคิดเลขของ HP มีชื่อเสียงจากไวยากรณ์แบบ RPN และแม้ RPN จะมีประสิทธิภาพ แต่สำหรับคนนอกก็ดูเข้าใจยากพอสมควร
  • ลักษณะเด่นข้อที่สองคือ data stack
    • การทำงานอย่าง PUSH, POP, SWAP, DUP ก็เป็น word ของ Forth ด้วย
    • เมื่อป้อนตัวเลข ค่านั้นจะถูกวางบนสแต็ก และตัวดำเนินการจะดึงค่าจากสแต็กไปคำนวณก่อนนำผลลัพธ์วางกลับเข้าไป
  • สแต็กช่วยลดความจำเป็นในการตั้งชื่อให้ค่ากลาง
    • ในภาษา imperative หลายภาษา มักต้องมีชื่อชั่วคราวอย่าง result2, matched_part3
    • วิธีทำงานแบบไม่ตั้งชื่อนี้ยังถูกเรียกว่า implicit, tacit หรือ point-free programming
    • การเข้าใจ Forth ด้วยแค่ RPN และสแต็กยังไม่เพียงพอ แต่ก็ถือเป็นจุดตั้งต้นที่เหมาะสมสำหรับทำความเข้าใจที่มาทางประวัติศาสตร์

Concatenative programming, Joy และความต่างของ Forth

  • เมื่อศึกษาลึกลงไปใน Forth ก็มักจะได้พบแนวคิดเรื่อง concatenative programming
    • ตัวอย่างแบบ applicative คือ eat(bake(prove(mix(ingredients))))
    • ตัวอย่างแบบ concatenative คือ ingredients mix prove bake eat
    • ฟังก์ชันถูกเรียงต่อกันตามลำดับ และค่าจากแต่ละขั้นจะถูกส่งต่อไปยังขั้นถัดไปโดยปริยาย
  • Joy เป็นตัวอย่างเด่นของ concatenative language
    • Manfred von Thun ได้แรงบันดาลใจจากปาฐกถา ACM Turing Award ปี 1977 ของ John Backus เรื่อง “Can Programming Be Liberated from the von Neumann Style?”
    • ใน Joy ทุกฟังก์ชันรับสแต็กหนึ่งก้อนเป็นอินพุต และคืนสแต็กหนึ่งก้อนเป็นเอาต์พุต
    • โปรแกรมคือรายการของฟังก์ชันที่อ่านจากซ้ายไปขวา
  • quotation และ combinator ของ Joy แสดงให้เห็นวิธีคำนวณแบบไร้ตัวแปร
    • ใน JavaScript [1, 2, 3, 4].map(n => n + 1) จะได้ [2,3,4,5]
    • ใน Joy สามารถได้ผลเดียวกันด้วย [1 2 3 4] [1 +] map
    • [] ใน Joy เป็นกลไก quotation ที่เก็บได้ทั้งข้อมูลและโปรแกรม ไม่ใช่แค่ข้อมูล
  • Combinator ถูกมองเป็น higher-order function ที่รับฟังก์ชันเป็นอินพุต
    • map() เป็นตัวอย่างของการนามธรรมแพตเทิร์นสำเร็จรูปสำหรับการวนผ่านลิสต์
    • combinator อย่าง I, K, S และ SKI calculus ปรากฏขึ้นในฐานะโครงสร้างที่ใช้อธิบายการคำนวณสากล
    • แค่ S และ K ก็เพียงพอจะสร้างระบบที่สมบูรณ์สำหรับการคำนวณสากลได้
  • Forth เองก็สามารถสร้าง higher-order function ได้ผ่าน execution token และ word EXECUTE
    • FOO EXECUTE จะรัน word ที่ word FOO ส่งกลับมา
    • สามารถนิยาม word เชิง combinatorial อย่าง MAP, FOLD, REDUCE ได้
  • แม้ Forth กับ Joy จะมีไวยากรณ์ภายนอกคล้ายกัน แต่แนวทางตีความนิพจน์ต่างกัน
    • ใน Forth 2 3 + ถูกอ่านว่า “push 2 และ 3 ลงสแต็กแล้วนำมาบวกกัน”
    • ใน Joy จะถูกอ่านว่า “composition ของฟังก์ชัน 2, 3 และ + เทียบเท่ากับฟังก์ชัน 5”
    • Forth เป็นภาษาที่เติบโตขึ้นจาก การปฏิสัมพันธ์กับฮาร์ดแวร์ มากกว่าจะยึดหลักการเชิงนามธรรมของ concatenative computing

เส้นทางที่ Chuck Moore สร้าง Forth

  • ในปี 1958 Chuck Moore ใช้ Fortran และ IBM 704 ระหว่างช่วงที่อยู่กับ Smithsonian Astrophysical Observatory และ MIT
    • Moore กล่าวไว้ใน Forth, the Early years ว่า “Compiling took 30 minutes...you got one shot per day”
    • มีการอ้างถึงด้วยว่า IBM 704 เป็นคอมพิวเตอร์หลอดสุญญากาศขนาดเต็มห้อง และโดยเฉลี่ยเสียทุกประมาณ 8 ชั่วโมง
  • Moore สร้างอินเทอร์พรีเตอร์แบบง่ายที่อ่านการ์ดซึ่งควบคุมโปรแกรม เพื่อลดการคอมไพล์ซ้ำ
    • ทำให้สามารถจัดชุดสมการที่ต่างกันสำหรับหลาย satellite ได้โดยไม่ต้อง recompile
    • รูปแบบอินพุตแบบ free-form เชื่อถือได้มากกว่าคอลัมน์ที่ฟอร์แมตตายตัวของ Fortran สำหรับการเขียนโดยมนุษย์
    • ระบบนี้กลายเป็นต้นกำเนิดของระบบที่ภายหลังถูกเรียกว่า Forth
  • ในปี 1961 ที่ Stanford Moore ใช้ Burroughs B5500 และเขียน mathematical application ชื่อ CURVE
    • CURVE มี interpreter ที่ซับซ้อนขึ้น, data stack และ control flow operator
    • ความสามารถโดยคร่าว ๆ เทียบได้กับ Forth word อย่าง IF ELSE DUP DROP SWAP + - *
    • มีการเพิ่ม parameter stack และความสามารถในการนิยาม procedure ใหม่ ทำให้เริ่มมีโครงสร้างที่ใกล้กับ Forth
  • ราวปี 1965 เมื่อเกิดสภาพแวดล้อม teletype, paper tape, timesharing และ interactive terminal ขึ้น Forth ก็มีความโต้ตอบมากขึ้น
    • มีการเพิ่ม word อย่าง KEY, EMIT, CR, SPACE, DIGIT
    • word เหล่านี้เปลี่ยนระบบของ Moore ให้กลายเป็น program editor และผู้ใช้สามารถแก้ไข program ภายใน program ได้
  • ในปี 1968 ที่ Mohasco Moore ทำงานกับ IBM 1130 และตั้งชื่อว่า “FORTH”
    • IBM 1130 เป็นระบบ 16 บิต พร้อม RAM 8KB และจำกัดชื่อไฟล์ไว้ที่ 5 ตัวอักษร
    • ระบบ “fourth generation” ของ Moore จึงกลายเป็น FORTH เพราะข้อจำกัด 5 ตัวอักษร
    • ช่วงเวลานี้มีการเพิ่ม return call stack และ word dictionary
  • word dictionary แบบมีชื่อของ Forth ทำหน้าที่เป็น abstraction หลัก
    • : DOUBLE DUP + ;
    • : QUAD DOUBLE DOUBLE ;
    • หากไม่มี return stack ก็จะไม่สามารถกลับไปยังตำแหน่งที่เหลือของ QUAD ได้หลังจากรัน DOUBLE

NRAO, การพอร์ต, และ indirect threaded code

  • ช่วงต้นทศวรรษ 1970 Moore เขียนซอฟต์แวร์ควบคุมคอมพิวเตอร์สำหรับ radio telescope ที่ National Radio Astronomy Observatory
    • NRAO มีนโยบายให้ใช้ Fortran บน minicomputer แต่ Moore ได้รับอนุญาตให้ใช้ Forth จากความสำเร็จก่อนหน้านั้น
    • ในงาน spectral-line observing สามารถแสดง spectra ที่กำลังเก็บข้อมูลอยู่ และ fit line-shapes ด้วย least-squares ได้
    • งานนี้ผลักดัน state-of-the-art ของ online data reduction และนักดาราศาสตร์ก็นำไปใช้ค้นพบและทำแผนที่ inter-stellar molecules
  • Elizabeth “Bess” Rather ยอมรับ Forth และเขียน Forth manual ฉบับแรกในปี 1972
    • ต่อมาเธอร่วมก่อตั้ง FORTH, Inc กับ Chuck Moore
    • จนเกษียณในปี 2006 เธอยังคงเป็นหนึ่งในผู้เชี่ยวชาญและผู้ผลักดันหลักของภาษา Forth
  • Forth ถูกพอร์ตไปยังหลายเครื่อง เช่น IBM 360/50, Honeywell 316, Honeywell DDP-116, DEC PDP-11
    • Forth implementation สำหรับ H316 ถูกพัฒนาอยู่บนคอมพิวเตอร์เครื่องนั้นเอง และถูกใช้เพื่อสร้าง Forth ตัวอื่น ๆ จึงถือเป็น implementation แบบ complete และ stand-alone ตัวแรก
    • PDP-11 เป็น minicomputer สำคัญที่เชื่อมโยงกับประวัติศาสตร์ของ Unix และภาษา C
  • เบื้องหลังที่ทำให้พอร์ตไปหลายเครื่องได้คือ indirect threaded code
    • ในที่นี้ threaded code ไม่เกี่ยวกับ concurrency หรือ multi-threaded programming
    • threaded code เก็บรายการ address ของ subroutine แทน instruction สำหรับเรียก subroutine
    • การรันรายการ address นี้ต้องมี code interpreter
  • indirect threaded code เก็บรายการ address ที่ชี้ไปยัง address ซึ่งชี้ไปยัง code อีกทอดหนึ่ง ไม่ได้ชี้ไปยัง code โดยตรง
    • indirection ชั้นที่สองนี้ทำให้สามารถมี inner interpreter แยกต่างหากสำหรับแต่ละชนิดของ subroutine ได้
    • ใน Forth นั้น outer interpreter คือส่วนที่ผู้ใช้โต้ตอบผ่าน terminal ส่วน inner interpreter จะรันส่วนที่เหลือของ word
  • ณ จุดนี้ Forth ได้ขยายจาก command interpreter แบบง่าย ไปเป็นทั้ง interactive language, editor, operating system และวิธีเก็บกับรันโค้ด
    • มีการสรุปคุณลักษณะว่าเป็น postfix notation, stack-oriented, concatenative style, interpreted, ปรับตัวเข้ากับ machine architecture ได้สูง, และมีขนาดกะทัดรัดมาก
    • Forth ไม่ใช่ภาษาที่ถูกออกแบบขึ้นครั้งเดียวในปี 1958 แต่เป็นผลลัพธ์ที่ Moore ค่อย ๆ ทำให้เติบโตตามความต้องการของตนเองและฮาร์ดแวร์ใหม่

หากอยากเข้าใจ Forth ก็ต้อง implement Forth

  • ในคำแนะนำ “To understand Forth, you have to implement a Forth” คำที่สำคัญคือ a Forth
    • จากมุมมองของ Chuck Moore ระบบ Forth จะดีที่สุดเมื่อถูกปรับแต่งให้เหมาะกับ system และ task นั้น ๆ โดยเฉพาะ
  • ก่อนจะลงมือกับซอร์สของ JonesForth ผู้เขียนได้ทำ Assembly Nights เพื่อเรียนพื้นฐาน assembly และ Linux ABI
    • JonesForth ใช้ซอร์ส i386 assembly ที่เขียนด้วย GNU GAS assembler
    • รองรับเฉพาะ 32-bit และใช้ Linux system call ABI โดยตรง
    • ผู้เขียนใช้เวลาราว 1 ปีในการพอร์ต JonesForth เป็นสำเนาที่ทำงานด้วย NASM assembler และพอร์ตนี้คือ nasmjf
  • ระหว่างการพอร์ต nasmjf ผู้เขียนได้เรียนรู้วิธีทำงานของ indirect threaded Forth แบบดั้งเดิม
    • jonesforth.S ของ JonesForth เป็นไฟล์เดียวที่เก็บส่วน assembly และ Richard W.M. Jones อธิบายลำดับการทำงานของ interpreter ด้วย ASCII art และคำอธิบาย
    • ผู้เขียนจึงเขียนไดอะแกรม ASCII art จำนวนมากไว้ในซอร์ส nasmjf เพื่อจัดระเบียบความเข้าใจของตนเอง
  • macro NEXT คือ flow หลักที่ใช้ขยับจาก word หนึ่งไปยัง word ถัดไปหลังการรัน
%macro NEXT 0
    lodsd     ; NEXT: Load from memory into eax, inc esi to point to next word.
    jmp [eax] ; Jump to whatever code we're now pointing at.
%endmacro
  • lodsd จะย้าย double word จาก memory ไปยัง eax และอัปเดตให้ชี้ไปยังตำแหน่งถัดไป
  • jmp [eax] จะย้ายการรันไปยังตำแหน่งที่กำลังชี้อยู่ และกลายเป็น inner interpreter ของ subroutine นั้น
  • ใน Forth แบบดั้งเดิม โดยพื้นฐานจะมีทั้ง code word และ colon word
    • code word คือ primitive ที่เขียนด้วย machine code
    • colon word คือ word ทั่วไปที่เขียนด้วยภาษา Forth และประกอบขึ้นโดยคอมไพเลอร์ :
    • colon word ลงท้ายด้วย EXIT และ EXIT จะจัดการ return stack ก่อนส่ง flow ต่อไปยัง NEXT
  • Forth เป็นโครงสร้างที่ชิ้นส่วนเล็กมาก ๆ ทำงานร่วมกันจนกลายเป็นระบบที่กำลังรันอยู่
    • ในระดับล่างจะได้ความยืดหยุ่นและความเรียบง่าย แต่ในระดับสูงอาจต้องแลกด้วยความเข้าใจที่ง่ายน้อยลง

code word, colon word และ compiler ทำงานอยู่บน interpreter ตัวเดียวกัน

  • SWAP, DUP, DROP แสดงให้เห็นว่า Forth primitive สามารถถูกอิมพลีเมนต์ให้ตรงกับ machine code ได้มากเพียงใด
DEFCODE "SWAP",SWAP,0
    pop eax
    pop ebx
    push eax
    push ebx
NEXT
DEFCODE "DUP",DUP,0
    mov eax, [esp]
    push eax
NEXT
DEFCODE "DROP",DROP,0
    pop eax
NEXT
  • JonesForth ใช้ i386 call/return stack เป็น Forth parameter stack จึงอิมพลีเมนต์ stack operation ด้วย pop และ push แบบ native
  • nasmjf มี code word อยู่ 130 ตัว ซึ่งส่วนใหญ่มีไว้เพื่อประสิทธิภาพ
    • มีค่าต่ำสุดในทางทฤษฎีของจำนวน machine-code word ที่จำเป็นสำหรับ Forth system แบบ bootstrappable
    • หากลดจำนวน primitive มากเกินไป Forth code ที่เหลืออาจไม่มีประสิทธิภาพและบิดเบี้ยวเกินไป
    • งานของ Frank Sergeant A 3-INSTRUCTION FORTH FOR EMBEDDED SYSTEMS WORK กล่าวถึง Forth แบบ 3-instruction บน Motorola MC68HC11 ที่ต้องใช้เพียง 66 bytes
    • sectorforth คือ Forth สำหรับ x86 แบบ 16-bit ที่อยู่ใน boot sector ขนาด 512-byte
  • colon word คือวิธีสร้าง word ใหม่จากการประกอบ word ที่มีอยู่แล้ว
: SDD SWAP DROP DUP ;
  • SDD ให้ผลเหมือนกับการเรียก SWAP DROP DUP ตามลำดับ
  • ในมุมมองของ indirect threaded code, colon word คือสถานะที่ถูก compile เป็น inner interpreter address ของ code word ทั้งสามตัว
  • : และ ; ดูเหมือน syntax แต่จริง ๆ แล้วเป็น Forth word
    • : จะรับชื่อของ word ใหม่และเปิด compile mode
    • ; จะทำ dictionary entry ใหม่ให้เสร็จสมบูรณ์และปิด compile mode
    • ผู้ใช้สามารถแทนที่ : เองด้วย definition ของตนเพื่อขยายหรือเปลี่ยน Forth ได้
    • syntax เพียงอย่างเดียวของ Forth คือ whitespace ระหว่าง input token
  • ใน Forth การ compile คือการใส่ word address หรือตัว literal พร้อม push code ลงใน memory
    • ใน normal mode จะรัน word ทันที
    • ใน compile mode จะเก็บ word address ลงใน memory
    • interpreter ตัวเดียวกันทำทั้งการรัน code และการ compile code
  • control structure อย่าง IF...THEN ก็สามารถอิมพลีเมนต์ด้วย Forth เองได้
: IF IMMEDIATE ' 0BRANCH , HERE @ 0 , ;

: THEN IMMEDIATE DUP HERE @ SWAP - SWAP ! ;
  • แม้องค์ประกอบพื้นฐานอย่าง IF ก็ยังถูกนิยามอยู่ภายในภาษาเอง นี่จึงเป็นเหตุผลสำคัญของชื่อ “The programming language that writes itself”
  • nested comment แบบ ( ... ) ก็ถูกอิมพลีเมนต์ด้วย Forth ใน jonesforth.f
    • แม้แต่ comment เองก็ยังถูกอิมพลีเมนต์อยู่ภายในภาษา และผู้ใช้สามารถนิยามใหม่หรือเพิ่มรูปแบบ comment ของตนเองได้
    • ตัวอย่างนี้เน้นให้เห็นว่า Forth แทบไม่มี native syntax เลย

Dictionary และการนิยามทับทำให้เกิดความขยายได้

  • โดยดั้งเดิมแล้ว Forth dictionary ใช้ linked list และการจับคู่คำจะเริ่มจาก entry ล่าสุด
    • definition ล่าสุดของคำชื่อเดียวกันจะบัง definition ก่อนหน้า
    • สามารถนิยามทับคำใดก็ได้ และแม้แต่คำที่นิยามครั้งแรกด้วย assembly ก็ยังนิยามทับได้
    • word ที่ถูก compile ไปแล้วจะเก็บ address ไม่ใช่ชื่อ จึงยังคงชี้ไปยัง address ของ word ก่อนการนิยามทับ
  • สามารถเรียกคำก่อนหน้าที่ชื่อเดียวกันจาก definition ใหม่เพื่อขยายความสามารถของคำได้
    • เมื่อต้องสร้าง recursive word, : จะซ่อนหรือทำเครื่องหมายให้ word ที่กำลัง compile อยู่ไม่พร้อมใช้งานใน dictionary
    • หากต้องการเรียกตัวเองจากภายใน word ปัจจุบัน ต้องใช้ RECURSE
  • ตัวอย่างตัวแปรแอปเปิลที่ดัดแปลงมาจาก Thinking Forth ของ Leo Brodie แสดงให้เห็นความยืดหยุ่นของ Forth
    • VARIABLE APPLES จะสร้าง word APPLES ที่เมื่อเรียกแล้วจะวาง memory address ลงบน stack
    • 20 APPLES ! จะเก็บค่า 20 ลงใน address นั้น
    • APPLES ? จะดึงค่าออกมาและแสดงผล
    • Thinking Forth (PDF) เปิดให้อ่านฟรี
  • แม้ต้องติดตามแอปเปิลสีแดงและสีเขียวแยกกัน ก็ยังไม่จำเป็นต้องแก้โค้ดเดิมที่ใช้ APPLES
VARIABLE COLOR

VARIABLE REDS
: RED REDS COLOR ! ;

VARIABLE GREENS
: GREEN GREENS COLOR ! ;

: APPLES COLOR @ ;
  • APPLES ตัวใหม่ก็ยังเป็น word ที่วาง address ลงบน stack ดังนั้นรูปแบบการใช้ APPLES ! และ APPLES ? เดิมจึงยังคงเดิม
  • มีเพียง address เท่านั้นที่เปลี่ยนไปเป็น REDS หรือ GREENS ตามสีแอปเปิลที่กำลังใช้งาน
  • ในมุมมองของภาษาทั่วไป สิ่งนี้อาจดูเหมือนตัวแปรถูกเปลี่ยนเป็นฟังก์ชัน แต่ใน Forth ทั้งตัวแปรก็เป็น word ที่วาง address และฟังก์ชันก็เป็น word เช่นกัน จึงไม่มีการเปลี่ยนระดับแนวคิดของภาษา
  • token ที่ดูเหมือนตัวเลขก็สามารถนิยามใหม่เป็น dictionary word ได้
: 4 12 ;
  • เมื่อรัน ." The value of 4 is " 4 . CR จะได้ผลลัพธ์ The value of 4 is 12

Meow5 และ Forth ในฐานะ “เส้นทางที่มีแรงต้านน้อยที่สุด”

  • nasmjf ซึ่งเป็นการพอร์ต JonesForth ไปยัง NASM ไม่ใช่การจำลองกระบวนการของ Moore แต่เป็นการฝึกแบบ “master copy” ที่เฝ้าสังเกตผลลัพธ์สุดท้ายอย่างละเอียดมากกว่า
  • หลังจากนั้น ผู้เขียนได้ทำการทดลอง programming แบบ concatenative สุดขั้วชื่อ Meow5
    • Meow5 เป็นการทดลองที่ต่อโค้ดทุกอย่างเข้าด้วยกันและ inline ตลอดเวลา
    • มันเป็น concatenative เพราะใช้แนวคิด parameter stack แบบเดียวกับ Forth
    • เป็นการทดลองทางความคิดที่ผลักไปจนสุดว่า ถ้าแทนที่จะเก็บ function call address เราเก็บสำเนาของฟังก์ชันทั้งหมดจะเป็นอย่างไร
  • หัวใจของ Meow5 คือการทำทุก word ให้เป็น 100% inline
    • แนวคิดนี้เริ่มจาก inline expansion ซึ่งเป็นการปรับแต่งประสิทธิภาพทั่วไปเพื่อหลีกเลี่ยง overhead ของการเรียกฟังก์ชันขนาดเล็ก
    • การเรียก primitive ที่มีเพียงคำสั่งเดียวอย่าง DROP ผ่านการกระโดดหลายครั้งดูเป็นความสิ้นเปลือง
  • Meow5 จบลงแบบ “ความล้มเหลวเล็ก ๆ ที่น่ารื่นรมย์”
    • ตัวการ inline machine code เองทำงานได้ดี และไฟล์ปฏิบัติการ ELF ที่ส่งออกมาก็ทำงานตามที่ตั้งใจ
    • ปัญหาอยู่ที่ข้อมูลสตริง เพราะต้องคัดลอกสตริงทุกครั้ง หรือไม่ก็ต้องติดตามอย่างซับซ้อนว่า word ไหนใช้สตริงใด
    • INLINE word ของ Forth ที่เปิดให้ inline แบบเลือกได้จึงถูกมองว่าเป็นวิธีที่ดีกว่า
  • ในเรื่อง syntax ของสตริงก็เป็นการยืนยันคำแนะนำของ Moore อีกครั้ง
    • ใน Forth ใช้ word ชื่อ " ดังนั้นจึงต้องมีช่องว่างแบบ " Hello World."
    • Meow5 เลือกรูปแบบ quoting ที่เป็นธรรมชาติกว่าอย่าง "Hello World." พร้อม escape sequence เช่น \n, \"
    • การเลือกนี้ทำให้ต้องมีการจัดการกรณีพิเศษของ " กระจายอยู่ใน tokenizer และ interpreter หลายจุด ส่งผลให้ความบริสุทธิ์และความเรียบง่ายลดลง
  • เมื่อเริ่มเดินตามเส้นทางของ Forth แล้ว ส่วนที่เหลือก็ดูเหมือนจะ “เขียนตัวเอง” ต่อไป
    • Forth คือการ bootstrapping, เป็น metaprogramming และสามารถเป็น OS กับ IDE/editor ได้
    • สิ่งนี้นำไปสู่ข้อสรุปว่า หากคุณกำลังสร้าง interpreter ที่ง่ายที่สุดสำหรับ CPU architecture แบบใหม่ทั้งหมด คุณอาจลงเอยด้วยสิ่งที่คล้าย Forth

การทำ Forth ขนาดเล็กและการใช้งานจริง

  • Forth สามารถนิยาม Forth เพิ่มเติมได้จากภายใน Forth เอง และ Forth หลายตัวก็มี assembler รวมมาด้วย
    • ตอนท้ายของ JonesForth มี stub ของ assembler ที่ทำงานอยู่ใน Forth
    • ;CODE จะอัปเดต header เพื่อให้ codeword ชี้ไปยัง assembled code แทน DOCOL
  • PlanckForth เป็นไบนารี Forth ที่เขียนด้วยมือและมีขนาดต่ำกว่า 1KB
    • ทั้งไบนารี ELF ที่สมบูรณ์และ Forth implementation ที่ใช้งานได้จริงอยู่ในขนาดต่ำกว่า 1KB
    • bootstrap.fs เริ่มต้นจากโอเปอเรเตอร์ที่เข้าใจยากในช่วงแรก แล้วอีกไม่กี่ร้อยบรรทัดต่อมากลายเป็น Forth ที่อ่านง่าย
  • ตัวอย่าง implementation ขนาดเล็กแสดงให้เห็นความกะทัดรัดอย่างสุดขั้วของ Forth
    • SmithForth เป็น machine code Forth ที่ David Smith เขียนด้วยมือ และถูกแนะนำว่าเป็นระบบ Forth ขนาด 1,000 ไบต์และ 1,000 บรรทัด
    • sectorforth เป็น boot sector Forth ขนาด 512 ไบต์
  • Forth ถูกใช้ในโรงไฟฟ้า หุ่นยนต์ ระบบติดตามขีปนาวุธ ระบบอัตโนมัติในอุตสาหกรรม ภาษาฝังตัวในวิดีโอเกม ฐานข้อมูล งานบัญชี โปรแกรมประมวลผลคำ กราฟิก ระบบคำนวณ Open Firmware boot loader และบนโปรเซสเซอร์กับไมโครคอนโทรลเลอร์หลากหลายชนิด
  • Open Firmware เป็นกรณีสำคัญที่มาจากงานวิศวกรรมของ Sun Microsystems
    • เพราะมีพื้นฐานเป็น interactive programming language จึงสามารถทดสอบและ bring-up ฮาร์ดแวร์ใหม่ได้อย่างมีประสิทธิภาพ
    • ในกรณีของ Space Shuttle ESN นั้น Open Firmware ถูกกล่าวถึงว่าเป็นเครื่องมือที่ใช้ดีบักได้ทั้งฮาร์ดแวร์ ซอฟต์แวร์ ไดรเวอร์แบบปลั๊กอิน และแม้แต่เฟิร์มแวร์เอง
  • Jupiter Ace เป็นคอมพิวเตอร์ใช้งานในบ้านของสหราชอาณาจักรในปี 1982 และใช้ Forth เป็นระบบปฏิบัติการ
    • ทั้ง OS และ routine library อยู่ใน ROM ขนาด 8KB
    • มีคำกล่าวอ้างจากปี 1982 ว่า Forth ที่มีมาในตัว “เร็วกว่า” interpreted BASIC ถึง “10 เท่า” และใช้หน่วยความจำน้อยกว่าครึ่ง
  • Canon Cat ในปี 1987 ใช้ Forth เป็นระบบปฏิบัติการ และบรรจุทั้ง OS ชุดโปรแกรมออฟฟิศ และสภาพแวดล้อมการเขียนโปรแกรมไว้ใน ROM ขนาด 256KB
    • เป็นผลิตภัณฑ์ที่ทำให้แนวคิดการออกแบบและอินเทอร์เฟซที่ยึดคีย์บอร์ดเป็นศูนย์กลางของ Jef Raskin กลายเป็นจริงทั้งในฮาร์ดแวร์และซอฟต์แวร์
    • ขั้นตอนการเข้าใช้อินเทอร์เฟซ Forth อาจไม่ได้ดูเหมือนเป็นเส้นทางการใช้งานหลักที่สุด แต่ถ้ารู้วิธีก็ทำได้ด้วยการกดปุ่มเพียงไม่กี่ครั้ง

ซอฟต์แวร์อวกาศและ Forth

  • หนึ่งในการใช้งาน Forth ที่น่าสนใจคือ การสำรวจอวกาศ
    • ยานอวกาศมีต้นทุนสูงและเข้าถึงเพื่อซ่อมแซมได้ยากหรือแทบเป็นไปไม่ได้ จึงทำให้ความน่าเชื่อถือของซอฟต์แวร์มีความสำคัญ
    • รายชื่อโครงการของ NASA ที่ใช้ Forth มีอยู่ยาวมาก แม้ลิงก์ต้นฉบับจะหายไปแล้ว แต่ยังมีสำเนาใน Wayback Machine และ forth.com
  • Space Shuttle Small Payload Accommodations Interface Module (SPAIM) เป็นตัวอย่างของการใช้ Forth
    • ทีมพัฒนาจะเขียน routine ของ Forth บน PC ดาวน์โหลดลงไป แล้วทดสอบแบบอินเทอร์แอ็กทีฟ
    • มีคำกล่าวอ้างว่าระหว่างภารกิจ Shuttle STS-45 ซอฟต์แวร์การบินของ SPAIM ทำงานได้โดยไม่มีปัญหา
    • ระบบ Forth ของ SPAIM รองรับ multitasking โดยแต่ละ task มี stack ของตัวเอง และมี watchdog task คอยเฝ้าดูสถานะของ stack
  • Space Shuttle Robot Arm Simulator เป็นกรณีของอุปกรณ์ซับซ้อนที่โปรแกรมเมอร์เพียงคนเดียวพัฒนาเสร็จภายใน 5 สัปดาห์
    • ต้องรับคำสั่งจาก joystick แบบ 3 แกนเพื่อควบคุมแขนยาว 50 ฟุตที่มี 6 ข้อต่อและ 6 ระบบพิกัด
    • มีการอ้างว่าระบบนี้มี process แยกกัน 14 ตัว
    • มีคำกล่าวอ้างว่าการทดสอบ simulation เข้มข้นมากจนหลังติดตั้งที่หน้างานแล้วไม่ได้เปลี่ยนอัลกอริทึม executive control เลย
  • Shuttle Mission Design and Operations System (SMDOS) เป็นซอฟต์แวร์ควบคุมภาคพื้นของ JPL
    • ระหว่างภารกิจ SIR-B มีการรับมือความขัดข้องของฮาร์ดแวร์หลายอย่างที่หน้างานด้วยการแก้ซอฟต์แวร์
    • เนื่องจากปัญหาเสาอากาศและการเปลี่ยนวงโคจร จึงต้องมีแผนการเก็บข้อมูลแบบใหม่ และ SMDOS ถูกใช้เพื่อแสดงแผนที่เหมาะกับเงื่อนไขใหม่
    • แม้จะสูญเสียข้อมูลไปมาก แต่ก็สามารถกู้คืนข้อมูลได้ 20% ด้วยวิธีหมุน-บันทึก-หมุน-ส่ง
  • Harris RTX2010 เป็นฮาร์ดแวร์ Forth ที่ถูกใช้ในงานอวกาศจำนวนมาก
    • รัน Forth ได้โดยตรง
    • มี hardware stack 2 ชุดที่ลึก 256 word
    • มี clock 8MHz และ latency ต่ำ
    • มีคุณสมบัติ radiation-hardened
  • Rosetta และ Philae ถูกแนะนำว่าเป็นภารกิจแรกที่ส่งยานไปโคจรรอบดาวหางและนำยานลงจอดลงบนพื้นผิวดาวหาง
    • Ion and Electron Sensor ของ Rosetta ใช้ Harris RTX2010
    • ยานลงจอด Philae ใช้ RTX2010 จำนวน 2 ตัวใน CDMS และอีก 2 ตัวสำหรับควบคุม ADS
    • Rosetta เดินทางตั้งแต่ปี 2004 ถึง 2014 ก่อนจะไปพบกับ 67P/Churyumov-Gerasimenko
    • 67P มีความกว้าง 4 กม. และโคจรรอบดวงอาทิตย์ทุก ๆ 6 ปีครึ่ง
  • Philae ประสบกับการกระดอนในแรงโน้มถ่วงต่ำบนพื้นผิวเพราะฉมวกและ thruster สำหรับลงจอดล้มเหลว แต่ก็ยังทนทานพอจะทำภารกิจวิทยาศาสตร์ได้ “80%”
  • ยังมีกรณีแพตช์โค้ดของ magnetometer บน Galileo ในปี 1993 ด้วย
    • magnetometer มี RCA1802, RAM 2KB และ ROM 2KB และเขียนโปรแกรม Forth ผ่านระบบพัฒนาที่ใช้ Apple II
    • มีไบต์หน่วยความจำเสียเกิดขึ้นกลางโค้ดของอุปกรณ์ จึงต้องแพตช์เพื่อไม่ให้ใช้ไบต์นั้น
    • ผู้ถูกอ้างอิงระบุว่าได้เขียนทั้งสภาพแวดล้อมพัฒนา Forth สำหรับอุปกรณ์นั้นและ hardware simulator ขึ้นใหม่ทั้งหมดด้วย Lisp เพื่อสร้างแพตช์ และใช้เวลาน้อยกว่า 3 เดือนแบบพาร์ตไทม์

Forth ใกล้เคียงกับแนวคิดและสายสืบทอดมากกว่าการมี implementation เดียว

  • Forth ใกล้เคียงกับการเป็นแนวคิดที่มี ชุดแนวคิดร่วมและสายสืบทอด มากกว่าจะเป็น implementation ตัวแทนเพียงตัวเดียว
  • เหตุผลหนึ่งที่ทำให้ Forth เรียนรู้ได้ยากคือไม่มี implementation เดียวที่เป็นตัวแทนชื่อ “Forth” แบบผูกขาด
    • Forth ยุคแรกบางตัวมีมาก่อนชื่อ “Forth” เสียอีก
    • มาตรฐานของ Forth สืบต่อมาในเอกสาร ANS Forth โดยมีการกล่าวถึง Forth 2012 Standard และคณะกรรมการ Forth200x
  • Forth หลายตัวมีแนวคิดและ word ร่วมกัน แต่ Forth ที่ออกแบบเฉพาะทางก็มีคำศัพท์เฉพาะของตนเอง
  • Chuck Moore ก่อตั้ง Forth, Inc ในปี 1973 และหลังจากนั้นก็พอร์ต Forth ไปยังหลายระบบ พร้อมทั้งยังสร้างระบบใหม่ ๆ อย่างต่อเนื่อง
  • colorForth เป็นสภาพแวดล้อมยุคหลังของ Chuck Moore
    • สีในซอร์สโค้ดเข้ามาแทนที่เครื่องหมายวรรคตอนบางส่วนของ Forth มาตรฐานเพื่อกำหนดวิธีประมวลผล word
    • มีการกล่าวว่าสีช่วยทำให้ semantics ของ Forth เรียบง่ายขึ้น เพิ่มความเร็วในการ compile และยังช่วยเรื่องสายตาที่ไม่ดีของ Moore ด้วย
    • colorForth มีระบบปฏิบัติการของตัวเองขนาด 63KB รวมอยู่ด้วย
  • Moore มองว่าเมื่อมีการเพิ่มความสามารถเข้ามาเรื่อย ๆ ซอฟต์แวร์ก็จะซับซ้อนขึ้น และสุดท้ายจะกลายเป็นสิ่งที่ไม่มีใครกล้าเปลี่ยนเพราะกลัวผลลัพธ์ที่ไม่ได้ตั้งใจ
    • สิ่งที่จำเป็นตามมุมมองนี้คือโปรแกรมเมอร์ที่ทุ่มอาชีพให้กับแอปพลิเคชันเดียว คอยเขียนมันขึ้นใหม่ซ้ำ ๆ จนสมบูรณ์แบบ

ความเป็นมิตรกับเครื่องจักร, ชิป Forth, GreenArrays

  • Chuck Moore ต่อต้านความซับซ้อนของซอฟต์แวร์มาตั้งแต่ทศวรรษ 1950 และมีการยกคำพูดที่มองว่าระบบปฏิบัติการอย่าง Windows, UNIX, DOS เป็นสิ่งที่เข้าใจไม่ได้หรือไม่จำเป็น
  • ผู้เขียนอธิบายปรัชญาของ Moore ด้วยแนวคิด Mechanical Sympathy
    • คำนี้มาจากคำพูดของนักขับ Formula One อย่าง Jackie Stewart และในบริบทซอฟต์แวร์ถูกใช้ใน Why Mechanical Sympathy? ของ Martin Thompson
    • Forth มักได้รับความนิยมในหมู่ “คนฮาร์ดแวร์” เช่น วิศวกรไฟฟ้าและผู้ออกแบบระบบฝังตัว
  • ดูเหมือนว่าความหลงใหลที่แท้จริงของ Chuck Moore จะอยู่ที่การออกแบบโปรเซสเซอร์
    • Harris RTX2000 และ RTX2010 ถูกแนะนำว่าโดยพื้นฐานแล้วเป็นชิปของ Moore
    • Moore ออกแบบฮาร์ดแวร์มาตั้งแต่ Novix N400 gate array ในปี 1983 และแบบที่ได้รับการปรับปรุงถูกขายให้ Harris จนกลายเป็นชิป RTX
  • Moore ออกแบบโปรเซสเซอร์ด้วย OKAD ซึ่งเป็นซอฟต์แวร์ VLSI ของตัวเองที่เขียนด้วย Forth 500 บรรทัด
    • VLSI Design Tools (OKAD) อธิบายว่ามันให้ทุกอย่างที่จำเป็นต่อการออกแบบชิปด้วย colorForth 500 บรรทัด
    • OKAD เป็นชุดเครื่องมือที่รวมเทคโนโลยีลอจิกเกต, การจัดวางวงจร, simulation การทำงานทางไฟฟ้า, และการ export GDSII
  • Novix NC4000 เป็นเอนจินประมวลผลความเร็วสูงมากที่ออกแบบมาเพื่อรันคำสั่ง Forth ระดับสูงโดยตรง
    • มันได้ประสิทธิภาพจากการตัด assembly language ทั่วไปและ internal microcode ออกไป
    • สถาปัตยกรรม dual stack ลด overhead ของการทำ subroutine ได้อย่างมาก
  • ชิป GreenArrays ถูกแนะนำโดยเน้นจากงานนำเสนอปี 2013 ของ Moore เรื่อง “Programming a 144-computer chip to minimize power”
    • มีคอมพิวเตอร์แบบ asynchronous 144 ตัวอยู่ในชิปเดียว
    • core ที่ว่างงานใช้พลังงาน 100 nW, core ที่ทำงานใช้ 4 mW และรันที่ 666 Mips ก่อนกลับสู่สถานะว่างงาน
    • เมื่อคอมพิวเตอร์ทุกตัวทำงานที่ความเร็วสูงสุด การใช้พลังงานอยู่ที่ 550 mW หรือประมาณ 0.5 W
  • เอกสาร GreenArrays Architecture เน้นคำว่า “NO CLOCKS”
    • มีคำอธิบายว่าการสร้างและกระจาย clock ของคอมพิวเตอร์ทั่วไปใช้พลังงานมากแม้ตอนรอ แต่ไม่ได้ทำงานอะไร
    • GreenArrays ถูกแนะนำว่าไม่ใช่ Multi-Core CPU แต่เป็น Multi-Computer System

ความเรียบง่าย, ประสิทธิภาพ, และอนาคตของการประมวลผลพลังงานต่ำ

  • ผู้เขียนมองว่าทั้งซอฟต์แวร์และฮาร์ดแวร์เดินหน้าต่อไปในทิศทางของการซ้อนทับชั้นความซับซ้อนมากขึ้นเรื่อย ๆ
    • การประมวลผลของดาต้าเซ็นเตอร์ขนาดใหญ่ถูกมองว่าราคาถูกหรือฟรี เพราะมีค่าโฆษณาช่วยจ่ายทางอ้อม
    • สิ่งที่ผู้ใช้จ่ายจริงคือความสนใจและข้อมูลส่วนตัวของตน
  • ผู้เขียนโต้แย้งว่าไม่มีเหตุผลที่จะต้องใช้ซอฟต์แวร์ที่ไร้ประสิทธิภาพและถูกสร้างอย่างหละหลวมมากขึ้นเรื่อย ๆ พร้อมกับความต้องการฮาร์ดแวร์ที่สูงชันขึ้นต่อไป
  • ภาษาแนว Forth อาจมีอนาคตที่แข็งแกร่งในด้านต่อไปนี้
    • คอมพิวเตอร์ขนาดเล็กที่มีอยู่ทุกหนแห่ง
    • พลังงานแสงอาทิตย์
    • VM ที่มีข้อจำกัดอย่างมาก
  • Dennard scaling แทบหยุดลงราวปี 2006
    • ความสัมพันธ์ที่ทรานซิสเตอร์ขนาดเล็กลงทำให้ได้ความเร็วสูงขึ้นและแรงดันต่ำลงไปถึงจุดชะงักที่ราว 4GHz เพราะกระแสรั่วและความร้อน
    • The Free Lunch Is Over ของ Herb Sutter เป็นบทความที่ว่าด้วยการที่แนวทางการเพิ่มประสิทธิภาพ CPU กำลังเปลี่ยนไปสู่ hyper-threading และ multicore
  • Sutter มองว่าต้องออกแบบแอปพลิเคชันใหม่ให้เหมาะกับการทำงานพร้อมกัน หรือไม่ก็เขียนโค้ดที่มีประสิทธิภาพและสิ้นเปลืองน้อยกว่า
    • เขากล่าวว่าการปรับแต่งประสิทธิภาพไม่ได้สำคัญน้อยลง แต่จะยิ่งสำคัญขึ้น
  • ทุกวันนี้เราสามารถซื้อ microcontroller ที่ทรงพลังยิ่งกว่า IBM 704 มากได้ในราคาเพียงไม่กี่เหรียญ และเขียน Forth system ที่ทรงพลังบนมันได้
    • microcontroller สามารถทำงานด้วยแบตเตอรี่ coin cell หรือแผงโซลาร์เซลล์ขนาดเล็ก
    • จากนั้นผู้เขียนกล่าวต่อว่าไม่เคยมีช่วงเวลาใดที่น่าทึ่งสำหรับการประมวลผลขนาดเล็กเท่านี้มาก่อน
  • หากต้องการเข้าใจ Forth ต้องพิจารณาความแตกต่างระหว่าง “simple” และ “easy”
    • Simple Made Easy ของ Rich Hickey ถูกแนะนำว่าเป็นงานบรรยายที่ทำให้สามารถพูดถึงความแตกต่างนี้ได้
    • Forth ไม่ใช่สิ่งที่ง่าย และอาจไม่สนุกเสมอไป แต่เป็นภาษาที่เรียบง่ายอย่างแน่นอน
  • Growing a Language ของ Guy Steele เป็นงานบรรยายที่แสดงให้เห็นว่าภาษาถูกสร้างขึ้นจาก primitive ได้อย่างไร
    • คำกล่าวเกี่ยวกับ Lisp ที่ว่า เมื่อคำใหม่ที่ผู้ใช้กำหนดดูเหมือน primitive และ primitive เองก็ดูเหมือนคำที่ผู้ใช้กำหนด เมื่อนั้นภาษาที่ใหญ่ขึ้นอย่างไร้รอยต่อก็เกิดขึ้น สามารถนำมาใช้กับ Forth ได้เช่นกัน
  • ข้อเชิญชวนสุดท้ายคือให้สร้างภาษาการเขียนโปรแกรมที่สมบูรณ์แบบสำหรับตัวเอง

1 ความคิดเห็น

 
GN⁺ 2023-07-18
ความคิดเห็นจาก Hacker News
  • พอได้รู้จัก Forth ก็รู้สึกทันทีว่าต้องลองสร้างมันขึ้นมาเอง เลยทำ MiniForth ขึ้นมาในเวลาแค่ หนึ่งสัปดาห์ เมื่อ 2 ปีก่อน
    ตั้งใจให้ใช้กับ Blue Pill และ Arduino รุ่นดั้งเดิม แต่พัฒนาเป็นครอสคอมไพเลอร์เพื่อให้ทดสอบบนโฮสต์ได้
    อินมากจนเฝ้ารอเวลาหลังเลิกงานในแต่ละวันเพื่อมานั่งเล่นกับมัน จบงานได้ภายในเย็นวันธรรมดา 5 วันกับสุดสัปดาห์อีก 1 วัน และการสร้าง Forth ก็สนุกมากขนาดนั้น
    ขอแนะนำอย่างยิ่ง และครั้งเดียวที่เคยได้ความรู้สึกแบบตาสว่างคล้ายกันก็คือตอนเจอ Lisp macro ครั้งแรก(https://www.thanassis.space/score4.html#lisp)
    • เห็นด้วยเลย ตอนเรียนวิชาโครงสร้างคอมพิวเตอร์ปี 1 ต้องทำโปรเจกต์ปลายภาคหัวข้ออิสระสำหรับ LC-3 แล้วผมเคยลองเล่น Forth มาบ้างจากม็อด Minecraft ชื่อ RedPower 2 เลยคิดว่าน่าจะสนุกถ้าลอง implement ดู
      มันกินเวลาแทบทั้งหมดของเวลาว่างในเทอมนั้นไปหมด และมีวันหนึ่งที่ผมมองนาฬิกาแล้วเพิ่งรู้ว่าตัวเองอดนอนทั้งคืนตอนฟ้าเริ่มสางแล้ว
      ผมไม่เคยใช้ Forth แบบจริงจังในชีวิตจริง แต่ประสบการณ์การสร้างมันขึ้นมาจากศูนย์นี่ใกล้เคียงกับคำว่า ประสบการณ์ทางศาสนา มากจนแทบไม่มีคำอื่นจะอธิบายได้
      มันเหมือนสิ่งที่ Fred Brooks พูดถึงว่าเป็นแก่นแท้ที่ถูกกลั่นบริสุทธิ์ของการเขียนโปรแกรม: โปรแกรมเมอร์ทำงานอยู่ห่างจากวัตถุดิบของความคิดบริสุทธิ์เพียงนิดเดียว เหมือนกวีสร้างปราสาทกลางอากาศด้วยจินตนาการล้วน ๆ และโปรแกรมคือเวทมนตร์ในโลกจริงที่ทำให้สิ่งซึ่งไม่เคยมีอยู่มาก่อนมีชีวิตขึ้นมาบนหน้าจอ เมื่อใส่คาถาได้ถูกต้อง
    • เห็นด้วยอย่างยิ่ง นานมากแล้วผมเคยสร้างคอมไพเลอร์ Forth ด้วย ZX81 BASIC
      งานที่เคยใช้เวลา 19 วินาทีในการพิมพ์ตัวเลข 1000 ตัวบนหน้าจอ กลายเป็นเสร็จแทบจะทันที
      และยังได้บทเรียนใหญ่ด้วย คือพอดู machine code ที่สร้างออกมาแล้วคิดว่ามันสมบูรณ์แบบจนปรับปรุงไม่ได้แล้ว แต่พอกลับมาวันถัดไปก็ทำให้เร็วขึ้นได้อีกมาก
  • บางคนอาจสงสัยว่า “ที่ว่าเขียนตัวเองได้คือยังไง? ก็แค่เขียนฟังก์ชันได้ไม่ใช่เหรอ?”
    ก็ถูกอยู่ระดับหนึ่ง แต่ Forth ไปไกลกว่านั้นตรงที่สามารถนิยาม word ใหม่ให้กลายเป็นส่วนหนึ่งของตัวภาษาได้เลย
    word เหล่านี้ใช้ได้เหมือนโอเปอเรชันที่มีมาในตัว และถึงขั้นเปลี่ยนวิธีการทำงานของภาษาได้ด้วย
    เพราะมันเป็นภาษาที่ขยายได้ คุณจึงสร้าง word สำหรับนิยามโครงสร้างควบคุมใหม่หรือแม้แต่เปลี่ยนไวยากรณ์ได้ และความยืดหยุ่นแบบนี้ก็หาได้ไม่บ่อยในภาษาอื่น
    ในแง่นี้ Forth จึงมองได้ว่าเป็นภาษาที่ “เขียนตัวเองได้” เพราะมันเปิดให้โปรแกรมเมอร์ปรับแต่งและขยายภาษาได้ในระดับที่ลึกมาก
    มันยังคล้ายกับระบบ macro ของ Lisp ด้วย เพราะเช่นเดียวกับที่ Lisp macro เปิดให้สร้างโครงสร้างไวยากรณ์ใหม่และภาษาจำเพาะโดเมนผ่านการแปลงตอนคอมไพล์ word ของ Forth ก็เปิดให้ขยายทั้งไวยากรณ์และความสามารถของภาษาได้
    • ฟังดูเท่นะ แต่ตลอดเกือบ 40 ปีที่ทำงานเป็นโปรแกรมเมอร์มืออาชีพ ปัญหาที่เจอไม่เคยเป็นเรื่อง syntax เลย แต่เป็นเรื่อง semantics ตลอด
      อาจมีบางกรณีอย่างการคูณเมทริกซ์ที่การเขียน A = B + C * D; ดีกว่าการต้องระบุฟังก์ชันที่จะเรียกทีละตัว แต่ผมไม่เคยเจอปัญหาแบบนั้นจริง ๆ
      เลยสงสัยว่าผมจินตนาการไม่พอเอง หรือว่านี่มีประโยชน์เฉพาะบางโดเมนซึ่งผมไม่เคยอยู่ในโดเมนนั้น หรือว่าไวยากรณ์ของ Forth มันเรียบจนต้องขยายถึงจะใช้งานได้ดี หรือจริง ๆ แล้วคนแค่อยากแต่งภาษาของตัวเองเหมือนแต่งรถ
      ผมไม่ค่อยเข้าใจว่าทำไมคนถึงสนใจเรื่องนี้กันจริงจัง
  • หนึ่งในโปรเจกต์ Forth ที่น่าสนใจที่สุดตอนนี้คือ Dusk OS ซึ่งเป็นระบบปฏิบัติการ 32 บิตที่เขียนด้วย Forth และมี C compiler ของตัวเองรวมอยู่ด้วย อีกทั้งยังมีงานพอร์ตไปแพลตฟอร์มต่าง ๆ อยู่หลายตัว
    https://duskos.org/
    • ตัว DuskOS เองผมไม่ค่อยรู้ แต่ในเชิงประวัติศาสตร์จะบอกว่า Forth เคยเป็น “ระบบปฏิบัติการของตัวเอง” ก็พอได้ เพียงแต่มันค่อนข้างหยาบมากเมื่อเทียบกับสิ่งที่ผู้อ่านยุคใหม่จะนึกถึงเมื่อพูดถึงระบบปฏิบัติการ
      ก็จริงที่คุณจะคาดหวังอะไรได้มากแค่ไหนจากของที่รันบน RAM 8KB แต่ถึงจะมีฟังก์ชันพื้นฐาน มันก็แทบไม่มีทั้งไดรเวอร์และแนวคิดเรื่อง abstraction ส่วนใหญ่ในเชิงประวัติศาสตร์
      โค้ดถูกโหลดจากซอร์สจึงช้า และการลิงก์ก็ใกล้เคียงกับการโหลดบล็อกตามลำดับที่ถูกต้องมากกว่า ส่วนถ้าจะโหลดโปรแกรมใหม่ก็ต้องลบโปรแกรมปัจจุบันทิ้งก่อน
      จะบอกว่ามันดีกว่า CP/M ที่มัก cold start เครื่องตอนโปรแกรมจบการทำงานมากนักก็คงยาก แต่อย่างน้อย CP/M ก็แยก BIOS กับ BDOS ออกจากกัน
    • อันนี้ผมพลาดไปเลย เพิ่งกำลังอ่าน “Beyond the Collapse” อยู่ และรู้สึกว่าด้วยทักษะ Lisp หรือ APL/J และ C ที่มี ก็ยังยากจะเข้าใกล้ ความเรียบง่าย ของ Forth ในระดับระบบปฏิบัติการได้
      ตั้งใจว่าจะต้องไปดูให้ได้ก่อนสุดสัปดาห์หน้า
  • ภาษาโปรแกรมแรกของผมคือ x86 assembly กับ Forth พ่อผมอิน Forth มาก และผมก็เรียนเขียนโปรแกรมจากท่าน
    ตอนเป็นวัยรุ่นผมสร้างระบบ x86 Forth สำหรับ DOS หลายตัว และตัวสุดท้ายก็กลายเป็น implementation ที่ค่อนข้างขัดเกลาและรองรับ ANS ชื่อ “Third”: https://github.com/benhoyt/third
    การที่คุณมีคอมไพเลอร์ Forth แบบ bootstrap ครบชุดพร้อม assembler ได้ด้วยโค้ดแค่ไม่กี่พันบรรทัดนั้นน่าทึ่งมาก
    เมื่อไม่นานมานี้ผมยังถอดบทความเก่าที่เคยเขียนร่วมกันลงในนิตยสาร Forth Dimensions ออกมาใหม่ด้วย
    ไอเดียของ Forth ยังดีอยู่เสมอ แต่ การจัดการสแตก นั้นน่าเบื่อเร็วมาก และยังอ่านยากมากด้วย
    ดูได้จากตัวอย่างโค้ดใน https://benhoyt.com/writings/forth-lookup-tables/ โดยเฉพาะ Search-Table แม้การตั้งชื่อจะยาก แต่ดูเหมือนการไม่ตั้งชื่อจะยากยิ่งกว่า
    • ที่การจัดการสแตกเริ่มน่าเบื่อ อาจเป็นเพราะคุณกับผมไม่ใช่ Chuck Moore ก็ได้
      โค้ดของเขาโดยมากแทบไม่มีการสลับสแตกเลย ตัวอย่าง: http://www.merlintec.com/download/color.html
    • ผมลองดูซอร์สของ Third แวบหนึ่งแล้ว น่าสนใจดี
      ตอน bootstrap เห็นมันเรียก kernel.com เลยสงสัยว่า kernel.com สร้างขึ้นมายังไง
  • ลิงก์บรรยายของ Chuck Moore ที่เกี่ยวข้อง: “Programming a 144 Computer Chip to Minimize Power” (2013)

https://www.youtube.com/watch?v=0PclgBd6_Zs
ว่ากันว่า Forth ขับเคลื่อนคอมพิวเตอร์พลังงานต่ำมากได้แบบนี้: GreenArrays กำลังจัดส่งชิปแบบอะซิงโครนัส 144 คอร์ และใช้พลังงานเพียง 7 pJ/inst
คอร์ที่ว่างอยู่จะไม่ใช้พลังงาน (100 nW) และคอร์ที่ทำงานอยู่จะรันอย่างรวดเร็วที่ 4 mW (666 Mips) ก่อนจะกลับสู่สถานะว่างระหว่างรอการสื่อสาร

  • “ผมเคยคิดว่าขนาดกับความเร็วสำคัญก็แต่สำหรับมือสมัครเล่นเท่านั้น แต่ในบริบทยุคใหม่ พารามิเตอร์ที่สำคัญมีอยู่แค่สามอย่างเท่านั้น: พลังงาน, พลังงาน, พลังงาน
    --Chuck Moore
    https://youtu.be/0PclgBd6_Zs?t=389
  • สงสัยจริง ๆ ว่า โครงสร้างแบบเฟส ลักษณะนี้จะกลับมาอีกครั้งในอีกไม่กี่ปีข้างหน้าหรือเปล่า
  • หนังสือเริ่มต้นที่ยอดเยี่ยมคือ Starting Forth
    มีภาพประกอบที่น่าดึงดูดที่สุดภาพหนึ่งเท่าที่เคยเห็นในตำราเรียน
    [0] https://www.forth.com/starting-forth/
  • เมื่อนานมาแล้วตอนที่ OS/2 ออกมาใหม่ ๆ มีเพื่อนบอกว่า “โปรแกรม OS/2 เขียนด้วยแอสเซมบลีไม่ได้ ต้องเขียนด้วย C”
    ผมเลยทำ Forth/2 ขึ้นมาเพื่อต่อต้านคำพูดนั้น
    มันเป็นคอมไพเลอร์ Forth แบบ native code สำหรับ OS/2 ที่ใช้ direct-threaded ซึ่งเขียนด้วยแอสเซมบลี และ Brian Matthewson ก็ช่วยเขียนคู่มือที่ยอดเยี่ยมให้ จนมีผู้ใช้หลายสิบคน
    [1] https://sourceforge.net/projects/forth2/
  • เป็นคนละเรื่องกันเล็กน้อย แต่จำได้ว่าเคยอ่านต้นแบบของงานนำเสนอดั้งเดิมของบทความนี้
    โดยพื้นฐานแล้วเหมือนกับบทความตอนนี้ แต่มีข้อความน้อยกว่ามากและมีช่องโหว่มากกว่า
    ที่พูดถึงเพราะมันยังแสดงให้เห็นถึงความงามของความมินิมัลในแง่ของ เทคโนโลยีเว็บไซต์ ที่ใช้รองรับด้วย
    [0] http://ratfactor.com/forth/forth_talk_2023.html
    [1] http://ratfactor.com/minslides/
    • มีอะไรบางอย่างเชื่อมโยงกันระหว่างการสร้าง Forth ของตัวเองกับการสร้าง ซอฟต์แวร์พรีเซนเทชัน แบบเรียบง่ายของตัวเองหรือเปล่า? https://www.mankier.com/1/techtalk-pse
  • น่าสนใจที่ Rust ก็มีคอมไพเลอร์ Forth อยู่ด้วย รายละเอียดเกี่ยวข้องอยู่ใน [1]
    วิธีใช้งานยังค่อนข้างไม่ชัดเจน[2] แต่ก่อนหน้านี้ก็เคยถูกพูดถึงที่นี่มาแล้ว[3] และตัว implementation ก็ดูแข็งแรงดี
    มันไม่ใช่ REPL Forth virtual machine แต่ก็เป็น การนำไปใช้เป็น virtual machine ที่น่าประทับใจ
    ถ้า FORTH คือ virtual machine ผมก็คิดมาตลอดว่าเมื่อคุณต้องการระบบเล็ก ๆ ที่มีประสิทธิภาพสำหรับจัดการข้อมูลแบบสตรีมมิง มันอาจเป็นตัวเลือกที่เหมาะที่สุดซึ่งให้ประสิทธิภาพใกล้เคียง bare metal ได้
    และยังไม่ต้องไปปวดหัวกับระบบปฏิบัติการด้วย
    มันเหมือนกับการทำสิ่งที่ FPGA ทำอยู่บน CPU มาตรฐานโดยเนื้อแท้หรือเปล่าก็ไม่แน่ใจ
    แต่ผมกำลังนึกภาพมันเป็นระบบเฉพาะทางที่ไม่จำเป็นต้องเขียนไดรเวอร์ทุกตัวเองเพื่อเชื่อมต่อกับฮาร์ดแวร์ที่ต้องใช้
    [1] https://docs.rs/rust-forth-compiler/latest/src/rust_forth_co...
    [2] https://docs.rs/fortraith/latest/fortraith/
    [3] https://news.ycombinator.com/item?id=23501474
  • ผมก็เคยลงมือทำ Forth ของตัวเองอีกตัวหนึ่งเหมือนกัน
    จุดประสงค์ไม่ใช่เพื่อคัดลอกไอเดียต้นฉบับแบบตรงตัว แต่มันทำงานแตกต่างออกไปเล็กน้อย
    ในบทความบอกว่าสามารถพบ Forth ได้ ก็เลยขอทิ้ง implementation ของผมไว้ด้วย: https://github.com/loscoala/goforth
    ความแตกต่างที่ใหญ่ที่สุดคือ ใน Forth แบบแปรผันตัวนี้ ข้อความซอร์สจะถูกแปลงเป็น ไบต์โค้ด ทั้งหมด และไม่มี runtime ในความหมายแบบ Forth ดั้งเดิม
    เลยแปลงไบต์โค้ดเป็น C ได้ง่าย
    ผมใช้ Forth ตัวนี้สร้างโค้ด C แล้วเอาโค้ดนั้นไปฝังในซอฟต์แวร์อื่นเพื่อใช้งาน
    • วิธีแบบนั้นอาจมีประสิทธิผลและฉลาดมาก แต่ก็ต้องตระหนักไว้เสมอว่า แนวทางหลายภาษา แบบนี้มักกลายเป็นฝันร้ายด้านการบำรุงรักษาในระยะยาว
      มีโปรเจกต์โอเพนซอร์สที่ดีมากตัวหนึ่งซึ่งช่วยฝึกการฟังโน้ตและการอ่านโน้ตฉับพลันได้ เขียนด้วยภาษาที่ผู้เขียนสร้างขึ้นเอง และภาษานั้นคอมไพล์เป็น JavaScript
      ความยุ่งยากในการตั้งค่า toolchain มากเกินไปจนแม้จะรู้ว่ามีบั๊กอยู่หลายจุด ก็ยังไม่กล้าลงมือแก้
      https://sightreading.training/
      https://github.com/leafo/sightreading.training
      โปรเจกต์นี้เขียนด้วยภาษาที่ชื่อว่า ‘Moonscript’: https://github.com/leafo/moonscript
      Moonscript คอมไพล์เป็น Lua และ Lua คอมไพล์เป็น JS
      บ้าคลั่งมาก เป็นความบ้าคลั่งที่เท่มากก็จริง แต่ก็ยังทำให้ผมไม่ได้กลายเป็นผู้มีส่วนร่วมอยู่ดี