โปรแกรม Erlang ที่ฉันชอบที่สุด (2013)
(joearms.github.io)- จากช่วงโน้ตที่ให้มาเพียงอย่างเดียว ไม่สามารถยืนยันได้ว่า โปรแกรม Erlang ในชื่อเรื่องคืออะไร หรือเหตุใดจึงสำคัญ
- ข้อความที่ตรวจสอบได้ส่วนใหญ่มีเพียง ชิ้นส่วนสคริปต์ Shell และประโยคแก้ไขสั้น ๆ
- สคริปต์นี้วนผ่านไฟล์
*.png.png.metaในไดเรกทอรีปัจจุบัน และดึงส่วนก่อนจุดแรกออกมาจากชื่อไฟล์ - คำสั่งที่ถูกรันจริงคือ
git mv $i $j.png.metaและคำสั่งสำหรับเปลี่ยน$j.png.pngเป็น$j.pngถูกเพียงแค่พิมพ์ออกมา - เนื่องจากต้นฉบับช่วง 5-104 ถูกละไว้ จึงไม่สามารถยืนยันข้ออ้างสำคัญที่เกี่ยวกับชื่อเรื่องหรือคำอธิบายโค้ด Erlang ได้
เนื้อหาที่ตรวจสอบได้
- จากช่วงที่ให้มาเพียงอย่างเดียว จึงยากที่จะตัดสินได้ว่า “โปรแกรม Erlang ที่ชอบที่สุด” คืออะไร เหตุผลที่ชอบคืออะไร หรือโครงสร้างโค้ดเป็นอย่างไร
- ชิ้นส่วนโค้ดที่ตรวจสอบได้เป็น สคริปต์ Shell สำหรับเปลี่ยนชื่อไฟล์ ที่ขึ้นต้นด้วย
#!/bin/sh- วนทำงานกับไฟล์
*.png.png.meta - ใช้
j="${i%%.*}"เพื่อดึงส่วนก่อนจุดแรกจากชื่อไฟล์ git mv $i $j.png.metaถูกรันจริงgit mv $j.png.png $j.pngถูกแสดงผลด้วยechoเท่านั้น
- วนทำงานกับไฟล์
- มีประโยคว่า “Actually you don't need the really do this. It should have been water the plants.” ซึ่งตีความได้ว่า คำสั่งหรือยกตัวอย่างก่อนหน้านี้จริง ๆ แล้วไม่จำเป็น และสิ่งที่ควรเป็นคือ “water the plants”
- ตอนท้ายมีการกล่าวถึง Joe Armstrong และ Jeremy Ruston ร่วมกัน
บริบทที่จำกัดการตัดสิน
- หลายช่วงประกอบด้วยเมทาดาทาสถานะ/แถบด้านข้างของ TiddlyWiki, ข้อมูล Base64 ที่ดูเหมือน JPEG/PNG และเนื้อหาว่าง ทำให้ดึงข้อเท็จจริงจากตัวบทได้ยาก
- โน้ตที่ให้มาไม่มีข้อมูลสำคัญ เช่น การทำงานของโปรแกรม Erlang, โค้ด, เหตุผลด้านการออกแบบ, ตัวอย่าง, ตัวเลข, เวิร์กโฟลว์ หรือข้ออ้างหลัก
- แม้แต่ชิ้นส่วนสคริปต์ Shell ก็ถูกให้มาเพียงบางส่วนโดยไม่มีคำอธิบายแวดล้อม จึงยืนยันไม่ได้ว่าเป็นส่วนหนึ่งของงานใด
ช่วงที่ถูกละไว้
- มีการระบุชัดเจนในอินพุตว่า ต้นฉบับช่วง 5-104 ถูกละไว้เนื่องจากข้อจำกัดด้านความยาว/ค่าใช้จ่าย
- สรุปนี้สะท้อนเฉพาะช่วงโน้ตที่ให้มา และไม่ได้ครอบคลุมรายละเอียดหรือข้อสรุปของต้นฉบับทั้งหมด
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
ถ้าเซิร์ฟเวอร์คลอเจอร์
Fสามารถรับข้อความ{become, F}ได้นอกเหนือจากข้อความของตัวเอง ก็จะเปลี่ยนเซิร์ฟเวอร์ให้กลายเป็นพฤติกรรมใหม่ไปเรื่อย ๆ ได้นอกเรื่องไปไกลหน่อย แต่ผมยังจำได้ว่าเคยคุยกับ Joe ในงานประชุม Erlang เขาตื่นเต้นกับเทคโนโลยีอยู่เสมอ และยินดีคุยกับใครก็ได้ เขาเสียดายที่ Windows แย่ลงทุกปีและใช้งานได้น้อยลงเรื่อย ๆ และเคยบอกว่าสักวันหนึ่งถ้าจะดูไฟล์อาจต้องดูโฆษณาอยู่พักหนึ่งถึงจะปลดล็อกได้ ซึ่งก็เกือบจะเป็นจริงแล้ว Windows 11 มีโฆษณาอยู่แล้ว และถ้าจะลบก็ต้องตั้งใจไปหาในการตั้งค่าเอง ดังนั้นพอถึง Windows 13 ก็น่าจะเป็นแบบนั้นจริง ๆ
เช่น เสียงหูฟังข้างหนึ่งดังกว่าอีกข้างมาก, แอปของ Microsoft แครชแบบประหลาด ๆ, หน้าเอกสารของ Windows เปิดไม่ได้ในเบราว์เซอร์ใดเลยจนต้องใช้เว็บอาร์ไคฟ์, จู่ ๆ ก็ตรวจไม่พบจอภายนอกที่เคยใช้ได้ดี หรือหน้าจอกะพริบ Office โดยพื้นฐานจะชักนำให้บันทึกไว้บนคลาวด์แทนที่จะเป็นเครื่อง แต่ผมอยากให้ไฟล์เป็นแบบ local-first และคลาวด์เป็นแค่ข้อมูลสำรองมากกว่า WSL ค่อนข้างหยาบ ๆ แต่ก็แทบจะเป็นเหตุผลเดียวที่ยังทำให้ใช้ Windows ได้
ผมได้ยินเสมอว่า Joe เป็นคนยอดเยี่ยม และก็เข้าใจว่าทำไม ตอนเริ่มหัดเขียนโค้ดด้วยตัวเอง ผมอ่านหนังสือ Erlang ของเขา ความขี้เล่น ความถ่อมตัว และจินตนาการของเขามีอิทธิพลต่อผมมาก แม้แทบไม่ได้ใช้ Erlang จริง ๆ แต่งานเขียนของเขาเปลี่ยนวิธีคิดของผมเกี่ยวกับโค้ด และผมอยากให้วัฒนธรรมคณิตศาสตร์ วิศวกรรมซอฟต์แวร์ และวิทยาการคอมพิวเตอร์เปิดรับ ความขี้เล่นและความถ่อมตัว มากขึ้น
วิดีโอสรุปสั้น ๆ 35 นาทีที่อธิบายว่า BEAM ต่างจาก virtual machine อื่น ๆ อย่าง JVM หรือ Node อย่างไร: https://www.youtube.com/watch?v=pO4_Wlq8JeI
คิดถึง Joe จัง ความหลงใหลอันแพร่เชื้อได้ในการทำให้คอมพิวติ้ง ดีขึ้น ของเขาฝังลึกอยู่ในตัวผมสมัยหนุ่ม และในแนวทางที่ผมเข้าหาเทคโนโลยีตอนนี้
universal_server() -> receive {become, F} -> F() end.พูดตามตรง ผมยังไม่เข้าใจพลังของ universal_server นี้อย่างเต็มที่ ใครช่วยอธิบายให้ฟังได้ไหม
ใน Erlang เรามักสร้างโปรเซสจำนวนมากเพื่อแก้ปัญหา และโปรเซสส่วนใหญ่ก็รอข้อความอยู่ ความแตกต่างสำคัญคือโปรเซสของ Erlang สามารถรันบนเครื่องระยะไกลได้อย่างไร้รอยต่อ โปรเซสนี้รับข้อความแบบทูเพิลที่มีอะตอมชื่อ
becomeกับฟังก์ชันอยู่ข้างใน และเมื่อโปรเซสอื่นส่งข้อความนั้นมาเมื่อไรก็ได้ มันจะ “แปลงร่าง” เป็นฟังก์ชันนั้นกล่าวคือสามารถสลับลอจิกของลูปรอให้เป็นลอจิกโปรโตคอลที่ต้องการได้ ในตัวอย่างมีการรันลูปนี้ไว้บนหลายเครื่องแล้วส่งฟังก์ชันที่ implements gossip protocol ไปให้ แต่คุณก็สามารถส่งข้อความที่ทำให้มันกลายเป็นไคลเอนต์ BitTorrent ได้เหมือนกัน Joe เป็นทั้งอัจฉริยะและคนที่ใจดีมาก และ Erlang เป็นหนึ่งในงานสร้างสรรค์ทางเทคนิคที่งดงามที่สุดที่ผมเคยเห็น มันทำให้มอง concurrency แบบใหม่โดยสิ้นเชิง
receiveคล้ายกับคำสั่งswitchสำหรับข้อความขาเข้า แต่จริง ๆ แล้วคือ pattern matchingตัวอย่างเช่น คุณสร้างเซิร์ฟเวอร์ factorial ที่รับ
{From, N}แล้วส่งผลลัพธ์กลับด้วยFrom ! factorial(N)ได้!คือโอเปอเรเตอร์ที่ส่งผลลัพธ์ไปยังโปรเซสที่จะรับคืนโค้ดทดสอบจะเริ่ม
universal_serverแล้วใช้Pid ! {become, fun factorial_server/0}เพื่อให้มันกลายเป็นเซิร์ฟเวอร์ factorial จากนั้นส่ง{self(), 50}เพื่อรับค่า factorial ของ 50 กลับมา จุดแข็งใหญ่ของ Erlang คือ parallelism แบบกระจายและ hot code update และในที่นี้มันปรากฏออกมาในรูปแบบที่ลูปรับข้อความของuniversal_serverถูกเขียนทับด้วยลูปรับข้อความของfactorial_serverแต่ผมคิดว่า hot code update จริง ๆ คงไม่ได้ทำงานตรงตามวิธีนี้แต่ใน Erlang เราสร้างเครือข่ายเซิร์ฟเวอร์ Erlang แบบกระจาย แล้วปล่อยให้เซิร์ฟเวอร์เป็น ทรัพยากรคำนวณอเนกประสงค์ ที่ทำงานตามที่ไคลเอนต์ต้องการได้ โค้ดมาจากไคลเอนต์ และไม่จำเป็นต้องขอให้ผู้ดูแลระบบติดตั้งไบนารีลงในทุกเครื่อง เพียงส่งฟังก์ชันไป เครื่องระยะไกลก็จะเรียกใช้
ฟังก์ชันจริงที่จะใช้รันเซิร์ฟเวอร์ถูกส่งมาจากไคลเอนต์ และโปรเซส Erlang ก็จะกลายเป็นเซิร์ฟเวอร์นั้นตามฟังก์ชันนั้น เมื่อพิจารณาความสามารถ hot reloading ของ Erlang ด้วย โครงสร้างเรียบง่ายนี้ก็ยิ่งทรงพลังขึ้น โปรเซส Erlang คือทรัพยากรคำนวณที่รอรับงาน และถ้างานนั้นคือการรันเซิร์ฟเวอร์ทั้งตัว ก็ถือว่าเท่มาก
ดังนั้นโปรเซสจะกลายเป็นอะไรก็ได้ตามโค้ดที่คุณส่งไป ถ้าต้องควบคุมเตาไมโครเวฟ แล้วต่อมาทำ quantum computing และวันถัดไปต้องทำนายผู้ชนะการแข่งขันฟุตบอล ก็แค่ส่งโค้ดที่จำเป็นสำหรับแต่ละงานไป มันก็ทำตามนั้น
ผมใช้เวลามากในการอธิบายว่า BEAM พิเศษอย่างไร และ concurrency ของ Erlang/Elixir ต่างจาก concurrency ของ Go หรือ Java อย่างไร
จากนี้ไปคงแค่ลิงก์โปรแกรม Erlang ที่ Joe ชอบที่สุดกับเธรด HN นี้ก็พอ
บล็อกโพสต์นี้ถูกพูดถึงในงานบรรยายยอดเยี่ยมเมื่อไม่นานมานี้ด้วย: https://youtu.be/pQ0CvjAJXz4
ผมมีแค่ความเข้าใจระดับสูงเกี่ยวกับภาษา Erlang แต่ยังไม่เคยเขียนโปรแกรมเอง เลยสงสัยว่าโค้ดนี้จำเป็นตรงไหน
universal_server() -> receive {become, F} -> F() end.แค่เรียก
F()บนเครื่องระยะไกลโดยตรงก็ได้นี่นา เครื่องเสมือนระยะไกลต้องมีโค้ดของFอยู่แล้ว ดังนั้นตัวอย่างนี้อาจหมายถึงการ serialize โค้ดของFแล้วส่งไปก็ได้ ถ้าเป็นการจัดการ boilerplate ร่วมกันก็พอเข้าใจประโยชน์ แต่ตอนนี้มันดูเหมือนแค่รอข้อความbecome Fแล้วรันF()ที่นี่
Fเป็น closure จึงอาจมีไม่ใช่แค่โค้ด แต่รวมถึงตัวแปรที่ capture ไว้และสภาพแวดล้อมตอนที่มันถูกสร้างขึ้นด้วย เมื่อเรียกF()โค้ดนั้นจะถูกทำงาน และสามารถเข้าถึงสภาพแวดล้อมรอบ ๆ ตอนที่Fถูกสร้างขึ้นได้ใน Erlang สามารถส่ง closure ข้ามเครือข่ายไปยัง Erlang node อื่นได้ แต่โค้ดของโมดูลที่ closure อ้างถึงต้องมีอยู่ในทุก node ถ้าเป็นโค้ด production ก็น่าจะทำอย่างที่บอก คือเรียกโมดูล
Fโดยตรงแล้วส่งอาร์กิวเมนต์อย่างชัดเจนมากกว่า นี่ใกล้เคียงกับเดโมเจ๋ง ๆ ที่แสดงให้เห็นว่าทำอะไรได้บ้างF()สามารถเป็น บริบทระดับบนสุด ที่ดีพอ ๆ กับบริบทเดิมใด ๆ ได้ ซึ่งเจ๋งมากคำขอเดิมสามารถถูกจัดการต่อไปด้วยลอจิกเก่าอย่างเป็นธรรมชาติ ขณะที่คำขอใหม่เริ่มด้วยลอจิกใหม่ได้ และท้ายที่สุดลอจิกเก่าก็อาจถูก garbage collect ไป
Fอยู่แล้ว แต่ก็สามารถส่งโค้ดไปยังเครื่องเสมือนระยะไกลได้เช่นกันตัวอย่างเช่น ใน Elixir สามารถใช้
Code.compile_stringเพื่อรับชื่อโมดูลและไบนารี BEAM bytecode ได้ จากนั้นส่ง bytecode นั้นไปยังเครื่องเสมือนอื่น แล้วใช้:rpc.call('node@remote_host', :code, :load_binary, [the_module_name, "filename_doesnt_really_matter", binary_code])เพื่อโหลดเข้าเครื่องเสมือนระยะไกล แล้วค่อยเรียกด้วยspawn('node@remote_host', my_module, my_function, [args])ที่นี่
Fเป็นตัวแปรที่แทนโปรแกรมใหม่ซึ่งถูก serialize แล้วส่งเป็นข้อความระหว่างโปรเซส และในกรณีนี้ก็ถูกส่งผ่านเครือข่ายด้วยมีเลกเชอร์ที่ Joe อธิบายวิธีเขียนเซิร์ฟเวอร์พื้นฐานด้วย Erlang ด้วย: https://gioorgi.com/2015/erlang-lesson1/
ผมจดตามเองและอธิบายเพิ่มอีกนิด ซึ่งแสดงให้เห็นพลังของ ภาษาแบบ asynchronous อย่าง Erlang/Elixir เมื่อเทียบกับภาษาอื่น น่าเสียดายที่ทุกวันนี้ไม่ค่อยมีคนใช้มากนัก
ช่วงหลังผมติด Julia อยู่ และดูเหมือนว่ามันยืมไอเดียของ Erlang มาไม่น้อยในโมเดลแบบ distributed
เซิร์ฟเวอร์เฉพาะกิจ แบบนี้ที่ทำงานข้ามหลาย node ราวกับเวทมนตร์ สามารถทำซ้ำใน Julia ได้ค่อนข้างง่ายด้วย ผมไม่แน่ใจนัก แต่ดูไม่น่าเป็นไปได้ที่โมดูล
Distributedของ Julia จะไม่ได้รับแรงบันดาลใจจาก Erlang เลยแม้แต่นิดเดียวผมชอบ Erlang มากจริง ๆ และอยากมีโอกาสใช้มันมากกว่านี้ แต่การได้เห็นแนวคิดของมันซึมไปสู่แพลตฟอร์มอื่นก็เป็นเรื่องดีเช่นกัน