กลับไปหน้าบทความ

อ่าน 22 นาที

นิม (ภาษาโปรแกรม)

Nim เป็น ภาษาโปรแกรมระบบ ระดับสูง แบบ คอมไพล์ได้ อเนกประสงค์ รองรับ หลาย พาราดิกม์ กำหนด ประเภทแบบคงที่ [ 9 ] ได้รับการออกแบบและพัฒนาโดยทีมงานที่นำโดย Andreas Rumpf Nim...

นิม (ภาษาโปรแกรม)

นิม
โลโก้มงกุฎนิม
กระบวนทัศน์หลายกระบวนทัศน์ : คอมไพล์ , พร้อมกัน , ขั้น ตอน , คำสั่ง , ฟังก์ชัน , เชิงวัตถุ , เมตา
ออกแบบโดยแอนเดรียส รัมป์ฟ
นักพัฒนาทีมนิมหลาง[ 1 ]
ปรากฏครั้งแรก2008 ( 2008 )
เวอร์ชันเสถียร
2.2.10 [ 2 ] แก้ไขข้อมูลนี้บนวิกิดาต้า / 24 เมษายน 2026 ( 24 เมษายน 2569 )
วินัยในการพิมพ์คงที่[ 3 ]แข็งแกร่ง [ 4 ]อนุมานได้โครงสร้าง
ขอบเขตคำศัพท์
ภาษาการใช้งานปาสคาล (2005–2008) นิม (2008–ปัจจุบัน, ดำเนินงานด้วยตนเอง)
แพลตฟอร์มIA-32 , x86-64 , ARM , Aarch64 , RISC-V , PowerPC ... [ 5 ]
โอเอสข้ามแพลตฟอร์ม[ 6 ]
ใบอนุญาตใบอนุญาต MIT [ 7 ] แก้ไขข้อมูลนี้บนวิกิดาต้า
นามสกุลไฟล์.nim, .nims, .nimble
เว็บไซต์nim-lang .org
ได้รับอิทธิพลจาก
Ada , Modula-3 , Lisp , C++ , Object Pascal , Python , Oberon , Rust , ParaSail [ 8 ]

Nimเป็นภาษาโปรแกรมระบบระดับสูงแบบคอมไพล์ได้อเนกประสงค์รองรับหลายพาราดิกม์กำหนดประเภทแบบคงที่[ 9 ]ได้รับการออกแบบและพัฒนาโดยทีมงานที่นำโดย Andreas Rumpf Nim มีเป้าหมายที่จะเป็น "มีประสิทธิภาพ แสดงออกได้ดี และสง่างาม" [ 10 ]และรองรับ พาราดิกม์การเขียนโปรแกรมแบบเม ตาโปรแกรมมิฟังก์ชันการส่งข้อความ [ 11 ] แบบขั้นตอนและแบบเชิงวัตถุ Nim มีคุณสมบัติต่างๆ เช่นการสร้างโค้ดในเวลาคอมไพล์ประเภทข้อมูลเชิงพีชคณิตและอินเทอร์เฟซฟังก์ชันภายนอก (FFI) สำหรับการเชื่อมต่อกับC , C++ , Objective-CและJavaScriptนอกจากนี้ยังรองรับการคอมไพล์ไปยังภาษาเหล่านี้ในรูปแบบตัวแทนระดับกลางด้วย

คำอธิบาย

Nim เป็นภาษาที่มีการกำหนดประเภทแบบคงที่[ 12 ]รองรับ คุณสมบัติ เมตาโปรแกรม มิ่งในเวลาคอมไพล์ เช่น มาโครทางไวยากรณ์และมาโครการเขียนเทอมใหม่ [ 13 ] มาโครการเขียนเทอมใหม่ช่วยให้ การใช้งาน ไลบรารีของโครงสร้างข้อมูลทั่วไป เช่น bignums และเมทริกซ์ สามารถใช้งานได้อย่างมีประสิทธิภาพและผสานรวมทางไวยากรณ์ ราวกับว่าเป็นสิ่งอำนวยความสะดวกในภาษา[ 14 ]รองรับตัววนซ้ำและสามารถใช้เป็นเอนทิตีระดับแรกได้[ 13 ]เช่นเดียวกับฟังก์ชัน ทำให้สามารถใช้วิธีการเขียนโปรแกรมเชิงฟังก์ชัน ได้ รองรับการเขียนโปรแกรมเชิงวัตถุ โดย การสืบทอดและการเรียกใช้หลายรายการฟังก์ชันสามารถเป็นแบบเจเนริกและโอเวอร์โหลดได้ และเจเนริก ได้รับการปรับปรุงเพิ่มเติมโดยการสนับสนุน คลาสประเภทของNim รองรับ การโอเวอร์โหลดตัวดำเนินการด้วย[ 13 ] Nim มีกลยุทธ์การจัดการหน่วยความจำที่ปรับแต่งได้หลายแบบ รวมถึงการรวบรวมขยะแบบติดตามการนับการอ้างอิงและระบบแบบแมนนวลทั้งหมดโดยค่าเริ่มต้นคือการนับการอ้างอิง แบบกำหนดได้ พร้อมการเพิ่มประสิทธิภาพผ่านความหมายของการย้ายและการรวบรวมวงจรผ่านการลบแบบทดลอง[ 15 ]

[Nim] ... นำเสนอการออกแบบที่แปลกใหม่ที่สุดซึ่งผสมผสานระหว่างPascalและPythonและคอมไพล์เป็นโค้ด C หรือ JavaScript [ 16 ]

— แอนดรูว์ บินสต็อก บรรณาธิการบริหารของวารสารดร. ด็อบส์ปี 2014

ณ เดือนสิงหาคม พ.ศ. 2566 Nim คอมไพล์เป็น C, C++, JavaScript, Objective-C, [ 17 ]และ LLVM [ 18 ]

ประวัติศาสตร์

สาขา เวอร์ชั่น วันที่วางจำหน่าย[ 19 ]
0.x ไม่รองรับ: 0.10.2 29 ธันวาคม 2014
ไม่รองรับ: 0.11.24 พฤษภาคม 2558
ไม่รองรับ: 0.12.027 ตุลาคม 2558
ไม่รองรับ: 0.13.018 มกราคม 2559
ไม่รองรับ: 0.14.29 มิถุนายน 2559
ไม่รองรับ: 0.15.223 ตุลาคม 2559
ไม่รองรับ: 0.16.08 มกราคม 2560
ไม่รองรับ: 0.17.27 กันยายน 2017
ไม่รองรับ: 0.18.01 มีนาคม 2018
ไม่รองรับ: 0.19.613 พฤษภาคม 2562
ไม่รองรับ: 0.20.217 มิถุนายน 2562
1.0 ไม่รองรับ: 1.0.023 กันยายน 2019
ไม่รองรับ: 1.0.1027 ตุลาคม 2020
1.2 ไม่รองรับ: 1.2.02020-04-03
ไม่รองรับ: 1.2.189 กุมภาพันธ์ 2022
1.4 ไม่รองรับ: 1.4.016 ตุลาคม 2020
ไม่รองรับ: 1.4.825 พฤษภาคม 2021
1.6 ไม่รองรับ: 1.6.019 ตุลาคม 2021
ไม่รองรับ: 1.6.2016 เมษายน 2567
2.0 ไม่รองรับ: 2.0.01 สิงหาคม 2023
รองรับ: 2.0.1622 เมษายน 2568
2.2 ไม่รองรับ: 2.2.02024-10-02
เวอร์ชันล่าสุด:2.2.1024 เมษายน 2569
ตำนาน:
ไม่ได้รับการสนับสนุน
ได้รับการสนับสนุน
เวอร์ชั่นล่าสุด
สำหรับแต่ละสาขา 0.x จะแสดงเฉพาะเวอร์ชันย่อยล่าสุดเท่านั้นสำหรับสาขาที่ใหม่กว่า จะแสดงทั้งเวอร์ชันย่อยแรกและเวอร์ชันย่อยล่าสุด

