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

อ่าน 15 นาที

โอแคมล์

OCaml ( / oʊ ˈ k æ m əl / oh- KAM -əl เดิมชื่อ Objective Caml ) เป็น ภาษาโปรแกรมอเนกประสงค์ ระดับ สูงแบบ หลายพารา ดิกม์ ซึ่งขยาย ภาษา Caml ของ ML ด้วย คุณสมบัติ เชิงวัตถุ OCaml...

โอแคมล์

โอแคมล์
กระบวนทัศน์หลายกระบวนทัศน์ : ฟังก์ชัน , เชิงบังคับ , แบบโมดูลาร์ , [ 1 ]เชิงวัตถุ
ตระกูลML : Caml
ออกแบบโดยซาเวียร์ เลรอย , เฆโรม วูยง, เดเมียน โดลิเจซ , ดิดิเยร์ เรมี, อัสคันเดอร์ ซัวเรซ
นักพัฒนาอินเรีย
ปรากฏครั้งแรก1996 [ 2 ] ( 1996 )
เวอร์ชันเสถียร
5.4.1 [ 3 ] แก้ไขข้อมูลนี้บนวิกิดาต้า / 17 กุมภาพันธ์ 2026 ( 17 กุมภาพันธ์ 2569 )
วินัยในการพิมพ์อนุมานได้ , คงที่ , แข็งแรง , โครงสร้าง
ภาษาการใช้งานโอแคมล์, ซี
แพลตฟอร์มIA-32 , x86-64 , Power , SPARC , ARM 32-64 , RISC-V
โอเอสรองรับหลายแพลตฟอร์ม : Linux , Unix , macOS , Windows
ใบอนุญาตLGPLv2.1
นามสกุลไฟล์.ml, .mli
เว็บไซต์ocaml.org
ได้รับอิทธิพลจาก
C , Caml , Modula-3 , Pascal , Standard ML
ได้รับอิทธิพล
ATS , Rocq (ชื่อเดิม: Coq ), Elm , F# , F* , Haxe , Opa , Rust , [ 4 ] Scala , Gleam
  • โลโก้ WikibooksOCamlที่ Wikibooks

OCaml ( / ˈ k æ m əl / oh- KAM -əlเดิมชื่อObjective Caml ) เป็นภาษาโปรแกรมอเนกประสงค์ระดับสูงแบบหลายพาราดิกม์ ซึ่งขยาย ภาษา CamlของMLด้วย คุณสมบัติ เชิงวัตถุ OCaml ถูกสร้างขึ้นในปี 1996 โดยXavier Leroy , Jérôme Vouillon, [ 5 ] Damien Doligez , Didier Rémy, [ 6 ] Ascánder Suárez และคนอื่นๆ

ชุดเครื่องมือ OCaml ประกอบด้วย ตัวแปลภาษาแบบโต้ตอบระดับบนสุดคอม ไพเลอ ร์ไบต์โค้ด คอมไพเลอร์ เนทีฟโค้ด ที่ ปรับแต่งประสิทธิภาพตัวดีบักเกอร์แบบย้อนกลับได้และตัวจัดการแพ็กเก จ ( OPAM ) พร้อมด้วยระบบสร้างแบบประกอบได้สำหรับ OCaml ( Dune ) OCaml ได้รับการพัฒนาขึ้นครั้งแรกในบริบทของการพิสูจน์ทฤษฎีบทอัตโนมัติและใช้ใน ซอฟต์แวร์ การวิเคราะห์แบบสถิตและวิธีการเชิงรูปธรรมนอกเหนือจากด้านเหล่านี้แล้ว ยังมีการใช้งานในด้านการเขียนโปรแกรมระบบการพัฒนาเว็บและยูทิลิตี้ทางการเงินเฉพาะด้าน รวมถึงโดเมนการใช้งานอื่นๆ อีกมากมาย

เดิมที คำย่อCAMLย่อมาจากCategorical Abstract Machine Languageแต่ OCaml ละเว้นเครื่องจักรนามธรรมนี้[ 7 ] OCaml เป็น โครงการ ซอฟต์แวร์โอเพนซอร์สฟรี ที่บริหาร จัดการ และดูแลรักษาโดยสถาบันวิจัยวิทยาศาสตร์คอมพิวเตอร์และระบบอัตโนมัติแห่งฝรั่งเศส (Inria) ในช่วงต้นทศวรรษ 2000 องค์ประกอบจาก OCaml ได้ถูกนำไปใช้ในหลายภาษา โดยเฉพาะF#และScala

ปรัชญา

ภาษาที่พัฒนามาจาก MLเป็นที่รู้จักกันดีที่สุดในเรื่องระบบประเภทข้อมูล แบบคงที่ และคอมไพเลอร์ที่อนุมานประเภทข้อมูล OCaml รวม การเขียนโปรแกรม เชิงฟังก์ชัน เชิงคำสั่งและเชิงวัตถุเข้าไว้ด้วย กัน ภายใต้ระบบประเภทข้อมูลที่คล้ายกับ ML ดังนั้น โปรแกรมเมอร์จึงไม่จำเป็นต้องคุ้นเคยกับกระบวนทัศน์ ภาษาเชิงฟังก์ชันบริสุทธิ์มากนัก ก็สามารถใช้ OCaml ได้

