- Tcl/Tk เป็นชุดเครื่องมือภายใต้ไลเซนส์ BSD ที่สามารถสร้างทั้ง CLI และ GUI แบบเนทีฟบน Windows, Linux และ macOS ได้ พร้อมรองรับอีเวนต์และ I/O แบบไม่บล็อก รวมถึงเธรดที่แยกจากกัน
- Tcl เป็น ภาษาที่มีคำสั่งเป็นศูนย์กลาง โดยตีความคำแรกเป็นคำสั่ง และจัดการโค้ดกับข้อมูลในรูปแบบสตริง ส่วน Tk ทำ abstraction ให้ UI ของแต่ละระบบปฏิบัติการผ่านวิดเจ็ตและอีเวนต์
- Tcl/Tk 9.0 ที่เปิดตัวเมื่อวันที่ 13 พฤศจิกายน 2025 เพิ่มการรองรับ 64 บิต, Unicode เต็มรูปแบบ, การเข้ารหัสที่เข้มงวด, การแพ็กเกจเป็นไฟล์เดียวด้วย ZipFS, SVG, DPI ความละเอียดสูง และ Dark Mode แต่มีการเปลี่ยนแปลงด้านความเข้ากันได้สำหรับโค้ดเดิมบางส่วน
- ถูกใช้งานระยะยาวใน
git gui, เครื่องมือ FPGA/EDA, Cisco IOS, สภาพแวดล้อมปฏิบัติการของ ESA, การบิลด์และทดสอบ SQLite, แอป Decent Espresso ฯลฯ และมีกรณีที่สคริปต์จากทศวรรษ 1990 ยังรันได้บนเวอร์ชันล่าสุด - เหมาะกับ UI แบบอิงอีเวนต์, งานอัตโนมัติ, I/O, DSL และการประสานงานโปรเซสเนทีฟในฐานะ ภาษาเชื่อมประสาน มากกว่าการคำนวณเชิงตัวเลขขนาดใหญ่ โดยสามารถมอบงานคำนวณให้คอมโพเนนต์ภายนอกอย่าง C, C# หรือ Python ได้
เหตุผลที่เลือก Tcl/Tk
- Tcl/Tk สามารถจัดสภาพแวดล้อมได้ในขนาดประมาณ ไม่เกิน 100MB แม้รวมแพ็กเกจทั่วไป และสร้างแอปไฟล์เดี่ยวขนาดเล็กสำหรับแต่ละแพลตฟอร์มที่รองรับ รวมถึงเว็บแอปได้
- ไลเซนส์ BSD อนุญาตให้แก้ไข แจกจ่ายซ้ำ และขายทั้งหมดหรือบางส่วนได้ โดยชุมชน Tcl ดูแลคอร์และรีลีสต่าง ๆ
- ตัวเลือก GUI อื่น ๆ ที่พิจารณามีข้อจำกัดดังนี้
- AutoHotkey v2 เหมาะกับเครื่องมือ Windows ขนาดเล็ก แต่เป็น Windows เท่านั้น และไม่สามารถรับประกันการเรียกแบบเนทีฟบน Wine ได้
- C# WinForms ผูกกับ Windows API ส่วน MAUI และ Avalonia มี dependency ขนาดใหญ่ และทำให้การพัฒนาขนาดเล็กที่ไม่ใช่องค์กรยุ่งยาก
- เว็บแอปโลคัลแบบ Electron ต้องจัดการการสื่อสารระหว่าง frontend/backend, port conflict และความปลอดภัย อีกทั้งแม้แต่เบราว์เซอร์เปล่า ๆ ก็อาจใช้พื้นที่เกิน 100MB
- หน้าต่างแบบง่ายที่สร้างด้วย Fyne/Gio ของ Go มี dependency ทางอ้อมราว 40,000 รายการ และ static binary ขนาดเกิน 30MB อีกทั้งดูไม่เหมือนแอปเนทีฟ
- Qt มีความซับซ้อนจาก MOC, signal/slot ที่ข้ามขอบเขตเนทีฟ และโครงสร้างไลเซนส์ GPL/LGPL/เชิงพาณิชย์
- เฟรมเวิร์ก GUI สมัยใหม่จำนวนมากวาดลงบนแคนวาสโดยตรงแทนที่จะใช้ UI API ของระบบปฏิบัติการ และมักผูกสภาพแวดล้อมรันไทม์ทั้งชุดตาม OS/CPU ทำให้ได้รูปลักษณ์แบบเนทีฟได้ยาก
Tcl ที่ออกแบบมาเป็นภาษาเชื่อมประสาน
- Tcl ที่ John Ousterhout เปิดตัวในปี 1990 ถูกออกแบบให้เป็น กาวเชิงสถาปัตยกรรม สำหรับเชื่อมโค้ดระดับต่ำประสิทธิภาพสูงกับเลเยอร์ตรรกะที่มนุษย์อ่านได้
- Bridge: เชื่อมโค้ดอย่าง C++ หรือ Rust กับ UI ระดับสูง
- Orchestrate: ควบคุมการไหลของข้อมูลระหว่างโปรแกรมและโมดูล
- Wrap: เปิดเผยงานภายในที่ซับซ้อนให้ใช้งานผ่านคำสั่งสคริปต์แบบง่าย
- Tk เป็นชุดเครื่องมือ GUI ข้ามแพลตฟอร์มที่เสริมการโต้ตอบผ่าน command line ของ Tcl และสามารถโหลดได้ด้วย
package require Tk - คอร์ C ขนาดเล็กของ Tcl รองรับ Windows, Linux, macOS รวมถึง ARM, x86 และ RISC-V
- บน Android สามารถใช้ Termux สำหรับ CLI และ AndroWish สำหรับ GUI ได้
- Ousterhout ได้รับ ACM Software System Award ในปี 1997 จากผลงานการพัฒนาระบบซอฟต์แวร์ที่ส่งอิทธิพลอย่างต่อเนื่อง
กรณีใช้งานในอุตสาหกรรมระยะยาว
- Tcl ถูกใช้งานมาราว 40 ปีในสภาพแวดล้อมที่ความน่าเชื่อถือ ความเข้ากันได้ย้อนหลัง และการพอร์ตมีความสำคัญ
git guiและgitkที่รวมอยู่ใน Git- ภาษาอัตโนมัติของเครื่องมือออกแบบ FPGA/ชิป เช่น Xilinx, Altera, Cadence
- Cisco IOS Embedded Event Manager
- GUI ภายในสำหรับ simulation farm และ hardware tester ของ Intel, NVIDIA, AMD
- Calibre และ Virtuoso ของ Siemens EDA
- สภาพแวดล้อมปฏิบัติการ ESTEC/ESOC ของ ESA
- เครื่องมือ Tcl/Tk ตัวเดียวกันสามารถรันได้ตั้งแต่เทอร์มินัลของโรงไฟฟ้านิวเคลียร์ไปจนถึง Raspberry Pi โดยไม่ต้องคอมไพล์ใหม่
- SQLite เริ่มต้นจากการเป็นส่วนขยายของ Tcl และการทดสอบครึ่งหนึ่งเขียนด้วย Tcl
- Tcl ยังทำหน้าที่เป็น “assembler” ที่ post-process ไฟล์อินพุต C กว่า 125 ไฟล์ เพื่อสร้างซอร์สสุดท้ายของ SQLite มากกว่า 200,000 บรรทัด
องค์ประกอบการติดตั้งและวิธีรัน
- การติดตั้งทั่วไปประกอบด้วยคอมโพเนนต์ต่อไปนี้
tclsh: อินเทอร์พรีเตอร์ CLIwish: เชลล์ GUI ที่รวม Tk และ event loopTcllib·Tklib: ไลบรารี เช่นhttp,csv,json,aes,tooltip,dateentry- แพ็กเกจส่วนขยาย เช่น Thread, TLS, drag and drop
- หากรันโดยไม่มีอาร์กิวเมนต์ จะเปิด REPL ซึ่งสามารถป้อนคำสั่ง วางสคริปต์ และรันไฟล์ผ่าน
sourceได้ - หากส่งไฟล์เข้าไป เช่น
tclsh myscript.tclหรือwish app.tkappจะรันในโหมด batch แบบไม่โต้ตอบ wishบน Windows เป็นแอปพลิเคชัน GUI จึงใช้ Tk Console แทนคอนโซลจริง และหาก UI thread ถูกบล็อก เอาต์พุตก็อาจดูเหมือนหยุดไปด้วย- สำหรับการเรียนรู้ แนะนำให้ใช้
tclshซึ่งให้ standard input/output บนทุกแพลตฟอร์มและยังสามารถโหลด Tk ได้
ไวยากรณ์ของ Tcl ที่มีคำสั่งเป็นศูนย์กลาง
- ซอร์ส Tcl ประกอบด้วยคำที่คั่นด้วยช่องว่าง โดย คำแรกเป็นคำสั่งเสมอ และคำที่เหลือเป็นอาร์กิวเมนต์
- องค์ประกอบไวยากรณ์หลักมีดังนี้
set: ตั้งค่าหรืออ่านค่าตัวแปร$name: แทนที่ด้วยค่าของตัวแปรproc: กำหนด procedure ที่ทำงานเป็นคำสั่งใหม่[...]: รันสคริปต์ภายในและแทนที่ด้วยผลลัพธ์{...}: รวมเป็นอาร์กิวเมนต์เดียวโดยไม่ทำการแทนที่"...": รวมเป็นอาร์กิวเมนต์เดียว แต่ทำการแทนที่$,[],\{*}: ขยาย list เป็นหลายอาร์กิวเมนต์::: ระบุพาธ global/namespace- การขึ้นบรรทัดใหม่และ
;: แยกคำสั่ง
- ใน
string range "Tcl Programming" 0 2นั้นstringเป็น ensemble ที่ dispatch ไปยังคำสั่งย่อยrangeและคืนค่าTcl if,while,returnก็เป็นคำสั่งทั่วไป ไม่ใช่ reserved keywordwhileประเมินสตริงเงื่อนไขและเนื้อหาซ้ำ ๆ- เมื่อใช้
uplevelสามารถสร้าง control statement ที่ผู้ใช้กำหนดเองอย่างrepeat ... until|while ...ได้ returnส่ง completion code ได้แก่TCL_OK,TCL_ERROR,TCL_RETURN,TCL_BREAK,TCL_CONTINUE
Homoiconicity และการแทนที่อย่างปลอดภัย
- ใน Tcl โค้ดและข้อมูลล้วนเป็นสตริงที่ประกอบด้วยคำ จึงสามารถตีความค่าเดียวกันเป็น list, ข้อมูล หรือคำสั่งที่รันได้
- เมื่อขยาย list อย่าง
{*}$userinputองค์ประกอบแรกจะกลายเป็นคำสั่ง และองค์ประกอบที่เหลือเป็นอาร์กิวเมนต์ ดังนั้นหากไม่ครอบอาร์กิวเมนต์ที่มีช่องว่างอย่างถูกต้อง อาจเกิดปัญหาอย่างข้อผิดพลาดชื่อ channel ได้ - Homoiconicity นี้ทำให้การขยาย DSL และ control statement ทำได้ง่าย แต่ก็สร้างภาระด้านความถูกต้องสมบูรณ์และความปลอดภัย เพราะข้อมูลอาจกลายเป็นโค้ดที่ถูกเรียกใช้ได้
- ควรประกอบ callback ด้วย
[list command $arg]เพื่อรักษาขอบเขตของอาร์กิวเมนต์ที่มีช่องว่างและอักขระพิเศษ - expression ของ
exprและifควรครอบด้วย{...}เสมอ เพื่อป้องกันการแทนที่ซ้ำและ command injection รวมถึงให้ได้รับการ optimize เป็น bytecode - Safe Interpreter จะบล็อกการเข้าถึง filesystem, socket และไลบรารีภายนอกโดยค่าเริ่มต้น และเปิดเผยเฉพาะฟังก์ชันที่อนุญาตผ่าน
interp alias
การเปลี่ยนแปลงใน Tcl/Tk 9.0
- Tcl/Tk Core Development Team เปิดตัวเวอร์ชัน 9.0 เมื่อวันที่ 13 พฤศจิกายน 2025 หลังจาก Tcl 8.6 เป็นเวลา 12 ปี
- การเปลี่ยนแปลงหลักมีดังนี้
- ย้ายไปเป็น 64 บิตอย่างสมบูรณ์ และรองรับ Unicode code point ทั้งหมด
- ZipFS สำหรับเมานต์ ZIP เป็นระบบไฟล์เสมือน
- Tk รองรับ SVG, DPI ความละเอียดสูง, การแจ้งเตือนของระบบ และ Dark Mode บน Windows·macOS
- โปรไฟล์เริ่มต้น
strictที่แจ้งข้อผิดพลาดทันทีเมื่อ encoding ไม่ตรงกัน
- มีการเปลี่ยนแปลงด้านความเข้ากันได้ด้วย
- การเปลี่ยนแปลงขนาด pointer อาจทำให้สคริปต์ที่มีโค้ด C ของ
critclหยุดทำงานได้ 010ใน Tcl 8.x คือเลขฐานแปดค่า 8 แต่ใน Tcl 9 คือเลขฐานสิบค่า 10 และเลขฐานแปดใช้ prefix0o- ไม่ลบ UTF-8 BOM
U+FEFFโดยอัตโนมัติ หากจำเป็นต้องตัดออกอย่างชัดเจน
- การเปลี่ยนแปลงขนาด pointer อาจทำให้สคริปต์ที่มีโค้ด C ของ
- Tcl 8.6 ยังใช้พัฒนา CLI·GUI ทั่วไปได้ แต่สำหรับโปรเจกต์ใหม่แนะนำให้ใช้ 9.0 ซึ่งมีความปลอดภัยและการปรับปรุง UI
- อิมพลีเมนเทชันขนาดเล็กมี Jim TCL ขนาดราว 100~200kB และ Picol ที่เป็นโค้ด C น้อยกว่า 1,000 บรรทัด
วิดเจ็ต Tk และรูปลักษณ์สมัยใหม่
- Tk ไม่ได้เปิดเผย Win32, X11, Cocoa โดยตรง แต่ abstract ผ่าน คำสั่งวิดเจ็ต และ event binding
- Tk ยุคแรกทิ้งภาพจำว่าล้าสมัยเพราะวิดเจ็ตคลาสสิกสีเทาและเหลี่ยม แต่
ttkให้วิดเจ็ตที่ใกล้เคียงธีมของระบบปฏิบัติการ- ธีมที่รวมมาโดยพื้นฐานคือ
alt,default,clam,classic - แอปเก่าสามารถแทนที่วิดเจ็ตคลาสสิกด้วย
ttk::treeview,ttk::notebook,ttk::progressbarเป็นต้น
- ธีมที่รวมมาโดยพื้นฐานคือ
- mortgage calculator applet ปี 1996 ยังรันได้บน Tcl 9.0.3 และเวอร์ชันปรับให้ทันสมัยเพิ่ม
grid, การตรวจสอบอินพุต, เงินดาวน์, การรองรับ DPI และ canvas แบบ responsive- ต้นฉบับมี 188 บรรทัดเมื่อไม่รวมคอมเมนต์และบรรทัดว่าง ส่วนเวอร์ชันปรับใหม่มีราว 250 บรรทัดรวมฟีเจอร์ใหม่
- สคริปต์เดียวกันรันได้บน Windows 10, Linux Mint, แท็บเล็ต·โทรศัพท์ Android และ ARM SBC
- Tcl/Tk 9.0 ขยายแทบจะเป็นสัดส่วนที่ 96 DPI·144 DPI บน Windows และควรใช้หน่วยสัมพัทธ์กับ padding มากกว่าพิกเซลคงที่
- แนะนำให้เรียนรู้ลำดับชั้นวิดเจ็ต, path แบบใช้จุด, เลย์เอาต์ และอีเวนต์จาก TkDocs tutorial
Event loop และการเชื่อมโยงแบบหลวม
- event loop ของ Tcl ประมวลผลเมาส์·คีย์บอร์ด, ไฟล์·channel และ callback ตามลำดับคิวในเธรดเดียว และจะเริ่มทำงานเบื้องหลังเมื่อโหลด Tk
- treeview กับ scrollbar เป็นวิดเจ็ต sibling ที่ไม่ได้ครอบกันและกัน และแลกเปลี่ยน command prefix เพื่ออัปเดตตำแหน่งแบบสองทิศทาง
- Tk สามารถส่ง virtual event อย่าง
<<UI:Request:Submit>>พร้อม payload แบบdictไปยังวิดเจ็ตได้ EventManagerที่นำกลับมาใช้ซ้ำได้สามารถจัดการรายชื่อ subscriber ของแต่ละ event ด้วยพจนานุกรม และเรียกevent generateเฉพาะกับวิดเจ็ตที่มีอยู่- มีบทบาทคล้าย C# Events/Delegates, JavaScript
CustomEvent, Python PyPubSub·blinker - สามารถส่งผลการตรวจสอบไปยัง subscriber หลายตัว เช่น popup, inspector, ปุ่ม
Sendโดยไม่ต้องอ้างอิงกันโดยตรง
- มีบทบาทคล้าย C# Events/Delegates, JavaScript
- แม้ใน Tcl ล้วนก็สร้าง event manager ที่เรียก callback ของ subscriber ได้ และนำไปใช้กับแอนิเมชันคอนโซลแบบอิง
tickทุก 50ms หรือการเลื่อนหลาย canvas ให้ซิงก์กันได้ - การออกแบบ event ที่ยึดข้อมูลเป็นศูนย์กลางเหมาะกับระบบแบบ MVC ที่แยก UI กับตรรกะ และสอดคล้องกับขั้นตอนเลือกเหตุการณ์·รวบรวมข้อมูล·ตัดสินกลยุทธ์·ดำเนินการ·ประเมินผลของ PIOSEE
การเชื่อมต่อกับ Python และโปรเซสภายนอก
tkinterของ Python เป็น wrapper ของ Tk แต่ตัวอย่างเก่าและธีมเริ่มต้นอาจทำให้เกิดภาพจำว่า Tk เองล้าสมัย- หากต้องการรูปลักษณ์สมัยใหม่ ต้องใช้
from tkinter import ttkและttk.Label,ttk.Buttonเป็นต้นอย่างชัดเจน
- หากต้องการรูปลักษณ์สมัยใหม่ ต้องใช้
- แนะนำให้ใช้ Tk ผ่าน Tcl ซึ่งถูกออกแบบมาคู่กันตั้งแต่แรก และแยก Python เป็นชั้นประมวลผลข้อมูล
- งาน Python แบบครั้งเดียวเชื่อมด้วย
execส่วนงาน asynchronous ต่อเนื่องเชื่อมผ่าน pipe ด้วยopen "|python3 -u script.py" r+- เมื่อใช้ non-blocking·line buffering และ
fileeventGUI จะยังตอบสนองได้ขณะทำงาน NumPy·Pandas
- เมื่อใช้ non-blocking·line buffering และ
- หากเชื่อมต่อโปรเซสลูกแบบ native เช่น C# ด้วยวิธีเดียวกัน แม้โปรเซสคำนวณจะ crash หรือใช้ CPU ทั้งหมด โปรเซส UI ก็ยังถูกแยกออกจากกัน
- EOF ของ pipe ก็เป็น readable event เช่นกัน ดังนั้นในฟังก์ชันจัดการต้องตรวจ
[eof $pipe]เพื่อป้องกัน callback วนไม่รู้จบ
การแทนค่า โครงสร้างข้อมูล และประสิทธิภาพ
- “Everything is a String” หมายความว่าค่าทุกค่ามี การแทนมาตรฐาน เป็นสตริง ไม่ได้หมายความว่าถูกเก็บเป็นสตริงเสมอไป
Tcl_Objเป็นอ็อบเจกต์แบบ dual-ported ที่จัดการทั้งการแทนแบบสตริง UTF-8 และการแทนภายใน เช่น integer, list, dict, byte array- การสร้างการแทนภายในใหม่เมื่อชนิดที่ต้องการเปลี่ยนไปเรียกว่า shimmering
- สำหรับ list ควรใช้คำสั่ง
lappend·lindexต่อเนื่อง, สำหรับ dict ใช้dict, สำหรับไบนารีใช้binaryเพื่อลดต้นทุนการแปลงและความเสียหายของข้อมูล - สามารถวินิจฉัย object pointer และการแทนภายในด้วย
tcl::unsupported::representation
- สำหรับ list ควรใช้คำสั่ง
- Tcl ใช้ Copy-on-Write จึงไม่คัดลอกทันทีเมื่อกำหนดค่า แต่จะโคลนเมื่อมีการแก้ไขอ็อบเจกต์ที่แชร์อยู่จริง
- ไบนารีอย่าง PNG ต้องตั้งค่า channel เป็น
-translation binaryและใช้binary encode/decodeเพื่อหลีกเลี่ยงการแปลง CR/LF และ UTF-8 dict setสร้างเส้นทางกลางให้อัตโนมัติ และสามารถแก้ไขค่าที่ซ้อนกันเหมือนตัวแปรท้องถิ่นด้วยdict with,dict update- คีย์ซ้ำจะถูกจัดการแบบ Last Writer Wins โดยเหลือค่าล่าสุดไว้
- list เหมาะกับข้อมูลที่มีลำดับและโครงสร้างแบบเมทริกซ์ ส่วน dict เหมาะกับข้อมูล key-value ซ้อนทั่วไป
Array, namespace และ TclOO
- namespace เป็นคอนเทนเนอร์แบบไดนามิกที่เก็บตัวแปรและคำสั่ง และสามารถสร้าง dispatcher อย่าง
Logger logได้ด้วยnamespace ensemble - ตัวแปรและคำสั่งใช้ hash table แยกกัน จึงมีชื่อเดียวกันพร้อมกันได้ และตรวจสอบโครงสร้าง runtime ได้ด้วย
info vars,info commands,info procs - Tcl Array คือ hash table แบบแบนที่ชี้ไปยังตัวแปรแต่ละตัว
- เหมาะกับคอลเลกชันที่มีคีย์ไดนามิก เช่น สถานะ UI และสามารถ bind หรือ trace องค์ประกอบแต่ละตัวกับวิดเจ็ตได้
- สำหรับ procedure ต้องส่งชื่อ array แล้วใช้
upvarเพื่อเชื่อม alias ไปยังต้นฉบับ
- แนะนำให้ใช้ namespace สำหรับสถานะ global·singleton ที่มีคีย์คงที่ และใช้ array สำหรับคอลเลกชันคีย์ไดนามิก
- TclOO ซึ่งรวมอยู่ใน core ตั้งแต่ Tcl 8.6 ให้ class, object, inheritance, constructor·destructor โดยอิง namespace และ command dispatch
- object เป็นคำสั่งจริงอย่าง
::oo::Obj42และเก็บสถานะไว้ใน namespace เฉพาะ - สามารถเปลี่ยน class ด้วย
oo::defineและเปลี่ยน object เฉพาะตัวขณะ runtime ด้วยoo::objdefine mymethodสร้าง callback เมธอดของ object แบบครบถ้วนสำหรับส่งให้afterเป็นต้น
- object เป็นคำสั่งจริงอย่าง
- TclOO ไม่มี garbage collection จึงต้องลบ object อย่างชัดเจนด้วย
$obj destroy- สามารถจัดการอายุการใช้งานด้วย
try/finallyหรือmanaged_createแบบอิง variable trace - channel ก็ต้อง
closeและสามารถใช้managed_channelเพื่อ cleanup อัตโนมัติเมื่อออกจาก scope
- สามารถจัดการอายุการใช้งานด้วย
- วิดเจ็ต Tk ก็ยังคงอยู่ในรูปคำสั่งเช่นกัน แต่เมื่อ
destroyวิดเจ็ตแม่ วิดเจ็กลูกทั้งหมดจะถูกลบไปด้วย
โครูทีนและเธรด
- โครูทีนของ Tcl เป็น stackful coroutine ที่รักษาสแตกการเรียกทั้งหมดไว้ และหลังจาก
yieldจะกลับมาทำงานต่อโดยคงตัวแปรภายในและตำแหน่งการทำงานเดิมไว้ - เมื่อนำ
afterมารวมกับโครูทีน จะสามารถจัดการดาวน์โหลด, state machine, แอนิเมชัน และงานเครือข่ายภายใน event loop ได้แบบไม่บล็อก- CLI ล้วนต้องใช้
vwaitเพื่อคงโปรเซสไว้ แต่แอป Tk มี window manager คอยรักษา event loop ให้ coroutine::utilของtcllibมี wrapper ที่รับรู้โครูทีนสำหรับsocket,gets,read
- CLI ล้วนต้องใช้
- โครูทีนใช้เธรด CPU เดียวร่วมกัน ดังนั้นหากมีการคำนวณยาว ๆ ทำงานอยู่ UI ทั้งหมดจะค้าง และควรแยกงานเหล่านี้ออกด้วยแพ็กเกจ Thread
- Tcl Thread เป็นโมเดล shared-nothing ที่แต่ละเธรดมีอินเทอร์พรีเตอร์แยกจากกัน
- ส่งข้อความด้วย
thread::sendและ TSV ให้ค่าที่แชร์ร่วมกันซึ่งป้องกันด้วย mutex - ช่องทาง (channel) โอนความเป็นเจ้าของได้ด้วย
thread::transfer,detach,attach
- ส่งข้อความด้วย
- เธรดที่ติดอยู่ในลูปไม่สิ้นสุดจะไม่กลับเข้าสู่ event queue จึงไม่สามารถบังคับปิดได้อย่างปลอดภัย
- เมื่อสร้างเธรดย่อย 32 เธรดบน AMD 5950X หน่วยความจำเพิ่มจาก 24MB เป็น 44MB หรือใช้ราว 0.6MB ต่ออินเทอร์พรีเตอร์
- การทำเธรดของ Tcl เป็นฟีเจอร์เพื่อการตอบสนองของ UI และการประสานงาน I/O มากกว่าการแข่งขันด้านประสิทธิภาพการคำนวณ
- ในการทดสอบหารากที่สอง 100 ล้านครั้ง AoT C# ใช้ 0.24 วินาที ส่วน Tcl ใช้ 16.8 วินาที ต่างกันประมาณ 70 เท่า
แยกการคำนวณด้วย C·C#
critclจะคอมไพล์โค้ด C·C++ ที่อยู่ในสคริปต์ Tcl เมื่อรันครั้งแรก แล้วเรียกใช้เป็นคำสั่งเนทีฟ- ระหว่างพัฒนาต้องมี
gccหรือclangและหลังทำเสร็จสามารถพรีบิลด์เป็นแพ็กเกจ.dll·.soเพื่อแจกจ่ายได้
- ระหว่างพัฒนาต้องมี
- ส่วนที่เป็นคอขวดด้านประสิทธิภาพอย่าง Mandelbrot หรือ Fibonacci สามารถย้ายไปเขียนด้วย C ได้ แต่งานที่ต้องจัดการโครงสร้างหน่วยความจำ Tcl/C โดยตรงนั้นยุ่งยาก
- อีกทางเลือกคือใช้ Tcl/Tk เป็น UI บาง ๆ แล้วมอบการคำนวณให้โปรเซสแยกต่างหาก ซึ่งเป็น Sidecar Pattern
- BFlat คอมไพล์ C# เป็นไบนารีเนทีฟแบบ self-contained และรองรับ Windows·Linux·Android
- CLI คำนวณตัวเลขพื้นฐานบน Windows อาจมีขนาดราว 900KB และหลังบีบอัดด้วย UPX อาจต่ำกว่า 500KB
- เมื่อรวมกับอินเทอร์พรีเตอร์ Tcl ขนาดราว 3MB จะสามารถจัดแอปตามแพลตฟอร์มให้มีขนาดประมาณ 3~4MB ได้
ZipFS และการแจกจ่ายไฟล์เดียว
- ก่อน Tcl 9 มีการใช้ Starpack ซึ่งนำ Starkit ไปแนบกับ Tclkit แต่ต้องพึ่งเครื่องมือแยกอย่าง Metakit และ SDX
- ZipFS ของ Tcl 9 เมานต์ ZIP เป็นระบบไฟล์เสมือนแบบอ่านอย่างเดียวที่
//zipfs:/ - Zipkit รวม
tclsh·wishที่ลิงก์แบบ static กับ ZIP ของแอป แล้วรันmain.tclตอนเริ่มต้น- มีเป้าหมายสำหรับ Windows x86/x86_64, macOS Intel·Apple Silicon, Linux x86_64/arm64/RISC-V 64 บิต และตระกูล Solaris
- เพียงเปลี่ยนเทมเพลต Zipkit ก็สามารถทำ cross-packaging ไบนารีสำหรับ OS อื่นได้
- ZipFS เริ่มจากการใช้งาน VFS ของ AndroWish ซึ่งต้องอ่านไฟล์ภายใน APK โดยตรง ก่อนถูกรวมเข้า Tcl core
- หากรวม
.dll·.soเฉพาะแพลตฟอร์มไว้ด้วย ต้องตรวจจับแพลตฟอร์มที่รันและเลือกส่วนขยายที่ถูกต้อง
AndroWish และ Decent Espresso
- แอป DE1 ของ Decent Espresso ยังคงเป็นแอป Tcl/Tk ที่รันบน AndroWish ณ เดือนเมษายน 2026
- แท็บเล็ตไม่ได้เป็นไคลเอนต์ของเซิร์ฟเวอร์ระยะไกล แต่ใช้ สถาปัตยกรรม local-first ที่ทำงานเป็น peer ของเครื่องชงกาแฟ
- AndroWish แมปคำสั่งวาดของ Tk เป็น texture ของ SDL2 จึงจัดการการแสดงผลความถี่สูงได้แม้บนแท็บเล็ต Android สเปกต่ำ
- ส่วนขยาย
borgให้ Bluetooth, การแจ้งเตือน, การสั่น, เสียง, ตำแหน่ง และอีเวนต์สถานะของ Android - ณ เดือนพฤษภาคม 2026 รองรับเฉพาะ Tcl/Tk 8.6 จึงใช้คำสั่งเฉพาะ Tcl 9 ไม่ได้
- ส่วนขยาย
- AndroWish SDK สร้าง APK ที่รวมสคริปต์ไว้ และหากลบส่วนขยายที่ไม่จำเป็นออก ขนาดประมาณ 30MB จะลดเหลือ 4~10MB ได้
undrowishเป็นอินเทอร์พรีเตอร์ไฟล์เดียวสำหรับทดสอบสภาพแวดล้อม SDL เดียวกันบน Windows·Linux แต่ไม่รวม Androidborg- สามารถใช้
tkconclientเชื่อมต่อระยะไกลจาก PC ไปยังอินเทอร์พรีเตอร์ Android ได้ แต่เพราะไม่มีรหัสผ่านจึงควรใช้เฉพาะระหว่างพัฒนา - Tk มีข้อจำกัดด้านการปรับภาพ raster อัตโนมัติตามความละเอียด Android และ UI เต็มจอแบบสัมผัส ทำให้ Decent Espresso ต้องสร้าง UI แบบสกินเอง
Wapp, DSL และ sandbox
- Wapp เป็นเว็บเฟรมเวิร์ก Tcl แบบเน้นไฟล์เดียวที่สร้างโดย D. Richard Hipp
- รองรับเซิร์ฟเวอร์ซ็อกเก็ตในตัว, CGI·SCGI และจัดการ URI decoding กับการทำความสะอาดพารามิเตอร์โดยพื้นฐาน
- ใช้ในแอป checklist ที่จัดการขั้นตอนการปล่อย SQLite และเว็บ UI ของ Fossil
- หากรวม htmx กับ CSS ปริมาณเล็กน้อย จะสร้างเว็บแอปที่เน้นโปรซีเยอร์ Tcl ได้โดยไม่ต้องใช้ JavaScript
- หากการเข้าถึงจากระยะไกล·มือถือเป็นสิ่งจำเป็น แนะนำ Wapp ส่วนเครื่องมือท้องถิ่นแนะนำ Tk ที่ผสานกับระบบปฏิบัติการโดยตรง
- Tcl เหมาะกับการสร้าง DSL เพราะแม้แต่ลูปและเงื่อนไขก็เป็นคำสั่ง
- ใช้
unknown,uplevel,upvarเพื่อสร้างคำสั่งทางธุรกิจอย่างcheckout 1000 USDได้ - สามารถสร้างสภาพแวดล้อมสคริปต์แบบจำกัดสำหรับธนาคาร·EDA โดยเปิดเผยเฉพาะคำสั่งที่อนุญาตใน Safe Interpreter
- ใช้
- ยังสามารถสร้างคำสั่งแบบมาโครเพื่อสร้างขั้นตอน post-processing ของสตริงหรือ flow การทำงานเฉพาะแอปพลิเคชันได้
ฟังก์ชันระบบปฏิบัติการแบบเนทีฟ
- Tcl/Tk เรียกใช้ได้ทั้งคำสั่งร่วมและ API เฉพาะแพลตฟอร์มผ่านส่วนขยาย
- TWAPI บน Windows ให้ API ระดับต่ำที่ใกล้เคียง Windows SDK และอินเทอร์เฟซอำนวยความสะดวก
- ใช้
twapi::shell_execute -verb runasเพื่อขอ elevation สิทธิ์ UAC ได้ - เข้าถึงเวลา creation·modification ของไฟล์, global hotkey, service และฟังก์ชันของ Windows ได้
- ใช้
- ในกรณีเครื่องมือช่วย Adobe DNG Converter หลังแปลง RAW รุ่นใหม่เป็น DNG ที่เข้ากันได้กับ CS6 แล้ว จะใช้ TWAPI กู้คืนเวลา creation·modification ของไฟล์ต้นฉบับ
- Tcl ล้วนจัดการได้เฉพาะเวลา modification·access จึงต้องใช้ TWAPI เพื่อกู้คืนเวลา creation ของ Windows
ข้อจำกัดและวินัยในการพัฒนา
- Tcl วางภาระด้านความถูกต้องไว้ที่วินัยของนักพัฒนามากกว่าคอมไพเลอร์
- หากเข้าใจความต่างของการแทนที่ระหว่าง
{}กับ""ผิด อาจเกิดการแทนที่ซ้ำและช่องโหว่ความปลอดภัย dict get,expr,formatที่ซ้อนกันควรแยกเป็นตัวแปรทีละขั้นเพื่อให้อ่านง่าย- หากนิยามภาษาใหม่มากเกินไป อาจกลายเป็นระบบคำสั่งกำหนดเองที่ดูแลรักษายาก
- หากเข้าใจความต่างของการแทนที่ระหว่าง
- Tcl แยกความต่างระหว่างการมีอยู่ของตัวแปรกับสตริงว่างแทน
nullและตรวจสอบด้วยinfo exists- หากใส่สตริงว่างในนิพจน์คณิตศาสตร์ จะไม่แปลงเป็น 0 หรือ NaN อัตโนมัติ แต่จะเกิดข้อผิดพลาด
- ไม่เหมาะกับ 3D·เสียงแบบเรียลไทม์และการคำนวณเมทริกซ์ขนาดใหญ่
- Tcl3D·Canvas3d และคำสั่งเสียงภายนอกใช้ได้ แต่ไม่ใช่กรณีใช้งานหลัก
- หากประมวลผลเมทริกซ์ 1GB เป็นสตริง·ลิสต์ ค่าใช้จ่ายในการจัดการอ็อบเจ็กต์จะสูง จึงเหมาะกับไลบรารี C หรือโปรเซสคำนวณแยกมากกว่า
- จุดแข็งของ Tcl คือการประสานงานด้วยโครูทีน·เธรด, I/O และอีเวนต์, ชั้นการแสดงผล Tk·CLI, การทดสอบและอัตโนมัติ
แพ็กเกจและสภาพแวดล้อมการพัฒนา
- Tcl ไม่มีตัวจัดการแพ็กเกจกลางแบบสากลที่เทียบได้กับ
npmหรือpipและteacup/teapotของ ActiveTcl ส่วนใหญ่กลายเป็นของเก่าไปแล้ว - ดิสทริบิวชันแบบ Batteries Included มาพร้อมแพ็กเกจที่ผ่านการตรวจสอบแล้ว
- Magicsplat ให้บริการแพ็กเกจ Tcl/Tk 9 ที่คัดสรรมา โดยเน้น Windows เป็นหลัก
- BAWT เป็นเฟรมเวิร์กบิลด์แนว maximalist สำหรับสร้างดิสทริบิวชันที่รวมส่วนขยายสำหรับหลายแพลตฟอร์มและหลาย CPU
- ขึ้นอยู่กับการตั้งค่า สามารถรวมแพ็กเกจหลักของอีโคซิสเต็มไว้ได้ในขนาดประมาณ 35MB
- การไม่มีตัวจัดการกลางไม่ได้ทำให้ปลอดภัยขึ้นโดยอัตโนมัติ แต่มีข้อดีคือสามารถล็อก dependency ทั้งหมดแล้ววิเคราะห์เพียงครั้งเดียวได้
- Tcl สร้างคำสั่งแบบไดนามิก จึงทำให้การวิเคราะห์แบบสแตติกและ autocomplete ทำได้ยาก และ Nagelfar ก็ไม่สามารถตรวจสอบคำสั่งที่ไม่รู้จักหรือการนิยามใหม่ตอนรันไทม์ได้อย่างสมบูรณ์
- ใน VSCode/VSCodium สามารถใช้ Tcl by bitwisecook, Tcl Navigation and Tools, Code Runner ได้
การติดตั้งตามแพลตฟอร์ม
- บน Windows หากติดตั้ง Magicsplat Tcl/Tk แบบทั่วทั้งระบบ จะสามารถตั้งค่า PATH และการเชื่อมโยงไฟล์
.tclapp/.tkappได้ - บนตระกูล Debian/Ubuntu สามารถติดตั้ง Tcl, Tk, SQLite, TLS, image และ Thread ได้ด้วยแพ็กเกจต่อไปนี้
sudo apt-get install tcl tk libsqlite3-tcl sqlite-tcl tcltls tcllib libtk-img tcl-thread
- repository ของ Linux LTS หลายรายการมี Tcl 8.6 ให้ใช้งาน และบิลด์ที่รวมส่วนขยาย Tcl 9 มีให้ที่ tcl-builds-with-libxft
- มีกรณีที่ Tk ทำงานได้ไม่เฉพาะบน X11 เท่านั้น แต่ยังรวมถึงสภาพแวดล้อม Wayland อย่าง Zorin OS 18 ด้วย
- Tcl 8.5 ที่มากับ macOS โดยพื้นฐานมีไว้เพื่อความเข้ากันได้กับ legacy จึงแนะนำให้หลีกเลี่ยงสำหรับการพัฒนา Tcl/Tk สมัยใหม่
- สามารถติดตั้ง Tcl/Tk 9 ผ่าน Homebrew, MacPorts หรือบิลด์ BAWT แบบทดลองได้
- บน Apple Silicon ควรวาง
/opt/homebrew/opt/tcl-tk/binไว้ด้านหน้าของ PATH เพื่อให้มีลำดับความสำคัญเหนือ Tcl ของระบบ
แหล่งเรียนรู้และการประเมินโดยสรุป
- The Tcl 9 Programming Language เป็นแหล่งข้อมูลขั้นสูงที่ลงลึก Tcl 9 ล้วน ๆ และเพื่อให้เข้าใจฟีเจอร์ทั้งหมด แนะนำให้อ่านซ้ำและไล่ตามตัวอย่างด้วยตนเอง
- TkDocs ครอบคลุม Tk สมัยใหม่,
grid, event loop และเทคนิคเก่า ๆ ที่ควรหลีกเลี่ยง - ไม่แนะนำเอกสารของ Tutorialspoint เพราะมีวิธีติดตั้งที่ล้าสมัยและแนวปฏิบัติอย่าง
exprที่ไม่ใส่วงเล็บปีกกา - REPL ของ
tclshและwishจะแสดงวิธีใช้งานเมื่อป้อนอาร์กิวเมนต์ผิด จึงใช้เป็นเครื่องมือเรียนรู้สำหรับทดลองควบคู่กับเอกสารได้ - Tcl/Tk ไม่ใช่อีโคซิสเต็มที่กำลังเป็นกระแสหรือมีชุมชนขนาดใหญ่ แต่ยังคงเป็นชุดเครื่องมืออเนกประสงค์ที่ให้ความสำคัญกับ ความเข้ากันได้ระยะยาวและความสม่ำเสมอ ในทีมขนาดเล็กและอุตสาหกรรมที่เป็น mission-critical
- เหมาะเมื่อคุณต้องการ ‘boring technology’ ที่ทำงานได้ยาวนานหลายสิบปีมากกว่าสแต็กที่เปลี่ยนเร็ว และต้องการเลเยอร์ CLI/GUI/automation/orchestration มากกว่าเครื่องมือคำนวณ
ยังไม่มีความคิดเห็น