Andreas Rumpf เป็นผู้ออกแบบและผู้พัฒนา Nim คนแรก เขาได้รับประกาศนียบัตรด้านวิทยาการคอมพิวเตอร์จากมหาวิทยาลัยเทคนิคไคเซอร์สเลาเทิร์นประเทศเยอรมนีความสนใจในการวิจัยของเขารวมถึงระบบเรียลไทม์แบบแข็งระบบฝังตัวการสร้างคอมไพเลอร์และปัญญาประดิษฐ์[ 20 ]

การพัฒนาเบื้องต้นของ Nim เริ่มขึ้นในปี 2548 ภายใต้ชื่อNimrodและเปิดตัวสู่สาธารณะในปี 2551 [ 21 ] : 4–11

คอมไพเลอร์ Nim เวอร์ชันแรกเขียนด้วยภาษา Pascalโดยใช้คอมไพเลอร์Free Pascal [ 22 ]ในปี 2551 คอมไพเลอร์เวอร์ชันที่เขียนด้วยภาษา Nim ได้ถูกเผยแพร่[ 23 ]คอมไพเลอร์นี้เป็นซอฟต์แวร์โอเพนซอร์สฟรีและได้รับการพัฒนาโดยชุมชนอาสาสมัครที่ทำงานร่วมกับ Andreas Rumpf [ 24 ]ภาษาดังกล่าวได้รับการเปลี่ยนชื่ออย่างเป็นทางการจากNimrodเป็นNimเมื่อมีการเผยแพร่เวอร์ชัน 0.10.2 ในเดือนธันวาคม 2557 [ 25 ]เมื่อวันที่ 23 กันยายน 2562 เวอร์ชัน 1.0 ของ Nim ได้ถูกเผยแพร่ ซึ่งแสดงให้เห็นถึงความสมบูรณ์ของภาษาและชุดเครื่องมือ เมื่อวันที่ 1 สิงหาคม 2566 เวอร์ชัน 2.0 ของ Nim ได้ถูกเผยแพร่ ซึ่งแสดงให้เห็นถึงความสมบูรณ์ ความเสถียร และการเปลี่ยนไปใช้โมเดลหน่วยความจำ ARC/ORC [ 26 ]

การออกแบบภาษา

ไวยากรณ์

ไวยากรณ์ของ Nim คล้ายกับของPython [ 27 ] บล็อกโค้ดและคำสั่งซ้อนกันจะถูกระบุโดยใช้ช่องว่างตามกฎออฟไซด์ คำหลัก หลายคำเหมือนกับคำที่เทียบเท่าใน Python ซึ่งส่วนใหญ่เป็นคำหลักภาษาอังกฤษ ในขณะที่ภาษาโปรแกรมอื่นๆ มักใช้เครื่องหมายวรรคตอน ด้วยเป้าหมายที่จะปรับปรุงภาษาที่มีอิทธิพล แม้ว่า Nim จะรองรับ ไวยากรณ์แบบ เยื้องเหมือน Python แต่ก็เพิ่มความยืดหยุ่นเพิ่มเติม ตัวอย่างเช่นคำสั่ง เดียว อาจครอบคลุมหลายบรรทัดหากมีเครื่องหมายจุลภาคหรือตัวดำเนินการไบนารีอยู่ที่ท้ายแต่ละบรรทัด Nim ยังรองรับตัวดำเนินการที่ผู้ใช้กำหนดเองด้วย

ต่างจาก Python, Nim ใช้ระบบการกำหนดประเภทข้อมูลแบบคงที่ (static typing) ระบบประเภทของ Nim ช่วยให้การแปลงประเภทข้อมูลการแคสต์ทำได้ง่าย และมีไวยากรณ์สำหรับการเขียนโปรแกรมแบบเจเนริก ที่สำคัญ Nim มีคลาสประเภท (type classes) ที่สามารถใช้แทนประเภทข้อมูลได้หลายประเภท และมีคลาสประเภทดังกล่าวให้ใช้งานได้ทันที คลาสประเภทช่วยให้สามารถทำงานกับประเภทข้อมูลหลายประเภทได้ราวกับว่าเป็นประเภทข้อมูลเดียว ตัวอย่างเช่น:

  • openarray– แสดงถึงอาร์เรย์ที่มีขนาดแตกต่างกัน ลำดับ และสตริง
  • SomeSignedInt– แสดงถึงชนิดข้อมูลจำนวนเต็มที่มีเครื่องหมายทั้งหมด
  • SomeInteger– แสดงถึงชนิดข้อมูลจำนวนเต็มทั้งหมด ไม่ว่าจะเป็นจำนวนเต็มมีเครื่องหมายหรือไม่ก็ตาม
  • SomeOrdinal– แสดงถึงชนิดข้อมูลพื้นฐานที่นับได้และเรียงลำดับได้ทั้งหมด ยกเว้นจำนวนที่ไม่ใช่จำนวนเต็ม

ตัวอย่างโค้ดนี้แสดงวิธีการใช้งาน typeclasses ในภาษา Nim:

# มาประกาศฟังก์ชันที่รับตัวเลขชนิดใดก็ได้และแสดงค่าทศนิยมของตัวเลขนั้นกัน# ใน Nim ฟังก์ชันที่มีผลข้างเคียงเรียกว่า "proc" proc timesTwo ( i : SomeNumber ) = echo i * 2
# มาเขียนฟังก์ชันอีกฟังก์ชันหนึ่งที่รับประเภทลำดับใดๆ ก็ได้ และส่งคืนค่า# สองเท่าของค่าที่ป้อนเข้ามาในรูปแบบเดิม หากเป็นตัวเลขหรือส่งคืนค่าที่ป้อนเข้ามาเองในกรณีอื่นๆ# เราใช้ Type(T) ทั่วไป และระบุว่าต้องเป็น Ordinal เท่านั้นfunc twiceIfIsNumber [ T : SomeOrdinal ] ( i : T ): T = when T is SomeNumber : # `when` คือ `if` ที่ประเมินระหว่างการคอมไพล์result = i * 2 # คุณสามารถเขียน `return i * 2` ได้เช่นกันelse : # หาก Ordinal ไม่ใช่ตัวเลข จะถูกแปลงเป็น int # คูณด้วยสอง และแปลงกลับเป็นประเภทพื้นฐานresult = ( i . int * 2 ). T
echotwiceIfIsNumber(67)# Passes an int to the function echo twiceIfIsNumber(67u8) # Passes an uint8echotwiceIfIsNumber(true)# Passes a bool (Which is also an Ordinal)

อิทธิพล

ตามที่ผู้สร้างภาษากล่าวไว้ Nim ถูกสร้างขึ้นเพื่อรวมส่วนที่ดีที่สุดของระบบการพิมพ์ Ada ความยืดหยุ่น ของ PythonและระบบมาโครLisp ที่ทรงพลัง [ 28 ]

นิมได้รับอิทธิพลจากลักษณะเฉพาะของภาษาที่มีอยู่เดิม ซึ่งรวมถึงสิ่งต่อไปนี้:

ไวยากรณ์การเรียกฟังก์ชันแบบเดียวกัน

Nim รองรับไวยากรณ์การเรียกฟังก์ชันแบบเดียวกัน (UFCS) [ 29 ]และความเท่าเทียมกันของตัวระบุ ซึ่งให้ความยืดหยุ่นในการใช้งานในระดับสูง

ตัวอย่างเช่น แต่ละบรรทัดเหล่านี้จะพิมพ์"hello world"เหมือนกัน เพียงแต่ใช้ไวยากรณ์ที่แตกต่างกัน:

echo "hello world" echo ( "hello world" ) "hello world" . echo () "hello world" . echo echo ( "hello" , " world" ) "hello" . echo ( " world" ) "hello" . echo " world"

ความเท่าเทียมกันของตัวระบุ