ด้วยการกำหนดให้โปรแกรมเมอร์ทำงานภายใต้ข้อจำกัดของระบบประเภทคงที่ (static type system ) OCaml จึงช่วยขจัด ปัญหา การทำงาน ที่เกี่ยวข้องกับประเภทข้อมูล ซึ่งมักพบใน ภาษาโปรแกรม แบบไดนามิก (dynamically typed languages) นอกจากนี้ คอมไพเลอร์ที่อนุมานประเภทข้อมูลของ OCaml ยังช่วยลดความจำเป็นในการระบุประเภทข้อมูลด้วยตนเอง ซึ่งเป็นสิ่งที่จำเป็นในภาษาโปรแกรมแบบคงที่ส่วนใหญ่ ตัวอย่างเช่นประเภทข้อมูลของตัวแปรและรูปแบบของฟังก์ชันมักไม่จำเป็นต้องประกาศอย่างชัดเจนเหมือนในภาษาอย่างJavaและC#เพราะสามารถอนุมานได้จากตัวดำเนินการและฟังก์ชันอื่นๆ ที่นำไปใช้กับตัวแปรและค่าอื่นๆ ในโค้ด การใช้งานระบบประเภทข้อมูลของ OCaml อย่างมีประสิทธิภาพอาจต้องอาศัยความเชี่ยวชาญจากโปรแกรมเมอร์ แต่ความพยายามนี้จะได้รับผลตอบแทนเป็นซอฟต์แวร์ที่มีประสิทธิภาพสูงและน่าเชื่อถือ

สิ่งที่โดดเด่นที่สุดจากภาษาโปรแกรมอื่นๆ ที่มีต้นกำเนิดมาจากแวดวงวิชาการอย่าง OCaml คือการเน้นประสิทธิภาพ ระบบการตรวจสอบชนิดข้อมูลแบบคงที่ (static type system) ของ OCaml ป้องกันความไม่ตรงกันของชนิดข้อมูลขณะรันไทม์ จึงช่วยลดความจำเป็นในการตรวจสอบชนิดข้อมูลและความปลอดภัยขณะรันไทม์ ซึ่งเป็นภาระต่อประสิทธิภาพของภาษาโปรแกรมแบบไดนามิก (dynamically typed languages) ในขณะเดียวกันก็ยังคงรับประกันความปลอดภัยขณะรันไทม์ ยกเว้นในกรณีที่ปิดการตรวจสอบขอบเขตของอาร์เรย์ หรือเมื่อใช้คุณสมบัติที่ไม่ปลอดภัยต่อชนิดข้อมูลบางอย่าง เช่น การทำให้เป็นอนุกรม (serialization ) ซึ่งกรณีเหล่านี้เกิดขึ้นได้น้อยมากจนสามารถหลีกเลี่ยงได้ในทางปฏิบัติ

นอกเหนือจากภาระในการตรวจสอบประเภทแล้ว โดยทั่วไปแล้วภาษา โปรแกรมเชิงฟังก์ชันนั้นยากที่จะคอมไพล์ให้เป็นโค้ดภาษาเครื่องที่มีประสิทธิภาพ เนื่องจากปัญหาต่างๆ เช่นปัญหา funargนอกจากวิธีการเพิ่มประสิทธิภาพลูป รีจิสเตอร์ และคำสั่งมาตรฐานแล้วคอมไพเลอร์ที่เพิ่มประสิทธิภาพ ของ OCaml ยังใช้วิธีการวิเคราะห์โปรแกรมแบบคงที่ เพื่อเพิ่มประสิทธิภาพ การแปลงค่าเป็นกล่องและ การจัดสรร Closureซึ่งช่วยเพิ่มประสิทธิภาพของโค้ดที่ได้สูงสุด แม้ว่าจะมีการใช้โครงสร้างโปรแกรมเชิงฟังก์ชันอย่างกว้างขวางก็ตาม

Xavier Leroyได้กล่าวว่า "OCaml ให้ประสิทธิภาพอย่างน้อย 50% ของคอมไพเลอร์ C ที่ดี" [ 8 ]แม้ว่าจะไม่สามารถเปรียบเทียบโดยตรงได้ก็ตาม ฟังก์ชันบางอย่างในไลบรารีมาตรฐานของ OCaml ถูกนำไปใช้ด้วยอัลกอริทึมที่เร็วกว่าฟังก์ชันที่เทียบเท่ากันในไลบรารีมาตรฐานของภาษาอื่นๆ ตัวอย่างเช่น การใช้งาน set union ในไลบรารีมาตรฐานของ OCaml ในทางทฤษฎีจะเร็วกว่าฟังก์ชันที่เทียบเท่ากันในไลบรารีมาตรฐานของภาษาเชิงคำสั่ง (เช่น C++, Java) เนื่องจาก OCaml สามารถใช้ประโยชน์จากความไม่เปลี่ยนแปลงของเซตเพื่อนำส่วนต่างๆ ของเซตอินพุตกลับมาใช้ในเอาต์พุตได้ (ดูโครงสร้างข้อมูลถาวร )

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

ทีมพัฒนา OCaml ได้รับรางวัลในงาน Symposium on Principles of Programming Languages ​​(POPL) ปี 2024

การพัฒนา ML (ภาษาเมตา)

