Lua เป็นภาษาที่ถูกประเมินค่าต่ำเกินไป
(nflatrea.bearblog.dev)- ยิ่งได้เรียนรู้การออกแบบและการอิมพลีเมนต์ของ Lua มากเท่าไร ก็ยิ่งประทับใจมากขึ้นเท่านั้น ซอฟต์แวร์ที่ทำอะไรได้มากด้วยโค้ดเพียงเล็กน้อยนั้นหาได้ยาก
- อย่างไรก็ตาม Lua ไม่ได้รับการทำการตลาดและความสนใจมากเท่าภาษาอื่น ๆ ทำให้นักพัฒนาที่รู้จักความสามารถและข้อดีของ Lua มีไม่มาก
- มักถูกมองว่าเป็นภาษากลุ่มเฉพาะที่ใช้หลัก ๆ ในเกมและระบบฝังตัว
[คุณสมบัติและข้อดีของ Lua]
ภาษาที่เข้าใจได้ง่าย
- Lua เป็นภาษาสคริปต์แบบฟรี, reflective และ imperative ถูกสร้างขึ้นในปี 1993 และออกแบบมาให้ฝังเข้าไปในแอปพลิเคชันอื่นเพื่อขยายความสามารถได้
- การออกแบบสะอาดตาและโค้ดทำงานได้รวดเร็ว C API ใช้งานง่ายและมีประสิทธิภาพดี
- ไวยากรณ์กระชับและมินิมัล ทำให้ผู้เริ่มต้นเข้าถึงได้ง่าย
ความสามารถในการฝังตัวที่ยอดเยี่ยม
- Lua ถูกออกแบบมาให้ฝังเข้าไปในแอปพลิเคชันที่เขียนด้วยภาษาอื่นได้ง่าย โดยเฉพาะ C และ C++
- เป็นตัวเลือกที่ยอดเยี่ยมสำหรับการเขียนสคริปต์และการขยายความสามารถของเกมและแอปพลิเคชันแบบฝังตัว
- ตัวอย่าง: ฝัง Lua ลงในโปรแกรม C
#include <lua.h> #include <lauxlib.h> #include <lualib.h> int main() { lua_State *L = luaL_newstate(); luaL_openlibs(L); luaL_dofile(L, "./myscript.lua"); lua_close(L); return 0; }
รองรับหลายกระบวนทัศน์การเขียนโปรแกรม
- Lua รองรับการเขียนโปรแกรมแบบ imperative, functional และ object-oriented ทั้งแบบเดี่ยว ๆ หรือใช้งานร่วมกับไลบรารีที่เหมาะสม
- มอบความยืดหยุ่นในการเลือกสไตล์การเขียนโปรแกรมให้เหมาะกับความต้องการของผู้ใช้
[ข้อเสียที่อาจมีของ Lua]
ธรรมเนียมการทำดัชนี
- ใน Lua การทำดัชนีโดยทั่วไปเริ่มจาก 1 แต่สิ่งนี้เป็นเพียงธรรมเนียมเท่านั้น อาร์เรย์สามารถทำดัชนีด้วย 0, ค่าติดลบ หรือค่าอื่น ๆ ได้
- ใน Lua ไม่มีอาร์เรย์จริง ๆ มีเพียงตารางที่เป็นแฮชแบบคีย์-ค่าเสมอ จึงทำดัชนีด้วยค่าได้หลากหลาย เช่น 0 หรือค่าติดลบ
- ไลบรารีมาตรฐานและฟังก์ชันในตัวจะสมมติว่าตารางที่มีลักษณะคล้ายอาร์เรย์นั้นมีดัชนีเริ่มต้นที่ 1
การจัดการข้อผิดพลาด
- การจัดการข้อผิดพลาดของ Lua อาจไม่ค่อยเป็นธรรมชาติสำหรับนักพัฒนาที่มาจากภาษาอื่น
- ใน Lua สามารถจัดการข้อผิดพลาดเป็นค่าได้ และสามารถใช้
pcallเพื่อดักจับข้อผิดพลาดfunction risky_function() error("Something went wrong!") end local status, err = pcall(risky_function) if not status then print("Error: " .. err) end
อาร์เรย์ที่สิ้นสุดด้วย Nil
- อาร์เรย์ของ Lua (ตารางที่ใช้เสมือนอาร์เรย์) จะสิ้นสุดเมื่อเจอค่า nil ซึ่งอาจทำให้เกิดพฤติกรรมที่ไม่คาดคิด
local arr = {10, 20, 30, nil, 50} for i, v in ipairs(arr) do print(v) -- 출력: 10, 20, 30 (nil에서 중단) end - ฟังก์ชัน
ipairsจะหยุดการวนซ้ำเมื่อเจอค่า nil - หากอาร์เรย์มีช่องว่าง ควรใช้
pairsแทนipairsเพื่อให้สำรวจได้ทุกสมาชิก รวมถึงตำแหน่งที่มีค่า nil
[สรุป]
- Lua เป็นภาษาโปรแกรมที่ทรงพลัง มีประสิทธิภาพ และใช้งานได้หลากหลาย ซึ่งสมควรได้รับการยอมรับมากกว่านี้
- ด้วยความเรียบง่าย ความสามารถในการฝังตัว และประสิทธิภาพ จึงเหมาะกับแอปพลิเคชันหลากหลายประเภท เช่น เกมและระบบฝังตัว
- แม้จะถูกมองข้าม แต่ด้วยความเรียบง่ายและประสิทธิภาพ ก็ยังเป็นภาษาที่คุ้มค่าจะลองใช้
- ถูกใช้ในระบบปลั๊กอินของ nvim และมีประสิทธิภาพ
7 ความคิดเห็น
> จริง ๆ แล้ว Lua ไม่มีอาร์เรย์ มีเพียงตารางที่เป็นแฮชแบบคีย์-ค่าเสมอ จึงสามารถใช้ค่าอย่าง 0 หรือค่าติดลบเป็นดัชนีได้
ผมเคยลองใช้ Lua อยู่พักหนึ่งเพราะ WoW addon และจำได้ว่าส่วนนี้นี่แหละที่น่าประทับใจที่สุด ดูเหมือนว่าแทบทุกโครงสร้างข้อมูลจะใช้ตารางกันตลอดเลยครับ
ก่อนหน้านี้รู้จักแค่ชื่อของ lua แต่พออ่านบทความนี้แล้วกลับรู้สึกว่ามันไม่ค่อยดีเท่าไหร่เลย 555..
ผมก็ไม่ค่อยรู้เหมือนกัน แต่ได้ยินมาว่าความเข้ากันได้ย้อนหลังระหว่างเวอร์ชันนั้นแย่มาก..
โดยส่วนตัวแล้ว เมื่อเทียบกับ Ruby.. ในแง่คำถามว่า 'อย่างแรกเลย โค้ดเก่ายังรันขึ้นไหม??' มันก็ถือว่าดีกว่าอยู่บ้าง แต่โดยเฉพาะใน 5.3 วิธีจัดการกับ
numberเปลี่ยนไปจากเวอร์ชันก่อนหน้า พออัปเกรดจาก 5.1 ไป 5.3 ก็จะมีบั๊กที่ติดตามภายในได้ยากโผล่มาเต็มไปหมด...แล้วก็มีหลายที่ที่ใช้ LuaJIT ซึ่งอันนี้อินเทอร์เฟซก็ต่างกันแบบละเอียดอ่อนอีก เลยรู้สึกว่าปัญหาที่เกิดจากความต่างเล็กๆ น้อยๆ นี่แหละร้ายแรงที่สุด ดูเหมือนจะทำอะไรได้ยากด้วย เพราะมีหลายส่วนที่พฤติกรรมภายในเปลี่ยนไป.. =meong =.
ผมเคยมีประสบการณ์เขียน Edge driver ของ SmartThings ด้วย Lua
ก็พอใช้งานได้ประมาณหนึ่ง แต่ไม่ใช่ภาษาที่ตรงกับรสนิยมของผม
ผมมองว่าสภาพแวดล้อมการพัฒนาและ DE ก็เป็นส่วนหนึ่งของภาษาด้วย
อย่างแรกคือดูเหมือนชุมชนจะค่อนข้างแตกเป็นหลายกลุ่มอยู่พอสมควร
language server ก็มีหลายตัว แต่แต่ละตัวขาดฟีเจอร์ไปอย่างละนิด หรือไม่ก็ทำ code indexing ช้า และพอมีการแก้ไขก็เหมือนจะเริ่มใหม่ทั้งหมด
ทั้งการทำ indexing แบบ 1-base และการเขียน type hint ด้วยคอมเมนต์ก็ไม่ค่อยถูกใจผม
แถม type hint เองก็ไม่ได้มีมาตรฐานกลาง ดูเหมือนจะแตกต่างกันไปตาม language server แต่ละตัว
ส่วน coroutine ก็ทำให้นึกถึงของ Python ยุคเก่า...
แต่เรื่อง embedding กับ FFI นี่ต้องยอมรับว่าสะดวกจริงครับ
ช่วงนี้ Lua language server ที่คุณ sumneko ทำไว้เจ๋งมาก
'ㅁ... (น่าจะทำไว้ปี 22 หรือ 23) ตัวนี้ทำ indexing ได้ฉลาดใช้ได้เลยผมคิดว่าจุดเด่นของ Lua (ซึ่งก็เป็นจุดด้อยด้วย) น่าจะเกิดตอนที่ไปทำอะไรแปลก ๆ คือมันเขียนทับเมธอดของอ็อบเจ็กต์อื่นได้ง่ายแบบเหลือเชื่อ และเพราะงั้นมันเลยเป็นภาษาที่เหมาะมากกับการเขียนแบบตามใจนึก นึกอะไรออกก็เขียนได้เลย
ส่วน type hinting... อย่างที่บอกไป โซลูชันที่ออกมามีเยอะมากจริง ๆ แต่แทบไม่มีตัวไหนที่ลงหลักปักฐานได้ดีนัก เลยกำลังฝากความหวังไว้กับ luau ที่ทีม Roblox ทำครับ..
ความคิดเห็นบน Hacker News
Lua เหมาะกับการฝังใช้งาน แต่การเลือกมันเป็นภาษาสคริปต์ใน Redis เป็นสิ่งที่น่าเสียดายอยู่มาก ไม่ชอบตัวภาษาเองเลย ดูเหมือนจะมีแรงเสียดทานเมื่อเทียบกับสิ่งที่คาดหวังในระดับ abstraction การตัดสินใจด้านการออกแบบเล็ก ๆ หลายอย่างสะสมกันจนภาษาดูค่อนข้างไม่เป็นมิตร อย่างไรก็ตาม มันยังคุ้มค่าที่จะเลือกใช้เพราะเร็ว ผสานรวมได้ง่าย ใช้หน่วยความจำน้อย และเชื่อถือได้ แม้แต่ในระดับ C-API ก็ยังมีความไม่เป็นมิตรจากแนวทางการเข้าถึงแบบสแตก แม้จะเคยสัมผัสภาษาสแตกอย่าง FORTH มาก่อน แต่ตอนเขียน binding ก็ยังต้องใช้แรงคิดอยู่ดี
ถ้าคุณชอบ Lua แนะนำให้ดู Terra ด้วย Terra เป็นภาษาระดับต่ำสำหรับ system programming ที่ฝังอยู่ใน Lua และทำ metaprogramming ผ่าน Lua ได้ เป็นภาษาคอมไพล์แบบ static type คล้าย C/C++ และจัดการหน่วยความจำเองได้ แต่ต่างจาก C/C++ ตรงที่มันถูกออกแบบมาตั้งแต่ต้นให้ทำ metaprogramming ด้วย Lua ได้ โปรแกรม Terra ใช้ LLVM backend ตัวเดียวกับที่ใช้ในคอมไพเลอร์ C ของ Apple ซึ่งหมายความว่าโค้ด Terra ให้ประสิทธิภาพใกล้เคียงกับโค้ด C ที่เทียบเท่ากัน
เพิ่งทำงานรวม Lua เข้ากับ game engine แบบคัสตอม และเข้าใจเลยว่าการรวมเข้ากับภาษาอื่นนั้นสะอาดแค่ไหน อินเทอร์เฟซสะอาดมากจนสร้าง binding อัตโนมัติได้ง่าย ใช้ Roslyn Incremental Source Generators เพื่อสร้าง binding ระหว่าง C# กับ Lua แบบอัตโนมัติ และด้วยการออกแบบอินเทอร์เฟซจึงไม่ยากเลย Lua stack, dynamic typing และ "table" ทำให้สร้าง marshaller สำหรับคลาสข้อมูลตามต้องการระหว่าง C# และ Lua ได้ง่าย อย่างไรก็ตาม ก็มีคำวิจารณ์ที่ใช้ได้กับตัวภาษาเองอยู่มาก โดยเฉพาะไม่ชอบการทำดัชนีแบบเริ่มที่ 1 กำลังคิดจะออกแบบภาษาสคริปต์แบบฝังที่มีอินเทอร์เฟซคล้ายกันแต่แก้ปัญหาเหล่านี้
ไม่ได้รัก Lua มากขึ้นเลย ตรงกันข้าม ความไม่พอใจยิ่งชัดขึ้น แม้จะไม่ได้เขียน Lua มานานแล้ว แต่ก็เคยคิดว่ามันไม่เป็นธรรมชาติ ไม่เข้าใจว่าทำไมอาร์เรย์ถึงเป็น table ทำไมถึงจบด้วย nil และทำไมถึงเริ่มที่ 1 ไม่คิดว่า Lua ถูกประเมินค่าต่ำเกินไป มันได้รับความนิยมมากอยู่แล้วสำหรับการเขียนสคริปต์ใน game engine รุ่นเก่า
เคยทำแชตบอตด้วยคำสั่งปลั๊กอิน Lua แต่มีประสบการณ์ที่แย่มากตอนรวมมันเข้ากับโปรแกรม C++ ไม่เข้าใจว่าทำไมคนถึงบอกว่าฝังใช้งานง่าย ต้องจัดการสแตกเยอะมาก ตัวภาษาเองก็ยุ่งยากและไม่ช่วยอะไรเลยเวลาทำพลาด จะไม่ใช้ Lua อีก และจะหลีกเลี่ยงโปรเจกต์ที่ใช้ Lua
Lua ทำให้การเขียนโค้ดปริมาณมากค่อนข้างยาก เพราะเป็น weakly typed ไม่มี type hints และไม่มีการจัดการข้อผิดพลาดที่ดีพอ มันไม่ได้ถูกประเมินค่าต่ำเกินไป เมื่อเวลาผ่านไปกลับชอบภาษาที่เป็น static type และมี type hints มากขึ้นเรื่อย ๆ (Python, TypeScript) การเขียนโค้ด Python หรือ JS แบบไม่มี hints ในคอมมูนิตี้เป็นเรื่องไม่ดี ไม่นานมานี้เพิ่งเขียน JS ขนาด 1.5k cloc ใหม่เป็น TypeScript และเจอ null ที่ตกหล่น การเข้าถึงพร็อพเพอร์ตีของ null หรือ null ที่น่าสงสัยในเชิงความหมายอยู่หลายสิบจุดเสมอ
คิดว่าแอปพลิเคชันส่วนใหญ่ที่ต้องการสคริปต์ควรฝัง JavaScript มากกว่า มีข้อได้เปรียบมหาศาลจาก ecosystem ที่มีอยู่ คนอาจไม่ได้ชอบมันเสมอไป แต่ก็มีคนหลายล้านที่รู้จักมันอยู่แล้ว ไม่จำเป็นต้องมาเรียนรู้ใหม่เรื่องความแปลกของการทำดัชนีอาร์เรย์ การจบด้วย nil และอีกหลายสิบเรื่องที่ Lua จะให้ไปรู้ตอนรันไทม์ มี JS engine ทุกขนาดให้เลือกใช้ และระบบปฏิบัติการส่วนใหญ่ก็มี engine คุณภาพสูงและ framework สำหรับ embedding ที่เข้าถึงได้โดยไม่ต้องติดตั้งอะไรเพิ่ม แทนที่จะบังคับให้ผู้ใช้เรียนภาษาใหม่ ควรใช้ภาษามาตรฐาน จะช่วยประหยัดเวลาให้ทั้งผู้ใช้และตัวเราเอง
สนุกกับการทำงานกับ Lua และคิดว่ามันเป็นภาษาที่ดีมาก โดยเฉพาะอินเทอร์เฟซสำหรับฝังใน C/C++ ที่สะอาดและยืดหยุ่น แม้จะมีปัญหาเรื่องประสิทธิภาพ แต่เมื่อดูจากการที่ Lua ถูกใช้กันอย่างแพร่หลายใน game logic ของวิดีโอเกมประสิทธิภาพสูง ปัญหาเหล่านี้ก็น่าจะแก้ได้ อย่างไรก็ตาม ยังมีปัญหาอื่นที่ทำให้สับสนและทำให้ภาษาใช้งานยาก การเรียนรู้ Lua กับ C interface นั้นพอ ๆ กัน ทำให้การสลับไปมาระหว่างดิสทริบิวชันสับสนกว่าภาษาอื่น ถึงอย่างนั้นก็ยังคิดว่าภาษานี้ถูกประเมินค่าต่ำเกินไป
การฝัง Lua เป็นเรื่องสนุก แต่เหมือนกับ wasm แทบไม่เคยมีกรณีที่ต้องรันโค้ดใหม่โดยไม่คอมไพล์ไบนารีทั้งก้อนใหม่เลย สิ่งที่สนุกที่สุดคือการทำ game engine ด้วย C++ แล้วใช้ Lua สำหรับ game logic ทั้งหมด วงจรดีบักที่รวดเร็วมีประโยชน์มาก สิ่งที่สนุกอันดับสองคือการทำ IRC bot ที่รีโหลดลอจิก Lua ได้ สิ่งที่สนุกอันดับสามคือการใช้ Lua เป็นภาษาคอนฟิกที่ Turing-complete ถ้าต้องการอาร์เรย์ก็สร้างอาร์เรย์ใน Lua เอง สิ่งที่สนุกน้อยที่สุดคือปลั๊กอิน Blender ที่ส่งออกโมเดล 3D เป็น Lua ที่ถูกสร้างขึ้นมา
คิดว่า Lua ถูกประเมินค่าสูงเกินไป เพราะถูกใช้อย่างแพร่หลายในอุตสาหกรรมเกม ข้อดีเพียงอย่างเดียวของ Lua คือฝังใน C++ ได้ง่าย นอกนั้นคือฝันร้ายทั้งหมด