Nim แทบจะไม่คำนึงถึงรูปแบบเลยตัวระบุ สองตัว จะถือว่าเท่ากันหากแตกต่างกันเพียงแค่การใช้ตัวพิมพ์ใหญ่และเครื่องหมายขีดล่าง ตราบใดที่อักขระตัวแรกเหมือนกัน นี่เป็นการเปิดใช้งานการผสมผสานรูปแบบต่างๆ ในไลบรารี ผู้ใช้คนหนึ่งสามารถเขียนไลบรารีโดยใช้ snake_case เป็นข้อกำหนด และผู้ใช้คนอื่นสามารถใช้ไลบรารีนั้นในรูปแบบ camelCase ได้โดยไม่มีปัญหา[ 30 ]

const useHttps = true assert useHttps == useHttps assert useHTTPS == useHttps assert use_https == useHttps

การหยุด

คุณสมบัติ การจำกัดขอบเขตช่วยให้สามารถใช้ชื่อใดก็ได้สำหรับตัวแปรหรือฟังก์ชัน แม้ว่าชื่อเหล่านั้นจะเป็นคำสงวนสำหรับคำหลักก็ตาม ตัวอย่างของการจำกัดขอบเขตคือความสามารถในการกำหนดตัวแปรชื่อifโดยไม่ขัดแย้งกับคำหลักifการใช้งานของ Nim ทำได้โดยใช้เครื่องหมายแบ็กติ๊ก ทำให้สามารถใช้คำสงวนใดก็ได้เป็นตัวระบุ[ 31 ]

ประเภทType = object ` int` : intlet ` object ` = Type (` int `: 9 ) assert ` object ` is Type assert ` object `.` int ` == 9var ` var ` = 42 ให้` ให้` = 8 ยืนยัน` var ` + ` ให้` == 50const ` assert ` = true assert ` assert `

คอมไพเลอร์

โดยค่าเริ่มต้นคอมไพเลอร์ Nim จะสร้าง โค้ด C ที่รวดเร็วและได้รับการปรับให้เหมาะสม โดยจะเลื่อนการคอมไพล์เป็นโค้ดออบเจ็กต์ไปยังคอมไพเลอร์ C ภายนอก [ 32 ]เพื่อใช้ประโยชน์จากการปรับให้เหมาะสมและความสามารถในการพกพาของคอมไพเลอร์ที่มีอยู่ รองรับคอมไพเลอร์ C หลายตัว รวมถึงClang , Microsoft Visual C++ (MSVC), MinGWและGNU Compiler Collection (GCC) นอกจากนี้ คอมไพเลอร์ Nim ยังสามารถสร้าง โค้ด C++ , Objective-CและJavaScriptเพื่อให้สามารถเชื่อมต่อกับอินเทอร์เฟซการเขียนโปรแกรมแอปพลิเคชัน ( API ) ที่เขียนด้วยภาษาเหล่านั้น ได้อย่างง่ายดาย [ 9 ]นักพัฒนาสามารถเขียนใน Nim จากนั้นคอมไพล์เป็นภาษาใดก็ได้ที่รองรับ นอกจากนี้ยังช่วยให้สามารถเขียนแอปพลิเคชันสำหรับiOSและAndroidได้อีกด้วย ยังมี แบ็กเอนด์ LLVM ที่ไม่เป็นทางการ ซึ่งช่วยให้สามารถใช้คอมไพเลอร์ Nim ในลักษณะแบบสแตนด์อะโลนได้[ 18 ]

คอมไพเลอร์ Nim เป็นแบบโฮสต์ตัวเองหมายความว่ามันถูกเขียนขึ้นด้วยภาษา Nim [ 33 ]คอมไพเลอร์รองรับการคอมไพล์ข้ามแพลตฟอร์ม ดังนั้นจึงสามารถคอมไพล์ซอฟต์แวร์สำหรับระบบปฏิบัติการที่รองรับได้ ไม่ว่าจะเป็นเครื่องพัฒนาใดก็ตาม ซึ่งมีประโยชน์สำหรับการคอมไพล์แอปพลิเคชันสำหรับระบบฝังตัว และสำหรับสถาปัตยกรรมคอมพิวเตอร์ที่ไม่ธรรมดาและหายาก

ตัวเลือกคอมไพเลอร์

โดยค่าเริ่มต้น คอมไพเลอร์ Nim จะสร้างบิลด์ดีบัก[ 34 ] ด้วยตัวเลือกนี้สามารถสร้างบิลด์รีลีสได้ ซึ่งได้รับการปรับให้เหมาะสมเพื่อความเร็วและมีการตรวจสอบรันไทม์น้อยลง-d:release[ 34 ]ด้วยตัว เลือกนี้-d:dangerสามารถปิดใช้งานการตรวจสอบรันไทม์ทั้งหมดได้ หากต้องการความเร็วสูงสุด[ 34 ]

การจัดการหน่วยความจำ

Nim รองรับกลยุทธ์การจัดการหน่วยความจำหลายแบบ รวมถึงดังต่อไปนี้: [ 35 ]

  • --mm:arc– การนับการอ้างอิงอัตโนมัติ(ARC) พร้อม การเพิ่มประสิทธิภาพ ความหมายของการย้ายเสนอฮีปที่ใช้ร่วมกัน ให้ประสิทธิภาพที่กำหนดได้อย่างสมบูรณ์สำหรับระบบเรียลไทม์ที่เข้มงวด[ 36 ]วงจรการอ้างอิงอาจทำให้เกิดการรั่วไหลของหน่วยความจำ: สามารถจัดการสิ่งเหล่านี้ได้โดยการระบุคำอธิบายประกอบ{.acyclic.}pragma ด้วยตนเองหรือโดยการใช้--mm:orc.
  • --mm:orc– เหมือนกัน--mm:arcแต่เพิ่มตัวรวบรวมวงจร ("O") โดยอิงจาก "การลบทดลอง" [ 37 ]ตัวรวบรวมวงจรจะวิเคราะห์เฉพาะประเภทที่อาจเป็นวงจรเท่านั้น
  • --mm:refc– ตัวเก็บขยะมาตรฐานที่ใช้การนับการอ้างอิง แบบเลื่อนออกไป พร้อมด้วยตัวเก็บขยะสำรองแบบทำเครื่องหมายและกวาดอย่างง่ายเพื่อเก็บรอบการทำงาน ฮีปเป็นแบบเฉพาะเธรด
  • --mm:markAndSweepระบบจัดการหน่วยความจำ แบบง่ายๆ ที่ใช้หลักการทำเครื่องหมายและกวาด (mark-and-sweep ) ฮีปจะทำงานเฉพาะในแต่ละเธรด
  • --mm:boehmระบบเก็บขยะของBoehmให้บริการกองขยะแบบใช้ร่วมกัน
  • --mm:goตัวจัดการขยะของภาษาGoซึ่งมีประโยชน์สำหรับการทำงานร่วมกันกับภาษา Goมีฮีปที่ใช้ร่วมกัน
  • --mm:none– ไม่มีกลยุทธ์การจัดการหน่วยความจำหรือตัวเก็บขยะ (garbage collector ) หน่วยความจำที่จัดสรรไว้จะไม่ถูกปล่อยให้ว่างเลย เว้นแต่จะถูกปล่อยให้ว่างด้วยตนเองโดยโค้ดของนักพัฒนา

ตั้งแต่ Nim 2.0 เป็นต้นไป ORC จะเป็น GC เริ่มต้น[ 26 ]

เครื่องมือพัฒนา

มัดรวม

แพ็กเกจการติดตั้ง Nim มาพร้อมกับเครื่องมือมากมาย ได้แก่:

ว่องไว

Nimble เป็นตัวจัดการแพ็กเกจ มาตรฐาน ที่ Nim ใช้ในการบรรจุโมดูล Nim [ 38 ]เดิมทีพัฒนาโดย Dominik Picheta ซึ่งเป็นนักพัฒนาหลักของ Nim ด้วย Nimble ได้รับการรวมเข้าเป็นตัวจัดการแพ็กเกจอย่างเป็นทางการของ Nim ตั้งแต่วันที่ 27 ตุลาคม 2015 ซึ่งเป็นเวอร์ชัน v0.12.0 [ 39 ]