ระหว่างช่วงทศวรรษ 1970 ถึง 1980 โรบิน มิลเนอร์นักวิทยาศาสตร์คอมพิวเตอร์ชาวอังกฤษและผู้ได้รับรางวัลทัวริง ทำงานที่ ห้องปฏิบัติการพื้นฐานวิทยาศาสตร์คอมพิวเตอร์ของมหาวิทยาลัยเอดินบะระ[ 9 ] [ 10 ]มิลเนอร์และคนอื่นๆ กำลังทำงานเกี่ยวกับตัวพิสูจน์ทฤษฎีบทซึ่งในอดีตพัฒนาขึ้นในภาษาต่างๆ เช่นLispมิลเนอร์พบปัญหาซ้ำแล้วซ้ำเล่าว่าตัวพิสูจน์ทฤษฎีบทจะพยายามอ้างว่าการพิสูจน์นั้นถูกต้องโดยการนำสิ่งที่ไม่ใช่การพิสูจน์มารวมกัน[ 10 ]ด้วยเหตุนี้ เขาจึงพัฒนาภาษาเมตาสำหรับตรรกะสำหรับฟังก์ชันที่คำนวณได้ (Logic for Computable Functions ) ซึ่งเป็นภาษาที่จะอนุญาตให้ผู้เขียนสร้างการพิสูจน์ที่ถูกต้องได้ด้วยระบบประเภทโพลีมอร์ฟิกเท่านั้น[ 11 ] ML ถูกเปลี่ยนเป็นคอมไพเลอร์เพื่อลดความซับซ้อนในการใช้ LCF บนเครื่องต่างๆ และในช่วงทศวรรษ 1980 ก็ถูกเปลี่ยนเป็นระบบที่สมบูรณ์ของตัวเอง[ 11 ]ในที่สุด ML ก็เป็นพื้นฐานสำหรับการสร้าง OCaml

ในช่วงต้นทศวรรษ 1980 มีการพัฒนาบางอย่างที่กระตุ้นให้ ทีม Formel ของ INRIAสนใจภาษา ML Luca Cardelliศาสตราจารย์วิจัยที่มหาวิทยาลัยออกซ์ฟอร์ดใช้เครื่องจักรนามธรรมเชิงฟังก์ชัน ของเขา เพื่อพัฒนาการใช้งาน ML ที่เร็วขึ้น และ Robin Milner เสนอคำจำกัดความใหม่ของ ML เพื่อหลีกเลี่ยงความแตกต่างระหว่างการใช้งานต่างๆ ในเวลาเดียวกัน Pierre-Louis Curien นักวิจัยอาวุโสที่มหาวิทยาลัยปารีส ดิดิโรต์ได้พัฒนาแคลคูลัสของตัวรวมเชิงหมวดหมู่และเชื่อมโยงกับแคลคูลัสแลมบ์ดาซึ่งนำไปสู่คำจำกัดความของเครื่องจักรนามธรรมเชิงหมวดหมู่ (CAM) Guy Cousineau นักวิจัยที่มหาวิทยาลัยปารีส ดิดิโรต์ ตระหนักว่าสิ่งนี้สามารถนำไปใช้เป็นวิธีการคอมไพล์สำหรับ ML ได้[ 12 ]

การนำไปใช้ครั้งแรก

Camlได้รับการออกแบบและพัฒนาครั้งแรกโดยทีม Formel ของ INRIA ซึ่งนำโดยGérard Huetการใช้งาน Caml ครั้งแรกเกิดขึ้นในปี 1987 และได้รับการพัฒนาต่อไปจนถึงปี 1992 แม้ว่า Ascánder Suárez จะเป็นผู้นำ แต่Pierre WeisและMichel Maunyก็ยังคงพัฒนาต่อหลังจากที่เขาออกจากทีมไปในปี 1988 [ 12 ]

Guy Cousineau อ้างว่าประสบการณ์ของเขาในการใช้งานภาษาโปรแกรมในตอนแรกนั้นค่อนข้างจำกัด และมีข้อบกพร่องหลายประการที่เขาต้องรับผิดชอบ ถึงกระนั้น เขาก็เชื่อว่า "Ascander, Pierre และ Michel ทำงานได้ดีทีเดียว" [ 12 ]

แคมไลท์

ระหว่างปี 1990 ถึง 1991 Xavier Leroyได้ออกแบบการใช้งาน Caml แบบใหม่โดยอิงจากตัวแปลไบต์โค้ดที่เขียนด้วยภาษาCนอกจากนี้Damien Doligezยังได้เขียนระบบจัดการหน่วยความจำ หรือที่รู้จักกันในชื่อตัวเก็บขยะ แบบลำดับ สำหรับการใช้งานนี้[ 11 ]การใช้งานแบบใหม่นี้ ซึ่งรู้จักกันในชื่อCaml Lightได้เข้ามาแทนที่การใช้งาน Caml แบบเก่าและทำงานบนเครื่องเดสก์ท็อปขนาดเล็ก[ 12 ]ในปีต่อมา ไลบรารีต่างๆ เช่น เครื่องมือจัดการไวยากรณ์ของ Michel Mauny ได้ปรากฏขึ้นและช่วยส่งเสริมการใช้ Caml ในทีมการศึกษาและการวิจัย[ 11 ]

แคมพิเศษไลท์

ในปี พ.ศ. 2538 Xavier Leroy ได้เผยแพร่ Caml Special Light ซึ่งเป็นเวอร์ชันปรับปรุงของ Caml [ 12 ]มีการเพิ่มคอมไพเลอร์โค้ดเนทีฟที่ปรับแต่งประสิทธิภาพ ลงในคอมไพเลอร์ไบต์โค้ด ซึ่งช่วยเพิ่มประสิทธิภาพอย่างมากจนเทียบเท่ากับภาษาหลักๆ เช่น C++ [ 11 ] [ 12 ] นอกจากนี้ Leroy ยังออกแบบระบบโมดูลระดับสูงที่ได้รับแรงบันดาลใจจากระบบโมดูลของ Standard ML ซึ่งมีสิ่งอำนวยความสะดวกที่มีประสิทธิภาพสำหรับการนามธรรมและการกำหนดพารามิเตอร์ และทำให้การสร้างโปรแกรมขนาดใหญ่ทำได้ง่ายขึ้น[ 11 ]

วัตถุประสงค์ของ Caml