แพ็กเกจ Nimble ถูกกำหนดโดย.nimbleไฟล์ ซึ่งมีข้อมูลเกี่ยวกับเวอร์ชันแพ็กเกจ ผู้เขียน ใบอนุญาต คำอธิบาย การพึ่งพา และอื่นๆ[ 21 ] : 132 ไฟล์เหล่านี้รองรับไวยากรณ์ Nim บางส่วนที่เรียกว่า NimScript โดยมีข้อจำกัดหลักคือการเข้าถึง FFI สคริปต์เหล่านี้อนุญาตให้เปลี่ยนแปลงขั้นตอนการทดสอบ หรือเขียนงานที่กำหนดเองได้

รายการแพ็กเกจจะถูกจัดเก็บไว้ในไฟล์ JavaScript Object Notation ( JSON ) ซึ่งสามารถเข้าถึงได้โดยอิสระในที่เก็บ nim-lang/packages บน GitHub ไฟล์ JSON นี้จะช่วยให้ Nimble สามารถจับคู่ชื่อแพ็กเกจกับ URL ของที่เก็บ Git หรือ Mercurial ได้

Nimble มาพร้อมกับคอมไพเลอร์ Nim ดังนั้นจึงสามารถทดสอบสภาพแวดล้อมของ Nimble ได้โดยการรันnimble -vคำสั่งนี้ คำสั่งนี้จะแสดงหมายเลขเวอร์ชัน วันที่และเวลาในการคอมไพล์ และ แฮช Gitของ nimble Nimble ใช้แพ็กเกจ Git ซึ่งต้องมีอยู่เพื่อให้ Nimble ทำงานได้อย่างถูกต้อง บรรทัดคำสั่งของ Nimble ใช้เป็นอินเทอร์เฟซสำหรับการติดตั้ง การลบ (ถอนการติดตั้ง) และการอัปเกรด-แก้ไขแพ็กเกจโมดูล[ 21 ] : 130–131

ซี2นิม

c2nim เป็นคอมไพเลอร์แบบซอร์สโค้ดต่อซอร์สโค้ด (ทรานส์คอมไพเลอร์หรือทรานสไพเลอร์) ที่ออกแบบมาเพื่อใช้กับ เฮดเดอร์ C / C++เพื่อช่วยสร้างการผูก Nim ใหม่[ 40 ]ผลลัพธ์คือโค้ด Nim ที่มนุษย์อ่านได้ ซึ่งออกแบบมาเพื่อแก้ไขด้วยตนเองหลังจากกระบวนการแปลเสร็จสิ้น

โคช

koch เป็นสคริปต์การบำรุงรักษาที่ใช้ในการสร้าง Nim และจัดเตรียมเอกสาร HTML [ 41 ]

นิมเกรป

nimgrep เป็นเครื่องมือทั่วไปสำหรับการจัดการข้อความ ใช้ในการค้นหา regex, รูปแบบ peg และเนื้อหาของไดเร็กทอรี และสามารถใช้แทนที่งานต่างๆ ได้ รวมอยู่ด้วยเพื่อช่วยในการค้นหาตัวระบุที่ไม่คำนึงถึงสไตล์ของ Nim [ 42 ]

นิมซักเกสต์

nimsuggest เป็นเครื่องมือที่ช่วยให้โปรแกรมแก้ไขซอร์สโค้ดใดๆ สามารถสอบถาม.nimไฟล์ซอร์สเพื่อรับข้อมูลที่เป็นประโยชน์ เช่น คำจำกัดความของสัญลักษณ์หรือคำแนะนำสำหรับการเติมคำ[ 43 ]

นิมินสต์

niminst เป็นเครื่องมือสำหรับสร้างตัวติดตั้งโปรแกรม Nim [ 44 ] โดยจะสร้างตัวติดตั้ง .msi สำหรับ Windows ผ่าน Inno Setup และสคริปต์การติดตั้งและถอนการติดตั้งสำหรับLinux , macOSและBerkeley Software Distribution (BSD)

นิมเพรตตี้

nimpretty เป็นโปรแกรมจัดรูปแบบโค้ดต้นฉบับให้สวยงาม ใช้สำหรับจัดรูปแบบโค้ดตามคู่มือสไตล์ Nim อย่างเป็นทางการ[ 45 ]

พินัยกรรม

Testamentเป็นเครื่องมือรันการทดสอบหน่วยอัตโนมัติขั้นสูงสำหรับทดสอบด้วยภาษา Nim ใช้ในการพัฒนาโปรแกรมด้วยภาษา Nim โดยมีคุณสมบัติในการทดสอบแบบแยกกระบวนการ สร้างสถิติเกี่ยวกับกรณีทดสอบ รองรับเป้าหมายหลายรายการและการจำลอง Dry-Run มีระบบบันทึกข้อมูล สามารถสร้างรายงาน HTML สามารถข้ามการทดสอบจากไฟล์ และอื่นๆ อีกมากมาย

เครื่องมืออื่นๆ ที่น่าสนใจ

เครื่องมือสำคัญบางอย่างที่ไม่ได้รวมอยู่ในชุดการแจกจ่าย Nim ได้แก่:

เลือกฉัน

choosenimได้รับการพัฒนาโดย Dominik Picheta ผู้สร้างตัวจัดการแพ็กเกจ Nimble เป็นเครื่องมือที่ช่วยให้สามารถติดตั้งและใช้งานคอมไพเลอร์ Nim หลายเวอร์ชันได้ โดยจะดาวน์โหลดคอมไพเลอร์ Nim เวอร์ชันเสถียรหรือเวอร์ชันพัฒนาใดๆ จากบรรทัดคำสั่ง ทำให้สามารถสลับไปมาระหว่างเวอร์ชันต่างๆ ได้อย่างง่ายดาย[ 46 ]

นิมปี้

nimpyเป็นไลบรารีที่ช่วยให้สามารถผสานรวม Python เข้ากับโปรแกรม Nim ได้อย่างสะดวก[ 47 ]

พิกซี่

Pixieเป็นไลบรารีกราฟิก 2 มิติที่มีฟีเจอร์มากมาย คล้ายกับCairoหรือSkiaมันใช้ การเร่งความเร็ว SIMDเพื่อเพิ่มความเร็วในการจัดการภาพอย่างมาก รองรับรูปแบบภาพหลายรูปแบบ การผสมผสาน การมาสก์ การเบลอ และสามารถใช้ร่วมกับ ไลบรารี Boxyเพื่อทำการเรนเดอร์แบบเร่งความเร็วด้วยฮาร์ดแวร์ได้

นิมเทอรอป

nimteropเป็นเครื่องมือที่มุ่งเน้นการสร้างตัวห่อ C/C++ โดยอัตโนมัติซึ่งจำเป็นสำหรับอินเทอร์เฟซฟังก์ชันภายนอกของ Nim [ 48 ]

ห้องสมุด

ห้องสมุดบริสุทธิ์/ไม่บริสุทธิ์

ไลบรารีบริสุทธิ์ คือโมดูลที่เขียนด้วยภาษา Nim เท่านั้น โดยไม่มีส่วนเชื่อมต่อเพื่อเข้าถึงไลบรารีที่เขียนด้วยภาษาโปรแกรมอื่นๆ

ไลบรารีที่ไม่บริสุทธิ์ คือโมดูลของโค้ด Nim ที่ขึ้นอยู่กับไลบรารีภายนอกซึ่งเขียนด้วยภาษาโปรแกรมอื่น เช่น ภาษา C

ไลบรารีมาตรฐาน

ไลบรารีมาตรฐานของ Nim ประกอบด้วยโมดูลสำหรับงานพื้นฐานทั้งหมด รวมถึง: [ 49 ]

  • ระบบและโมดูลหลัก
  • คอลเลกชันและอัลกอริธึม
  • การจัดการสตริง
  • การจัดการเวลา
  • บริการระบบปฏิบัติการทั่วไป
  • ห้องสมุดคณิตศาสตร์
  • โปรโตคอลอินเทอร์เน็ตและการสนับสนุน
  • การร้อยด้าย
  • ตัวแยกวิเคราะห์
  • โดคูทิลส์
  • การประมวลผล XML
  • เครื่องมือสร้างโค้ด XML และ HTML
  • การแฮช
  • รองรับฐานข้อมูล (PostgreSQL, MySQL และ SQLite)
  • ตัวห่อหุ้ม (Win32 API, POSIX)

การใช้ไลบรารีอื่นๆ

โปรแกรม Nim สามารถใช้ไลบรารีใดก็ได้ที่สามารถใช้ในโปรแกรม C , C++ หรือ JavaScript ได้ มี การเชื่อมต่อภาษาสำหรับไลบรารีจำนวนมาก รวมถึงGTK [ 50 ] [ 51 ] Qt QML [ 52 ] wxWidgets [ 53 ] SDL 2 [ 54 ] [ 55 ] Raylib [ 56 ] Godot [ 57 ] UE5 [ 58 ] Cairo [ 59 ] OpenGL [ 60 ] Vulkan [ 61 ] Windows API ( WinAPI ) [ 62 ] zlib libzip OpenSSL และcURL [ 63 ] Nim ทำงานร่วมกับฐานข้อมูลPostgreSQL MySQLและSQLite

มีเครื่องมือโอเพนซอร์สอยู่หลายระดับการสนับสนุน ซึ่งสามารถใช้เชื่อมต่อ Nim กับภาษาLua [ 64 ] Julia [ 65 ] Rust [ 66 ] C # [ 67 ]และPython [ 68 ]หรือแปลงNim เป็นTypeScript [ 69 ]

ตัวอย่าง

สวัสดีโลก

โปรแกรม"Hello, World!"ในภาษานิม:

echo ( "Hello, World!" ) # สามารถเรียกใช้โปรซีเดอร์ได้โดยไม่ต้องมีวงเล็บecho "Hello, World!"

อีกรูปแบบหนึ่งของการแสดงข้อความ "Hello World" สามารถทำได้โดยการเรียกใช้writeฟังก์ชันด้วยstdoutสตรีม:

stdout.write ( "Hello, World! \n " ) write ( stdout , " Hello, World! \ n " )

ฟิโบนาชชี

ตัวอย่างการใช้งานฟังก์ชันฟิโบนาชี่ หลายรูปแบบ โดยแสดงให้เห็นถึงการส่งคืนค่าโดยปริยาย พารามิเตอร์เริ่มต้น ตัววนซ้ำ การเรียกซ้ำ และลูป while:

proc fib ( n : Natural ): Natural = if n < 2 : return n else : return fib ( n - 1 ) + fib ( n - 2 ) func fib2 ( n : int , a = 0 , b = 1 ): int = if n == 0 : a else : fib2 ( n - 1 , b , a + b ) iterator fib3 : int = var a = 0 var b = 1 while true : yield a swap a , b b += a

แฟกทอเรียล

โปรแกรมคำนวณแฟกทอเรียลของจำนวนเต็มบวกโดยใช้วิธีการวนซ้ำ โดยแสดงการจัดการข้อผิดพลาดด้วย try/catch และลูป for:

import std / strutilsvar n = 0 try : stdout . write "ป้อนจำนวนเต็มบวก: " n = stdin . readline . parseInt except ValueError : raise newException ( ValueError , "คุณต้องป้อนจำนวนบวก" )var fact = 1 for i in 2 .. n : fact = fact * iเอคโค แฟคต์

โดยใช้โมดูล math จากไลบรารีมาตรฐานของ Nim:

import std / math echo fac ( x )

การกลับสตริง

ตัวอย่างง่ายๆ ที่แสดงให้เห็นถึงตัวแปรผลลัพธ์โดยปริยายและการใช้ตัววนซ้ำ

proc reverse ( s : string ): string = for i in countdown ( s . high , 0 ): result . add s [ i ]let str1 = "กลับด้านข้อความนี้!" echo "ผลลัพธ์ที่กลับด้าน: " , reverse ( str1 )

หนึ่งในคุณสมบัติที่แปลกใหม่ของ Nim คือตัวแปรโดยresultปริยาย ทุกขั้นตอนใน Nim ที่มีประเภทการคืนค่าที่ไม่ใช่ void จะมีตัวแปรผลลัพธ์โดยปริยายซึ่งแสดงถึงค่าที่จะส่งคืน ในลูป for เราจะเห็นการเรียกใช้ซึ่งcountdownเป็นตัววนซ้ำ หากละเว้นตัววนซ้ำ คอมไพเลอร์จะพยายามใช้itemsตัววนซ้ำหากมีการกำหนดไว้สำหรับประเภทที่ระบุ

ส่วนติดต่อผู้ใช้แบบกราฟิก

การใช้งานGTK 3ร่วมกับการตรวจสอบโครงสร้างของ GObject ผ่าน โมดูล gintro :

import gintro /[ gtk , glib , gobject , gio ]proc appActivate ( app : Application ) = let window = newApplicationWindow ( app ) window . title = "แอปพลิเคชัน GTK3 พร้อมการตรวจสอบ gobject" window . defaultSize = ( 400 , 400 ) showAll ( window )proc main = let app = newApplication ( "org.gtk.example" ) connect ( app , "activate" , appActivate ) discard run ( app )หลัก()

โค้ดนี้ต้องการโมดูล gintro ในการทำงาน ซึ่งไม่ได้เป็นส่วนหนึ่งของไลบรารีมาตรฐาน ในการติดตั้งโมดูล gintro และโมดูลอื่นๆ อีกมากมาย คุณสามารถใช้เครื่องมือ nimble ซึ่งเป็นส่วนหนึ่งของ Nim ได้ ในการติดตั้งโมดูล gintro ด้วย nimble ให้ทำดังนี้:

ติดตั้ง gintro อย่างคล่องแคล่ว 

รูปแบบการเขียนโปรแกรม

การเขียนโปรแกรมเชิงฟังก์ชัน

การเขียนโปรแกรมเชิงฟังก์ชันได้รับการสนับสนุนใน Nim ผ่านฟังก์ชันระดับเฟิร์สคลาสและโค้ดที่ไม่มีผลข้างเคียงผ่านnoSideEffectpragma หรือfuncคีย์เวิร์ด[ 70 ] Nim จะทำการ วิเคราะห์ ผลข้างเคียงและแจ้งข้อผิดพลาดในการคอมไพล์สำหรับโค้ดที่ไม่ปฏิบัติตามข้อตกลงในการไม่ก่อให้เกิดผลข้างเคียงเมื่อคอมไพล์ด้วยคุณสมบัติทดลองstrictFuncsซึ่งวางแผนไว้ว่าจะกลายเป็นค่าเริ่มต้นในเวอร์ชันต่อๆ ไป[ 71 ]

แตกต่างจาก ภาษา การเขียนโปรแกรมเชิงฟังก์ชัน โดยสมบูรณ์ Nim เป็น ภาษาการเขียนโปรแกรม แบบหลายกระบวนทัศน์ดังนั้น ข้อจำกัด ของการเขียนโปรแกรมเชิงฟังก์ชันจึงเป็นการเลือกใช้งานตามแต่ละฟังก์ชัน

ฟังก์ชันชั้นหนึ่ง

Nim รองรับฟังก์ชันระดับเฟิร์สคลาสโดยอนุญาตให้จัดเก็บฟังก์ชันไว้ในตัวแปรหรือส่งผ่านแบบไม่ระบุชื่อเป็นพารามิเตอร์เพื่อเรียกใช้โดยฟังก์ชันอื่น[ 72 ] โมดูล นี้std/sugarให้ไวยากรณ์ที่ง่ายขึ้นสำหรับฟังก์ชันที่ไม่ระบุชื่อในการประกาศประเภทและการสร้างอินสแตนซ์