Didier Rémy และ Jérôme Vouillon ได้ออกแบบระบบประเภท ที่แสดงออก สำหรับวัตถุและคลาส ซึ่งถูกรวมเข้าไว้ใน Caml Special Light ส่งผลให้เกิดภาษา Objective Caml ขึ้น โดยเปิดตัวครั้งแรกในปี 1996 และเปลี่ยนชื่อเป็น OCaml ในปี 2011 ระบบวัตถุนี้รองรับรูปแบบการเขียนโปรแกรมเชิงวัตถุที่แพร่หลายจำนวนมากได้อย่างปลอดภัยด้วยประเภทข้อมูลแบบคงที่ ในขณะที่รูปแบบการเขียนโปรแกรมเหล่านั้นทำให้เกิดความไม่ถูกต้องหรือต้องมีการตรวจสอบขณะรันไทม์ในภาษาต่างๆ เช่น C++ หรือJavaในปี 2000 Jacques Garrigue ได้ขยาย Objective Caml ด้วยคุณสมบัติใหม่ๆ มากมาย เช่น เมธอดแบบโพลีมอร์ฟิก ตัวแปร และอาร์กิวเมนต์ที่มีป้ายกำกับและตัวเลือก[ 11 ] [ 12 ]

การพัฒนาอย่างต่อเนื่อง

การปรับปรุงภาษาได้รับการเพิ่มเข้ามาทีละน้อยในช่วงสองทศวรรษที่ผ่านมาเพื่อรองรับฐานรหัสเชิงพาณิชย์และวิชาการที่เติบโตขึ้นใน OCaml [ 11 ]การเปิดตัว OCaml 4.0 ในปี 2012 ได้เพิ่มประเภทข้อมูลพีชคณิตทั่วไป (GADTs) และโมดูลระดับเฟิร์สคลาสเพื่อเพิ่มความยืดหยุ่นของภาษา[ 11 ]การเปิดตัว OCaml 5.0.0 ในปี 2022 [ 13 ]เป็นการเขียนรันไทม์ของภาษาใหม่ทั้งหมด โดยลบการล็อก GC ทั่วโลกและเพิ่มตัวจัดการเอฟเฟกต์ผ่านcontinuations ที่คั่นด้วยตัวคั่นการเปลี่ยนแปลงเหล่านี้ทำให้สามารถรองรับการทำงานแบบขนานหน่วยความจำร่วมและการทำงานพร้อมกันแบบไม่มองสีได้ตามลำดับ

การพัฒนา OCaml ยังคงดำเนินต่อไปภายในทีม Cristal ที่ INRIA จนถึงปี 2005 เมื่อทีม Gallium เข้ามารับช่วงต่อ[ 14 ]ต่อมาทีม Gallium ก็ถูกแทนที่ด้วยทีม Cambium ในปี 2019 [ 15 ] [ 16 ]ณ ปี 2023 มีนักพัฒนาหลักของการแจกจ่ายคอมไพเลอร์ 23 คนจากองค์กรต่างๆ[ 17 ]และนักพัฒนา 41 คนสำหรับระบบนิเวศเครื่องมือและบรรจุภัณฑ์ OCaml ที่กว้างขึ้น[ 18 ]ในปี 2023 คอมไพเลอร์ OCaml ได้รับการยอมรับด้วยรางวัลซอฟต์แวร์ภาษาโปรแกรมของ ACM SIGPLAN

คุณสมบัติ

OCaml มีคุณสมบัติเด่นหลายประการ ได้แก่ระบบประเภทคงที่ (static type system) , การอนุมานประเภท (type inference) , โพลีมอร์ฟิซึม แบบพารามิเตอร์ (parametric polymorphism ) , การเรียกซ้ำแบบหาง ( tail recursion ) , การจับคู่รูปแบบ ( pattern matching ), การปิดเชิงศัพท์ชั้นหนึ่ง (first class lexical closures) , ฟังก์ชัน (โมดูลแบบพารามิเตอร์) , การจัดการข้อยกเว้น (exception handling) , การจัดการเอฟเฟกต์ (effect handling ) และ การเก็บขยะอัตโนมัติแบบเพิ่มทีละรุ่น (incremental generational automatic garbage collection )

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

OCaml มีอินเทอร์เฟซฟังก์ชันภายนอกสำหรับการเชื่อมโยงกับฟังก์ชันพื้นฐานของภาษา C รวมถึงการสนับสนุนภาษาสำหรับอาร์เรย์ตัวเลขที่มีประสิทธิภาพในรูปแบบที่เข้ากันได้กับทั้งภาษา C และFortranนอกจากนี้ OCaml ยังสนับสนุนการสร้างไลบรารีของฟังก์ชัน OCaml ที่สามารถเชื่อมโยงกับ โปรแกรม หลักในภาษา C ได้ เพื่อให้สามารถแจกจ่ายไลบรารี OCaml ให้กับโปรแกรมเมอร์ภาษา C ที่ไม่มีความรู้หรือไม่ได้ติดตั้ง OCaml ไว้

แม้ว่า OCaml จะไม่มีระบบมาโครเป็นส่วนหนึ่งที่แยกไม่ออกของภาษา ( เมตาโปรแกรมมิง ) กล่าวคือไม่มีการสนับสนุนการประมวลผล ล่วงหน้าในตัว แต่แพลตฟอร์มOCaml ก็สนับสนุนไลบรารีสำหรับการเขียนตัวประมวลผลล่วงหน้าดังกล่าวอย่างเป็นทางการซึ่งมีอยู่สองประเภท: ประเภทหนึ่งที่ทำงานในระดับซอร์สโค้ด (เช่นเดียวกับในภาษา C) และอีกประเภทหนึ่งที่ทำงานใน ระดับ Abstract Syntax Treeประเภทหลังนี้เรียกว่า PPX ซึ่งเป็นตัวย่อของ Pre-Processor eXtension และเป็นแบบที่แนะนำ