import std /[ sequtils , sugar ]let powersOfTwo = @[ 1 , 2 , 4 , 8 , 16 , 32 , 64 , 128 , 256 ]proc filter [ T ] ( s : openArray [ T ] , pred : T -> bool ): seq [ T ] = result = newSeq [ T ] () for i in 0 .. < s . len : if pred ( s [ i ] ): result . add ( s [ i ] )echo powersOfTwo.filter ( proc ( x : int ): bool = x > 32 ) # รูปแบบการเขียนโค้ดที่ช่วยให้ เขียนได้ ง่ายขึ้น โดยมีให้ใน รูปแบบมาโครจาก std/sugar echo powersOfTwo.filter ( x = > x > 32 )proc greaterThan32 ( x : int ): bool = x > 32 echo powersOfTwo . filter ( greaterThan32 )

ผลข้างเคียง

ผลข้างเคียงของฟังก์ชันที่ระบุด้วยnoSideEffectpragma จะถูกตรวจสอบ และคอมไพเลอร์จะปฏิเสธการคอมไพล์ฟังก์ชันที่ไม่ตรงตามเงื่อนไขเหล่านั้น ผลข้างเคียงใน Nim ได้แก่ การเปลี่ยนแปลงค่า การเข้าถึงหรือแก้ไขสถานะทั่วโลก โค้ดแบบอะซิงโครนัส โค้ดแบบมัลติเธรด และ IO การเปลี่ยนแปลงค่าพารามิเตอร์อาจเกิดขึ้นกับฟังก์ชันที่รับพารามิเตอร์ ประเภท varหรือrefซึ่งคาดว่าจะไม่สามารถคอมไพล์ได้strictFuncsในอนาคตด้วยฟังก์ชันทดลองในปัจจุบัน[ 73 ] คำหลัก นี้funcแนะนำทางลัดสำหรับnoSideEffectpragma [ 74 ]

funcbinarySearch[T](a:openArray[T];elem:T):int # ย่อมาจาก... procbinarySearch[T](a:openArray[T];elem:T):int{.noSideEffect.} {.experimental: "strictFuncs".} typeNode=refobjectle,ri:Nodedata:stringfunclen(n:Node):int= # ถูกต้อง: len ไม่มีผลข้างเคียง varit=nwhileit!=nil:incresultit=it.rifuncmut(n:Node)=letm=n# is the statement that connected the mutation to the parameterm.data="yeah"# the mutation is here# Error: 'mut' can have side effects# an object reachable from 'n' is potentially mutated

การประกอบฟังก์ชัน

ไวยากรณ์การเรียกฟังก์ชันแบบเดียวกันช่วยให้สามารถเชื่อมโยงฟังก์ชันต่างๆ เข้าด้วยกันได้ซึ่งอาจแสดงให้เห็นได้ดีที่สุดด้วยstd/sequtilsไลบรารี[ 75 ]

import std /[ sequtils , sugar ]let numbers = @[ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 7 , 6 , 5 , 4 , 3 , 2 , 1 ] # a และ b เป็นตัวระบุพิเศษในมาโคร foldr echo numbers . filter ( x => x > 3 ). deduplicate . foldr ( a + b ) # 30

ประเภทข้อมูลเชิงพีชคณิตและการจับคู่รูปแบบ

Nim รองรับประเภทผลิตภัณฑ์ผ่านทางobjectประเภท และรองรับประเภทผลรวมผ่านทางตัวแปรออบเจ็กต์ : การแสดงผลดิบของยูเนียนที่มีแท็กโดยมีแท็กประเภทที่แจงนับซึ่งต้องจับคู่ได้อย่างปลอดภัยก่อนจึงจะสามารถเข้าถึงฟิลด์ของตัวแปรได้[ 76 ]ประเภทเหล่านี้สามารถประกอบกันได้ทางพีชคณิตการจับคู่รูปแบบโครงสร้างมีให้ใช้งาน แต่ถูกจำกัดไว้ในมาโครในไลบรารีของบุคคลที่สามต่างๆ[ 77 ]

นำเข้าตารางมาตรฐานtype Value = uint64 Ident = string ExprKind = enum Literal , Variable , Abstraction , Application Expr = ref object case kind : ExprKind of Literal : litIdent : Value of Variable : varIdent : Ident of Abstraction : paramAbs : Ident funcAbs : Expr of Application : funcApp , argApp : Exprfunc eval ( expr : Expr , context : var Table [ Ident , Value ] ): Value = case expr . kind of Literal : return expr . litIdent of Variable : return context [ expr . varIdent ] of Application : case expr . funcApp . kind of Abstraction : context [ expr . funcApp . paramAbs ] = expr . argApp . eval ( context ) return expr . funcAbs . eval ( context ) else : raise newException ( ValueError , "Invalid expression!" ) else : raise newException ( ValueError , "Invalid expression!" )

การเขียนโปรแกรมเชิงวัตถุ

แม้ว่า Nim จะเป็นภาษาเชิงคำสั่งและเชิงฟังก์ชันเป็นหลัก แต่ก็รองรับคุณสมบัติต่างๆ ที่ช่วยให้สามารถใช้แนวคิดเชิงวัตถุได้[ 78 ] [ 79 ]

การกำหนดชนิดย่อยและการสืบทอด

Nim รองรับการสืบทอดแบบจำกัดโดยใช้ref objectsคีย์เวิร์ด[of 79 ]เพื่อเปิดใช้งานการสืบทอด วัตถุเริ่มต้น ("root") ใดๆ จะต้องสืบทอดมาจาก การ สืบทอดมีประโยชน์จำกัดภายในโค้ด Nim ที่เป็นสำนวน: ยกเว้นข้อยกเว้นที่สำคัญ[ 80 ]RootObj

ประเภทAnimal = วัตถุอ้างอิงของRootObj ชื่อ: สตริงอายุ: จำนวนเต็มประเภทDog = วัตถุอ้างอิงของAnimal ประเภทCat = วัตถุอ้างอิงของAnimalvar animals : seq [ Animal ] = @[] animals . add ( Dog ( name : "Sparky" , age : 10 )) animals . add ( Cat ( name : "Mitten" , age : 10 ))สำหรับสัตว์: ยืนยันa ของสัตว์

ความสัมพันธ์ของประเภทย่อยยังสามารถสอบถามได้ด้วยofคำหลัก[ 79 ]

การเรียกเมธอดและการห่อหุ้มข้อมูล

ไวยากรณ์การเรียกฟังก์ชันที่เป็นมาตรฐานของ Nim ช่วยให้สามารถเรียกฟังก์ชันทั่วไปได้ด้วยไวยากรณ์ที่คล้ายกับการเรียกเมธอดในภาษาโปรแกรมอื่นๆ ซึ่งใช้งานได้กับ "getter" และ Nim ยังมีไวยากรณ์สำหรับการสร้าง "setter" ด้วยเช่นกัน วัตถุสามารถเปิดเผยต่อสาธารณะได้ในแต่ละฟิลด์ ซึ่งช่วยให้เกิดการห่อหุ้มข้อมูล (encapsulation)

type Socket * = ref object host : int # ส่วนตัว ไม่มีเครื่องหมายส่งออก# ฟังก์ชันสำหรับดึงที่อยู่โฮสต์proc host * ( s : Socket ): int = s . host# ตัวกำหนดค่าที่อยู่โฮสต์proc `host=` * ( s : var Socket , value : int ) = s . host = valuevar s : Socket new s assert s . host == 0 # เหมือนกับ host(s), s.host() s . host = 34 # เหมือนกับ `host=`(s, 34)

การจัดส่งแบบไดนามิก

การเรียกใช้แบบคงที่เป็นที่นิยมมากกว่า มีประสิทธิภาพมากกว่า และเป็นมาตรฐานแม้กระทั่งในรูทีนที่ดูเหมือนเมธอด[ 79 ]อย่างไรก็ตาม หากต้องการเรียกใช้แบบไดนามิก Nim ก็มีmethodคีย์เวิร์ดสำหรับเปิดใช้งานการเรียกใช้แบบไดนามิกบนประเภทอ้างอิง

import std / strformatประเภทPerson = วัตถุอ้างอิงของRootObj ชื่อ: สตริงStudent = วัตถุอ้างอิงของPerson Teacher = วัตถุอ้างอิงของPersonmethod introduce ( a : Person ) = raise newException ( CatchableError , "Method without implementation override" )method introduce ( a : Student ) = echo & "ฉันเป็นนักเรียนชื่อ {a.name}!"method introduce ( a : Teacher ) = echo & "ฉันเป็นครูชื่อ {a.name}!" let people : seq [ Person ] = @[ Teacher ( name : "Alice" ), Student ( name : "Bob" ) ] for person in people : person . introduce ()

เมตาโปรแกรมมิ่ง

แม่แบบ

Nim รองรับการแทนที่แบบง่ายบนโครงสร้างต้นไม้ไวยากรณ์นามธรรมผ่านทางเทมเพลตของมัน

template genType ( name , fieldname : untyped , fieldtype : typedesc ) = type name = object fieldname : fieldtypegenType ( Test , foo , int )var x = Test ( foo : 4566 ) echo ( x . foo ) # 4566

ฟังก์ชันนี้genTypeจะถูกเรียกใช้ในขั้นตอนการคอมไพล์ และTestจะมีการสร้างประเภทข้อมูลขึ้นมา

ยาสามัญ

ภาษาโปรแกรม Nim รองรับการเขียนโปรแกรมแบบเจเนริกทั้งแบบมีข้อจำกัดและไม่มีข้อจำกัด เจเนริกสามารถใช้ในขั้นตอนการทำงาน เทมเพลต และมาโครได้ ตัวTระบุเจเนริกแบบไม่มีข้อจำกัด (ในตัวอย่างนี้) จะถูกกำหนดไว้หลังชื่อของรูทีนในวงเล็บเหลี่ยม ส่วนเจเนริกแบบมีข้อจำกัดสามารถวางไว้บนตัวระบุเจเนริก หรือบนพารามิเตอร์โดยตรงก็ได้

proc addThese [ T ] ( a , b : T ): T = a + b echo addThese ( 1 , 2 ) # 3 (ชนิด int) echo addThese ( uint8 1 , uint8 2 ) # 3 (ชนิด uint8)# เราไม่ต้องการเสี่ยงกับการลบจำนวนที่ไม่มีเครื่องหมาย! proc subtractThese [ T : SomeSignedInt | float ] ( a , b : T ): T = a - b echo subtractThese ( 1 , 2 ) # -1 (ของชนิด int)import std / sequtils# เจเนริกแบบจำกัดยังสามารถกำหนดโดยตรงให้กับพารามิเตอร์ได้ด้วยproc compareThese [ T ] ( a , b : string | seq [ T ] ): bool = for ( i , j ) in zip ( a , b ): if i != j : return false

เราสามารถชี้แจงเพิ่มเติมเกี่ยวกับประเภทที่ขั้นตอนจะยอมรับได้โดยการระบุคลาสประเภท (ในตัวอย่างข้างต้นSomeSignedInt) [ 81 ]

มาโคร

มาโครสามารถเขียนโค้ดบางส่วนใหม่ได้ในระหว่างการคอมไพล์ มาโครของ Nim มีประสิทธิภาพและสามารถดำเนินการกับโครงสร้างต้นไม้ไวยากรณ์นามธรรมก่อนหรือหลังการตรวจสอบความหมายได้[ 82 ]

นี่คือตัวอย่างง่ายๆ ที่สร้างมาโครเพื่อเรียกใช้โค้ดสองครั้ง:

นำเข้าstd / macrosมาโครสองครั้ง( อาร์กิวเมนต์: ไม่ระบุประเภท): ไม่ระบุประเภท= ผลลัพธ์= คำพูดทำ: ` อาร์กิวเมนต์` ` อาร์กิวเมนต์`ส่งเสียง"Hello world!" สองครั้ง

มาโครtwiceในตัวอย่างนี้รับคำสั่ง echo ในรูปแบบของโครงสร้างต้นไม้ไวยากรณ์นามธรรม (abstract syntax tree) เป็นอินพุต ในตัวอย่างนี้ เราตัดสินใจที่จะส่งคืนโครงสร้างต้นไม้ไวยากรณ์นี้โดยไม่มีการดัดแปลงใดๆ แต่เราทำเช่นนั้นสองครั้ง จึงเป็นที่มาของชื่อมาโคร ผลลัพธ์คือ โค้ดจะถูกเขียนใหม่โดยมาโครให้มีลักษณะดังโค้ดต่อไปนี้ในระหว่างการคอมไพล์:

echo "Hello world!" echo "Hello world!"

อินเทอร์เฟซฟังก์ชันภายนอก (FFI)

FFI ของ Nim ใช้สำหรับเรียกฟังก์ชันที่เขียนด้วยภาษาโปรแกรมอื่น ๆ ที่สามารถคอมไพล์ได้ ซึ่งหมายความว่าไลบรารีที่เขียนด้วยภาษา C, C++, Objective-C และ JavaScript สามารถนำมาใช้ในซอร์สโค้ดของ Nim ได้ ควรทราบว่า JavaScript และไลบรารี C, C++ หรือ Objective-C ไม่สามารถรวมกันในโปรแกรมเดียวกันได้ เนื่องจากไม่เข้ากันกับ JavaScript เท่ากับที่เข้ากันได้ดีกับภาษาอื่น ๆ ทั้ง C++ และ Objective-C นั้นมีพื้นฐานมาจากและเข้ากันได้กับ C แต่ JavaScript นั้นไม่เข้ากัน เนื่องจากเป็นภาษาแบบไดนามิกฝั่งไคลเอ็นต์ที่ใช้บนเว็บ[ 21 ] : 226

โปรแกรมต่อไปนี้แสดงให้เห็นถึงความง่ายดายในการใช้โค้ด C ภายนอกโดยตรงใน Nim

proc printf ( formatstr : cstring ) {.header : "<stdio.h>", varargs.}printf ( "%s %d \n " , "foo" , 5 )

ในโค้ดนี้printfฟังก์ชันจะถูกนำเข้าในภาษานิม แล้วจึงนำไปใช้งาน

ตัวอย่างพื้นฐานการใช้ 'console.log' โดยตรงสำหรับ เป้าหมายการคอมไพล์ JavaScript :

proc log ( args : any ) {.importjs : "console.log(@)", varargs.} log ( 42 , "z" , true , 3.14 )

โค้ด JavaScript ที่สร้างโดยคอมไพเลอร์ Nim สามารถเรียกใช้งานได้ด้วยNode.jsหรือเว็บเบราว์เซอร์

ความขนาน

ในการเปิดใช้งานการทำงานแบบมัลติเธรดใน Nim โปรแกรมจะต้องถูกคอมไพล์โดยใช้--threads:onพารามิเตอร์บรรทัดคำสั่ง แต่ละเธรดจะมีฮีปที่จัดการโดยระบบจัดการขยะแยกต่างหาก และการแชร์หน่วยความจำจะถูกจำกัด ซึ่งช่วยเพิ่มประสิทธิภาพและป้องกันสภาวะการแข่งขันของเธรด

นำเข้าstd / locksvar thr : array [ 0 .. 4 , Thread [ tuple [ a , b : int ]]] L : Lockproc threadFunc ( interval : tuple [ a , b : int ] ) {.thread.} = for i in interval . a .. interval . b : acquire ( L ) # ล็อก stdout echo i release ( L )initLock ( L )สำหรับi ตั้งแต่0 ถึงสูง( thr ): สร้างเธรด( thr [ i ] , threadFunc , ( i * 10 , i * 10 + 5 )) เข้าร่วมเธรด( thr )

นอกจากนี้ Nim ยังมีchannelsโมดูลที่ช่วยให้การส่งข้อมูลระหว่างเธรดทำได้ง่ายขึ้น