ชุดการแจกจ่าย OCaml ประกอบด้วย:

คอมไพเลอร์โค้ดเนทีฟพร้อมใช้งานสำหรับหลายแพลตฟอร์ม รวมถึงUnix , Microsoft WindowsและApple macOSความสามารถในการพกพาได้นั้นเกิดขึ้นจาก การรองรับ การสร้างโค้ด เนทีฟ สำหรับสถาปัตยกรรมหลักๆ:

  • X86-64 (AMD64), RISC-VและARM64 (ใน OCaml 5.0.0 ขึ้นไป) [ 19 ]
  • IBM Z (ก่อน OCaml 5.0.0 และย้อนกลับไปใน OCaml 5.1.0)
  • Power (ก่อน OCaml 5.0.0 และคาดว่าจะกลับมาปรากฏอีกครั้งใน OCaml 5.2.0)
  • IA-32และARM (ก่อน OCaml 5.0.0)
  • SPARC (ก่อน OCaml 4.06.0)
  • DEC Alpha , HPPA , IA64และMIPS (ก่อน OCaml 4.00.0)

คอมไพ เลอร์ ไบต์โค้ด รองรับการทำงานบนสถาปัตยกรรม 32 บิตหรือ 64 บิตใดๆ ก็ได้ เมื่อไม่สามารถสร้างโค้ดเนทีฟได้ โดยต้องการเพียงคอมไพเลอร์ภาษา C เท่านั้น

โปรแกรมไบต์โค้ด OCaml และโค้ดเนทีฟสามารถเขียนได้ใน รูปแบบ มัลติเธรดโดยมีการสลับบริบทแบบพรีเอ็ม ทีฟ เธรด OCaml ในโดเมนเดียวกัน[ 20 ]จะทำงานโดยการแบ่งเวลาเท่านั้น อย่างไรก็ตาม โปรแกรม OCaml สามารถประกอบด้วยหลายโดเมน

ตัวอย่างโค้ด

ตัวอย่างโค้ด OCaml สามารถศึกษาได้ง่ายที่สุดโดยการป้อนลงในREPLระดับบนสุดนี่คือเซสชัน OCaml แบบโต้ตอบที่พิมพ์ ประเภท ที่อนุมานได้ของนิพจน์ที่ได้หรือที่กำหนดไว้[ 21 ]การเริ่มต้น OCaml ระดับบนสุดทำได้โดยการเรียกใช้โปรแกรม OCaml:

$ ocaml OCaml เวอร์ชัน 5.4.0 พิมพ์ #help;; เพื่อขอความช่วยเหลือ#

จากนั้นสามารถป้อนรหัสได้ที่ช่องป้อนรหัส "#" ตัวอย่างเช่น ในการคำนวณ 1+2*3:

# 1 + 2 * 3 ;; - : int = 7

OCaml อนุมานชนิดของนิพจน์ว่าเป็น "int" ( จำนวนเต็มที่มีความแม่นยำสูง ) และให้ผลลัพธ์เป็น "7"

สวัสดีโลก

โปรแกรมต่อไปนี้ชื่อ "hello.ml":

print_endline "สวัสดีโลก!"

สามารถเรียกใช้งานได้โดยตรง:

$ ocaml hello.ml 

คอมไพล์เป็นไบต์โค้ดที่สามารถเรียกใช้งานได้:

$ ocamlc hello.ml -o hello 

หรือคอมไพล์เป็น ไฟล์ปฏิบัติการ โค้ดเนทีฟ ที่ได้รับการปรับให้เหมาะสม :

$ ocamlopt hello.ml -o hello 

และดำเนินการ:

$ ./hello Hello World! $

อาร์กิวเมนต์แรกของ ocamlc คือ "hello.ml" ซึ่งระบุไฟล์ต้นฉบับที่จะคอมไพล์ และแฟล็ก "-o hello" ระบุไฟล์เอาต์พุต[ 22 ]

ตัวเลือก

ตัวoptionสร้างประเภทใน OCaml คล้ายกับMaybeประเภทในHaskellจะเพิ่มประเภทข้อมูลที่กำหนดเพื่อส่งคืนSomeค่าของประเภทข้อมูลที่กำหนด หรือส่งคืนค่าว่างNone[ 23 ] สิ่งนี้ใช้เพื่อแสดงว่าค่าอาจมีอยู่หรือไม่ก็ได้

# บางส่วน42 ;; - : ตัวเลือกจำนวนเต็ม= บางส่วน42 # ไม่มี;; - : ตัวเลือก' a = ไม่มี

นี่คือตัวอย่างของฟังก์ชันที่ดึงค่าจำนวนเต็มจากตัวเลือก หากมีอยู่ และแปลงเป็นสตริงหรือหากไม่มี ตัวเลือกนั้นจะส่งคืนสตริงว่าง:

let extract o = match o with | Some i -> string_of_int i | None -> "" ;;
# แยก( 42 บางส่วน);; - : สตริง= "42" # แยกไม่มี;; - : สตริง= ""

การหาผลรวมของรายการจำนวนเต็ม

ลิสต์เป็นหนึ่งในชนิดข้อมูลพื้นฐานใน OCaml ตัวอย่างโค้ดต่อไปนี้กำหนดฟังก์ชันเรียกซ้ำsumที่รับอาร์กิวเมนต์หนึ่งตัวคือจำนวนเต็มซึ่งควรจะเป็นลิสต์ของจำนวนเต็ม โปรดสังเกตคำหลัก ` match` recซึ่งบ่งบอกว่าฟังก์ชันนี้เป็นแบบเรียกซ้ำ ฟังก์ชันจะวนซ้ำในลิสต์ของจำนวนเต็มที่กำหนดและให้ผลรวมขององค์ประกอบต่างๆ คำสั่ง `match`มีความคล้ายคลึงกับ คำสั่ง ` switch` หรือ `element` ในภาษาCแต่มีความทั่วไปมากกว่ามาก