import std / osประเภทCalculationTask = object id * : int data * : intCalculationResult = object id * : int result * : intvar task_queue : Channel [ CalculationTask ] var result_queue : Channel [ CalculationResult ]proc workerFunc () {.thread.} = result_queue . open ()ในขณะที่เงื่อนไขเป็นจริง: var task = task_queue.recv ( ) result_queue.send ( CalculationResult ( id : task.id , result : task.data * 2 ) )var workerThread : Thread [ void ] createThread ( workerThread , workerFunc )task_queue.open ( ) task_queue.send ( CalculationTask ( id : 1 , data : 13 ) ) task_queue.send ( CalculationTask ( id : 2 , data : 37 ) )ในขณะที่เงื่อนไขเป็นจริงให้แสดงข้อความ"ได้รับผลลัพธ์: " , repr ( result_queue . recv ())

ความพร้อมกัน

การรับส่งข้อมูลแบบอะซิงโครนัสได้รับการสนับสนุนผ่านasyncdispatchโมดูลในไลบรารีมาตรฐานหรือchronosไลบรารี ภายนอก [ 83 ]ไลบรารีทั้งสองเพิ่ม ไวยากรณ์ async/awaitผ่านระบบมาโคร โดยไม่จำเป็นต้องมีการสนับสนุนภาษาพิเศษ ตัวอย่างของ เซิร์ฟเวอร์ HTTP แบบอะซิงโครนัส :

import std /[ asynchttpserver , asyncdispatch ] # สามารถใช้ chronos แทน asyncdispatch ได้เช่นกัน# โดยไม่ต้องเปลี่ยนแปลงอะไรเพิ่มเติมvar server = newAsyncHttpServer ( ) proc cb ( req : Request ) {.async.} = await req.respond ( Http200 , " Hello World" )waitFor server.serve ( Port ( 8080 ) , cb )

ชุมชน

ออนไลน์

Nim มีชุมชนที่ใช้งานอยู่บนฟอรัมอย่างเป็นทางการที่โฮสต์และพัฒนาเอง[ 84 ]นอกจากนี้ โครงการยังใช้ Git repository, bug tracker, RFC tracker และ wiki ที่โฮสต์โดยGitHubซึ่งชุมชนมีส่วนร่วมกับภาษา[ 85 ]นอกจากนี้ยังมีห้องแชทออนไลน์อย่างเป็นทางการที่เชื่อมโยงระหว่าง IRC , Matrix , Discord , GitterและTelegram [ 86 ]

อนุสัญญา

การประชุม Nim ครั้งแรก หรือ NimConf จัดขึ้นเมื่อวันที่ 20 มิถุนายน 2020 โดยจัดขึ้นในรูปแบบดิจิทัลเนื่องจากสถานการณ์ COVID-19พร้อมกับการเปิดรับการบรรยายจากผู้ร่วมให้ข้อมูลในรูปแบบวิดีโอYouTube [ 87 ]การประชุมเริ่มต้นด้วยภาพรวมของภาษาโดยนักพัฒนา Nim Andreas Rumpf และ Dominik Picheta หัวข้อการนำเสนอประกอบด้วยการบรรยายเกี่ยวกับเฟรมเวิร์กเว็บการพัฒนาแอปพลิเคชันบนมือถือ อุปกรณ์ Internet of Things ( IoT) และการพัฒนาเกมรวมถึงการบรรยายเกี่ยวกับการเขียน Nim สำหรับGame Boy Advance [ 88 ] NimConf 2020 มีให้รับชมในรูปแบบเพลย์ลิสต์ YouTube [ 89 ] NimConf 2021 จัดขึ้นในปีถัด มาโดยจัดขึ้นในรูปแบบดิจิทัลเช่นกัน และมีการบรรยายเกี่ยวกับการพัฒนาเกม REPLs ระบบปฏิบัติการแบบเรียลไทม์ Nim ในอุตสาหกรรมการแมปอ็อบเจ็กต์เชิงสัมพันธ์ ( ORM ) การทดสอบ แบบฟัซซิ่งการออกแบบภาษาและไลบรารีกราฟิก[ 90 ]

นอกจากงานประชุมอย่างเป็นทางการแล้ว Nim ยังได้รับการนำเสนอในงานประชุมอื่นๆ อีกมากมาย มีการนำเสนอเกี่ยวกับ Nim ในงานO'Reilly Open Source Convention (OSCON) ในปี 2015 [ 91 ] [ 92 ] [ 93 ] มี ผู้บรรยาย 4 คนเป็นตัวแทนของ Nim ในงาน FOSDEM 2020 รวมถึงผู้สร้างภาษา Andreas Rumpf [ 94 ]ในงาน FOSDEM 2022 Nim ได้จัดห้องสำหรับนักพัฒนาของตนเองแบบเสมือนจริงเนื่องจาก การระบาด ของCOVID-19 [ 95 ]มีการบรรยายเกี่ยวกับการทำงานพร้อมกันการเขียนโปรแกรมฝังตัวการเขียนโปรแกรมสำหรับGPUระบบเอนทิตี- คอมโพเนนต์ การพัฒนาเกมกลไกกฎ การทำงานร่วมกับ Python และ เมตาโปรแกรมมิ่ง[ 96 ]

ดูเพิ่มเติม

  • เว็บไซต์อย่างเป็นทางการแก้ไขข้อมูลนี้ได้ที่วิกิดาต้า
  • นิมบนGitHub
  • ข้อมูลเกี่ยวกับ NimบนStack Overflow
  • การเขียนโปรแกรมคอมพิวเตอร์ด้วยภาษาโปรแกรม Nim – บทนำอย่างง่าย โดย Stefan Salewski
ดึงข้อมูลมาจาก " https://en.wikipedia.org/w/index.php?title=Nim_(programming_language)&oldid=1359618827 "

สรุปเนื้อหา

ข้อมูลสำคัญจากบทความ

ข้อมูลสำคัญเกี่ยวกับ นิม (ภาษาโปรแกรม)

Nim เป็น ภาษาโปรแกรมระบบ ระดับสูง แบบ คอมไพล์ได้ อเนกประสงค์ รองรับ หลาย พาราดิกม์ กำหนด ประเภทแบบคงที่ [ 9 ] ได้รับการออกแบบและพัฒนาโดยทีมงานที่นำโดย Andreas Rumpf Nim...

คำอธิบาย

Nim เป็นภาษาที่มีการกำหนดประเภทแบบคงที่ [ 12 ] รองรับ คุณสมบัติ เมตาโปรแกรม มิ่งในเวลาคอมไพล์ เช่น มาโครทางไวยากรณ์และ มาโครการเขียนเทอมใหม่ [ 13 ] มาโคร การเขียนเทอมใหม่ช่วยให้ การใช้งาน ไลบรารี ของโครงสร้างข้อมูลทั่วไป เช่น bignums และเมทริกซ์...

ประวัติศาสตร์

Andreas Rumpf เป็นผู้ออกแบบและผู้พัฒนา Nim คนแรก เขาได้รับประกาศนียบัตรด้านวิทยาการคอมพิวเตอร์จาก มหาวิทยาลัยเทคนิคไคเซอร์สเลาเทิร์น ประเทศ เยอรมนี ความสนใจในการวิจัยของเขารวมถึง ระบบเรียลไทม์แบบแข็ง ระบบ ฝังตัว การ สร้างคอมไพเลอร์ และ ปัญญา ประดิษฐ์ [ 20 ]

ไวยากรณ์

ไวยากรณ์ของ Nim คล้ายกับของPython [ 27 ] บล็อก โค้ดและคำสั่งซ้อนกันจะถูกระบุโดยใช้ ช่องว่าง ตาม กฎออฟไซด์ คำหลัก หลาย คำ เหมือนกับคำที่เทียบเท่าใน Python ซึ่งส่วนใหญ่เป็นคำหลักภาษาอังกฤษ ในขณะที่ภาษาโปรแกรมอื่นๆ มักใช้เครื่องหมายวรรคตอน...