let rec sum integers = (* คำหลัก rec หมายถึง 'เรียกซ้ำ' *) match integers with | [] -> 0 (* ส่งคืนค่า 0 ถ้า integers เป็น ลิสต์ว่าง [] *) | first :: rest -> first + sum rest ;; (* เรียกซ้ำถ้า integers เป็น ลิสต์ที่ไม่ว่าง first คือองค์ประกอบแรก ของลิสต์ และ rest คือ ลิสต์ขององค์ประกอบที่เหลือ ซึ่งอาจเป็น [] *)
# ผลรวม[ 1 ; 2 ; 3 ; 4 ; 5 ];; - : int = 15

อีกวิธีหนึ่งคือการใช้ฟังก์ชัน fold มาตรฐาน ที่ใช้งานได้กับลิสต์

let sum integers = List . fold_left ( fun accumulator x -> accumulator + x ) 0 integers ;;
# ผลรวม[ 1 ; 2 ; 3 ; 4 ; 5 ];; - : int = 15

เนื่องจากฟังก์ชันนิรนามเป็นเพียงการประยุกต์ใช้ตัวดำเนินการ + ดังนั้นจึงสามารถย่อให้สั้นลงได้ดังนี้:

let sum integers = List . fold_left (+) 0 integers

นอกจากนี้ เรายังสามารถละเว้นอาร์กิวเมนต์รายการได้โดยใช้การประยุกต์ใช้บางส่วน :

let sum = List . fold_left (+) 0

เรียงลำดับเร็ว

OCaml เหมาะสำหรับการแสดงอัลกอริทึมแบบเรียกซ้ำอย่างกระชับ ตัวอย่างโค้ดต่อไปนี้แสดงการใช้งานอัลกอริทึมที่คล้ายกับquicksortซึ่งเรียงลำดับรายการจากน้อยไปมาก

let rec qsort = function | [] -> [] | pivot :: rest -> let is_less x = x < pivot in let left , right = List . partition is_less rest in qsort left @ [ pivot ] @ qsort right

หรือใช้การประยุกต์ใช้ตัวดำเนินการ >= เพียงบางส่วน

let rec qsort = function | [] -> [] | pivot :: rest -> let is_less = (>=) pivot in let left , right = List . partition is_less rest in qsort left @ [ pivot ] @ qsort right

ปัญหาวันเกิด

โปรแกรมต่อไปนี้คำนวณจำนวนคนน้อยที่สุดในห้องที่มีความน่าจะเป็นที่วันเกิดของแต่ละคนจะไม่ซ้ำกันเลยน้อยกว่า 50% ( ปัญหาเรื่องวันเกิดซึ่งสำหรับ 1 คน ความน่าจะเป็นคือ 365/365 (หรือ 100%) สำหรับ 2 คนคือ 364/365 สำหรับ 3 คนคือ 364/365 × 363/365 เป็นต้น) (คำตอบ = 23)

let year_size = 365 .let rec birthday_paradox prob people = let prob = ( year_size -. float people ) /. year_size *. prob in if prob < 0 . 5 then Printf . printf "answer = %d \n " ( people + 1 ) else birthday_paradox prob ( people + 1 ) ;;birthday_paradox 1 . 0 1

ตัวเลขโบสถ์

โค้ดต่อไปนี้กำหนดการเข้ารหัสแบบ Churchสำหรับจำนวนธรรมชาติโดยมีตัวสืบทอด (succ) และการบวก (add) ตัวเลขแบบ Church nเป็นฟังก์ชันลำดับสูงที่รับฟังก์ชันfและค่าxและใช้ได้fกับ จำนวนครั้ง xที่แน่นอนเท่านั้นnในการแปลงตัวเลขแบบ Church จากค่าฟังก์ชันเป็นสตริง เราจะส่งฟังก์ชันที่เพิ่มสตริงไว้"S"ข้างหน้าอินพุตและสตริงคงที่เข้าไป"0"ตัวอย่างที่ให้มาจะแสดงผลตัวเลขแบบ Church สำหรับเลขห้าเป็น “SSSSS0”

let zero f x = x let succ n f x = f ( n f x ) let one = succ zero let two = succ ( succ zero ) let add n1 n2 f x = n1 f ( n2 f x ) let to_string n = n ( fun k -> "S" ^ k ) "0" let church_5 = to_string ( add ( succ two ) two ) ;; print_endline church_5 ;

ฟังก์ชันแฟกทอเรียลความแม่นยำสูง (ไลบรารี)

OCaml สามารถเข้าถึงไลบรารีต่างๆ ได้โดยตรงจากภาษาโปรแกรมนี้ ตัวอย่างเช่น OCaml มีไลบรารีในตัวสำหรับการคำนวณเลขคณิตความแม่นยำสูงเนื่องจากฟังก์ชันแฟกทอเรียลเติบโตอย่างรวดเร็วมาก จึงทำให้เกินขีดจำกัดความแม่นยำของเครื่อง (โดยทั่วไปคือ 32 หรือ 64 บิต) อย่างรวดเร็ว ดังนั้น แฟกทอเรียลจึงเป็นตัวเลือกที่เหมาะสมสำหรับการคำนวณเลขคณิตความแม่นยำสูง

ใน OCaml โมดูล Num (ปัจจุบันถูกแทนที่ด้วยโมดูล ZArith) ให้การคำนวณเลขคณิตที่มีความแม่นยำสูง และสามารถโหลดเข้าไปในโปรแกรมระดับบนสุดที่กำลังทำงานอยู่ได้โดยใช้คำสั่ง:

# # ใช้"topfind" ;; # # ต้องการ"num" ;; # เปิดNum ;;

ฟังก์ชันแฟกทอเรียลสามารถเขียนได้โดยใช้ตัวดำเนินการตัวเลขความแม่นยำสูง=/ , */และ-/  :

# let rec fact n = if n =/ Int 0 then Int 1 else n */ fact ( n -/ Int 1 );; val fact : Num . num -> Num . num = < fun >

ฟังก์ชันนี้สามารถคำนวณค่าแฟกทอเรียลขนาดใหญ่ได้ เช่น 120!

# string_of_num ( fact ( Int 120 ));; - : string = "6689502913449127057588118054090372586752746333138029810295671352301633 55724496298936687416527198498130815763789321409055253440858940812185989 84811143896500059649605212569600000000000000000000000000000"

สามเหลี่ยม (กราฟิก)

โปรแกรมต่อไปนี้แสดงผลรูปสามเหลี่ยมหมุนในแบบ 2 มิติโดยใช้OpenGL :

let () = ignore ( Glut . init Sys . argv ); Glut . initDisplayMode ~ double_buffer : true () ; ignore ( Glut . createWindow ~ title : "OpenGL Demo" ); let angle t = 10 . *. t *. t in let render () = GlClear . clear [ ` color ]; GlMat . load_identity () ; GlMat . rotate ~ angle : ( angle ( Sys . time () )) ~ z : 1 . () ; GlDraw . begins ` triangles ; List . iter GlDraw . vertex2 [- 1 ., - 1 .; 0 ., 1 .; 1 ., - 1 .]; GlDraw . ends () ; Glut . swapBuffers () in GlMat . โหมด` modelview ; Glut . displayFunc ~ cb : render ; Glut . idleFunc ~ cb :( Some Glut . postRedisplay ); Glut . mainLoop ()

จำเป็นต้องมีส่วนเชื่อมต่อ LablGL กับ OpenGL จากนั้นจึงสามารถคอมไพล์โปรแกรมเป็นไบต์โค้ดได้ด้วยคำสั่ง:

$ ocamlc -I +lablGL lablglut.cma lablgl.cma simple.ml -o simple 

หรือเขียนโค้ดด้วย NativeCode โดยใช้:

$ ocamlopt -I +lablGL lablglut.cmxa lablgl.cmxa simple.ml -o simple 

หรือจะใช้วิธีที่ง่ายกว่านั้นคือ ใช้คำสั่ง build ของ ocamlfind

$ ocamlfind opt simple.ml -package lablgl.glut -linkpkg -o simple 

และวิ่ง:

$ ./simple 

โปรแกรมกราฟิก 2 มิติและ 3 มิติที่มีความซับซ้อนและประสิทธิภาพสูงกว่ามากสามารถพัฒนาได้ด้วยภาษา OCaml ด้วยการใช้ OpenGL และ OCaml โปรแกรมที่ได้จึงสามารถใช้งานได้บนหลายแพลตฟอร์ม โดยสามารถคอมไพล์ได้โดยไม่ต้องเปลี่ยนแปลงใดๆ บนหลายแพลตฟอร์มหลัก

ลำดับฟิโบนาชชี

โค้ดต่อไปนี้คำนวณลำดับฟิโบนาชชีของตัวเลขnที่ป้อนเข้ามา โดยใช้การเรียกซ้ำแบบหาง (tail recursion)และการจับคู่รูปแบบ (pattern matching)

let fib n = let rec fib_aux m a b = match m with | 0 -> a | _ -> fib_aux ( m - 1 ) b ( a + b ) in fib_aux n 0 1

ฟังก์ชันลำดับสูงกว่า

ฟังก์ชันอาจรับฟังก์ชันอื่นเป็นอินพุตและส่งคืนฟังก์ชันอื่นเป็นผลลัพธ์ ตัวอย่างเช่น การใช้ฟังก์ชันf สองครั้งจะได้ฟังก์ชันที่ใช้ฟังก์ชันfกับอาร์กิวเมนต์สองครั้งเช่นกัน

let twice ( f : ' a -> ' a ) = fun ( x : ' a ) -> f ( f x );; let inc ( x : int ) : int = x + 1 ;; let add2 = twice inc ;; let inc_str ( x : string ) : string = x ^ " " ^ x ;; let add_str = twice ( inc_str );;
# add2 98 ;; - : int = 100 # add_str "Test" ;; - : string = "Test Test Test Test"

ฟังก์ชันtwiceใช้ตัวแปรชนิด'a'เพื่อระบุว่าสามารถนำไปใช้กับฟังก์ชันf ใดๆ ที่ แมปจากชนิด'a'ไปยังตัวมันเองได้ ไม่ใช่แค่ ฟังก์ชัน int->int เท่านั้น โดยเฉพาะอย่างยิ่งtwiceยังสามารถนำไปใช้กับตัวมันเองได้ด้วย

# let fourtimes f = ( twice twice ) f ;; val fourtimes : ( ' a -> ' a ) -> ' a -> ' a = < fun > # let add4 = fourtimes inc ;; val add4 : int -> int = < fun > # add4 98 ;; - : int = 102

ภาษาที่สืบเนื่องมาจากภาษาเดิม

เมตาโอแคมล์

MetaOCaml [ 24 ]เป็น ส่วนขยาย การเขียนโปรแกรมแบบหลายขั้นตอนของ OCaml ที่ช่วยให้สามารถคอมไพล์โค้ดเครื่อง ใหม่แบบเพิ่มทีละขั้นตอนได้ ในระหว่างการทำงาน ภายใต้สถานการณ์บางอย่างสามารถเพิ่มความเร็ว ได้อย่างมากโดยใช้ การเขียนโปรแกรมแบบหลายขั้นตอนเนื่องจากมีข้อมูลรายละเอียดเพิ่มเติมเกี่ยวกับข้อมูลที่จะประมวลผลในระหว่างการทำงานมากกว่าในระหว่างการคอมไพล์ตามปกติ ดังนั้นคอมไพเลอร์แบบเพิ่มทีละขั้นตอนจึงสามารถเพิ่มประสิทธิภาพการตรวจสอบเงื่อนไข ฯลฯ ได้หลายกรณี

ตัวอย่างเช่น หากทราบในขั้นตอนการคอมไพล์ว่า จำเป็นต้องใช้ ฟังก์ชันยกกำลัง บาง อย่างบ่อยๆ แต่ทราบค่าของฟังก์ชันนั้นเฉพาะในขั้นตอนการรันไทม์ เท่านั้น สามารถใช้ฟังก์ชันยกกำลังแบบสองขั้นตอนใน MetaOCaml ได้: x->x^nn

ให้rec power n x = ถ้าn = 0 แล้ว.< 1 >. มิฉะนั้นถ้าn เป็นเลขคู่แล้วsqr ( power ( n / 2 ) x ) มิฉะนั้น.<.~ x *. .~( power ( n - 1 ) x )>.

เมื่อnทราบข้อมูลในระหว่างการทำงานแล้ว สามารถสร้างฟังก์ชันพลังงานเฉพาะทางที่รวดเร็วมากได้:

.< fun x -> .~( power 5 .< x >.)>.

ผลลัพธ์คือ:

fun x_1 -> ( x_1 * let y_3 = let y_2 = ( x_1 * 1 ) in ( y_2 * y_2 ) in ( y_3 * y_3 ))

ฟังก์ชันใหม่จะถูกคอมไพล์โดยอัตโนมัติ

ภาษาอื่นๆ ที่สืบเนื่องมาจากภาษานี้

ซอฟต์แวร์ที่เขียนด้วยภาษา OCaml

ผู้ใช้

บริษัทอย่างน้อยหลายสิบแห่งใช้ OCaml ในระดับหนึ่ง[ 30 ]ตัวอย่างที่น่าสนใจได้แก่:

  • Bloomberg LPซึ่งสร้าง BuckleScript ซึ่งเป็นแบ็กเอนด์คอมไพเลอร์ OCaml ที่กำหนดเป้าหมายเป็น JavaScript (ซึ่งต่อมาพัฒนาเป็นReScript ) [ 31 ]
  • Citrix Systemsซึ่งใช้ OCaml ในXenServer (เปลี่ยนชื่อเป็น Citrix Hypervisor ในปี 2018) [ 32 ]
  • Facebookซึ่งพัฒนา Flow [ 33 ] Hack, Infer, Pfff และReasonMLใน OCaml
  • Jane Street Capitalบริษัทซื้อขายหลักทรัพย์ที่ใช้ OCaml เป็นภาษาที่ต้องการตั้งแต่ช่วงแรกๆ[ 34 ]และยังคงใช้มาจนถึงปี 2023 [ 35 ] [ 36 ]ในเดือนมิถุนายน 2025 บริษัทได้ประกาศการแยกสาขาOxCaml [ 37 ]
  • Dockerซึ่งใช้ OCaml ในเวอร์ชันเดสก์ท็อปบนmacOSและWindows [ 38 ] [ 39 ] [ 40 ]

ในบริบทของการสอนและการวิจัยทางวิชาการ OCaml มีบทบาทที่โดดเด่นในหลักสูตรการสอนด้านวิทยาการคอมพิวเตอร์ ทั้งในมหาวิทยาลัยและวิทยาลัย สามารถดูรายการแหล่งข้อมูลทางการศึกษาและหลักสูตรการสอนเหล่านี้ได้ที่ ocaml.org

  • เว็บไซต์อย่างเป็นทางการแก้ไขข้อมูลนี้ได้ที่วิกิดาต้า
  • คู่มือ OCaml
  • ตัวจัดการแพ็กเกจ OCaml
  • OCaml ในโลกแห่งความเป็นจริง
ดึงข้อมูลมาจาก " https://en.wikipedia.org/w/index.php?title=OCaml&oldid=1343769161#MetaOCaml "

สรุปเนื้อหา

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

ข้อมูลสำคัญเกี่ยวกับ โอแคมล์

OCaml ( / oʊ ˈ k æ m əl / oh- KAM -əl เดิมชื่อ Objective Caml ) เป็น ภาษาโปรแกรมอเนกประสงค์ ระดับ สูงแบบ หลายพารา ดิกม์ ซึ่งขยาย ภาษา Caml ของ ML ด้วย คุณสมบัติ เชิงวัตถุ OCaml...

ปรัชญา

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

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

ทีมพัฒนา OCaml ได้รับรางวัลใน งาน Symposium on Principles of Programming Languages ​​(POPL) ปี 2024

การพัฒนา ML (ภาษาเมตา)

ระหว่างช่วงทศวรรษ 1970 ถึง 1980 โรบิน มิลเนอร์ นักวิทยาศาสตร์คอมพิวเตอร์ชาวอังกฤษและผู้ได้รับ รางวัลทัวริง ทำงานที่ ห้องปฏิบัติการพื้นฐานวิทยาศาสตร์คอมพิวเตอร์ ของมหาวิทยาลัย เอดินบะระ [ 9 ] [ 10 ] มิลเนอร์และคนอื่นๆ กำลังทำงานเกี่ยวกับ ตัวพิสูจน์ทฤษฎีบท...