อะไรคือฟังก์ชั่นฉาก (แนวความคิด)?


24

ในบทความ CACM ที่ผ่านมา [1] ผู้เขียนนำเสนอการดำเนินงานสำหรับฟังก์ชั่นการจัดฉาก พวกเขาใช้คำศัพท์ราวกับว่าเป็นที่รู้จักกันดีและไม่มีการอ้างอิงใด ๆ ที่ดูเหมือนเป็นการแนะนำที่ชัดเจน

พวกเขาให้คำอธิบายสั้น ๆ (เปลี่ยนการเน้นของฉันและหมายเลขอ้างอิงเปลี่ยนเป็น 22 ในต้นฉบับ)

ในบริบทของการสร้างโปรแกรมการเขียนโปรแกรมแบบหลายขั้นตอน (MSP, การแสดงละครสั้น ๆ ) ที่จัดตั้งขึ้นตาม Taha และ Sheard [2] ช่วยให้โปรแกรมเมอร์อย่างชัดเจนการประเมินผลความล่าช้าของการแสดงออกโปรแกรมขั้นตอนภายหลัง (ดังนั้นการแสดงละครการแสดงออก) ขั้นตอนปัจจุบันได้อย่างมีประสิทธิภาพทำหน้าที่เป็นตัวสร้างรหัสที่ประกอบด้วย (และอาจดำเนินการ) โปรแกรมของขั้นตอนต่อไป

อย่างไรก็ตาม Taha และ Sheard เขียน (เน้นที่เหมือง):

โปรแกรมหลายขั้นตอนเป็นโปรแกรมที่เกี่ยวข้องกับการสร้างการรวบรวมและการประมวลผลโค้ดทั้งหมดที่อยู่ในกระบวนการเดียวกัน หลายภาษาแสดงโปรแกรมหลายขั้นตอน การจัดเตรียมและการเขียนโปรแกรมแบบหลายขั้นตอนจึงตอบสนองความต้องการโซลูชันทั่วไปที่ไม่ต้องจ่ายค่าโสหุ้ยการแปลขณะใช้งาน

พวกเขามากกว่าที่จะอ้างถึงการอ้างอิงหลายงานที่ถูกกล่าวหาว่าแสดงให้เห็นว่าการแสดงละครมีประสิทธิภาพซึ่งแสดงให้เห็นว่าแนวคิดนั้นเก่ากว่า พวกเขาไม่ได้ให้การอ้างอิงสำหรับคำนั้น ๆ

ข้อความเหล่านี้ดูเหมือนจะเป็นมุมฉากถ้าไม่ขัดแย้ง; บางทีสิ่งที่ Rompf และ Odersky เขียนเป็นแอพพลิเคชั่นที่ Taha และ Sheard เสนอ แต่อาจเป็นอีกมุมมองหนึ่งในสิ่งเดียวกัน พวกเขาดูเหมือนจะยอมรับว่าประเด็นสำคัญคือโปรแกรม (อีกครั้ง) เขียนบางส่วนของตัวเองที่รันไทม์ แต่ฉันไม่รู้ว่ามันเป็นความสามารถที่จำเป็นและ / หรือเพียงพอ

ดังนั้นการจัดเตรียมตามลำดับคือการตีความการจัดเตรียมในบริบทนี้ คำนี้มาจากไหน


  1. การแสดงละคร Modular แบบจริงจัง: แนวทางปฏิบัติในการสร้างรหัสรันไทม์และ DSL ที่คอมไพล์โดย T. Rompf และ M. Odersky (2012)
  2. MetaML และหลายขั้นตอนการเขียนโปรแกรมพร้อมคำอธิบายประกอบอย่างชัดเจนโดย W. Taha และ T. Sheard (2000)

คุณเห็นความขัดแย้งอะไรระหว่างข้อความทั้งสองนี้ สำหรับฉันดูเหมือนพวกเขากำลังพูดถึงสิ่งเดียวกันโดยเน้นที่แตกต่างกัน
Gilles 'หยุดชั่วร้าย'

@Gilles ฉันไม่ต้องการการสร้างรหัสรันไทม์ / - คอมไพล์เพื่อชะลอการประเมินบางสิ่ง (ดูต่อเนื่อง) อาจเป็นไปได้ว่ามันเป็นเพียงการเน้นอีกครั้ง (ฉันยอมรับตัวเลือกนั้นในคำถาม) แต่ฉันไม่สามารถบอกได้
ราฟาเอล

คุณสามารถตรวจสอบการใช้ภาษาโปรแกรมจูเลียและเอกสารประกอบ metaprogramming ได้ที่@generated functions: julia.readthedocs.org/en/latest/manual/metaprogramming/?hl=th
SalchiPapa

คำตอบ:


21

เพื่อให้ได้ความรู้ที่ดีที่สุดของฉันคำว่าการจัดฉากเป็นการใช้งานครั้งแรกโดย Bill Scherlis ในบทความนี้ ก่อนหน้านั้นคำว่า " การประเมินผลบางส่วน " ใช้สำหรับแนวคิดเดียวกันมาก แต่แนวคิดของการคำนวณแบบฉากแตกต่างกันเล็กน้อย ทั้งความคิดที่เกี่ยวข้องกับ Kleene ของทฤษฎีบท SMN

หากคุณมีฟังก์ชั่นของสองข้อโต้แย้ง แต่คุณรู้ข้อโต้แย้งหนึ่งข้อพูดว่าคุณสามารถทำการคำนวณฟังก์ชันได้ทันทีโดยใช้ความรู้ของอาร์กิวเมนต์แรก สิ่งที่คุณเหลืออยู่คือฟังก์ชั่นซึ่งการคำนวณขึ้นอยู่กับอาร์กิวเมนต์ที่สองไม่รู้จักm ϕ m ( n )ϕ(m,n)mϕm(n)

ความคิดของการประเมินผลบางส่วนคือการคำนวณฟังก์ชั่นพิเศษโดยอัตโนมัติ ได้รับรหัสสำหรับฟังก์ชั่นเดิมประเมินบางส่วนไม่วิเคราะห์แบบคงที่เพื่อตรวจสอบว่าบิตของรหัสขึ้นอยู่กับและที่บิตขึ้นอยู่กับและแปลงไปยังฟังก์ชั่นซึ่งได้รับ , สร้าง\ที่สองอาร์กิวเมนต์จากนั้นจะสามารถป้อนให้กับฟังก์ชั่นพิเศษนี้ϕ m n ϕ m ϕ m nϕm(n) ϕmnϕmϕmn

แนวคิดของการคำนวณแบบ staged คือคิดถึงฟังก์ชันก่อน มันถูกเรียกว่า "ฉาก" ฟังก์ชั่นเพราะมันทำงานได้ในหลายขั้นตอน เมื่อเราให้มันเป็นครั้งแรกอาร์กิวเมนต์ก็สร้างรหัสสำหรับฟังก์ชั่นพิเศษ\นี่คือ "ขั้นตอนแรก" ในขั้นตอนที่สองอาร์กิวเมนต์ที่สองจะถูกจัดเตรียมให้กับซึ่งทำหน้าที่ส่วนที่เหลือ m ϕ m ϕ mϕmϕmϕm

ดังนั้นงานบางส่วนของการประเมินผลคือการแปลงรหัสสำหรับฟังก์ชั่นสามัญกับฟังก์ชั่นฉากพี' Scherlis นึกภาพว่าการเปลี่ยนแปลงนี้สามารถทำได้โดยกลไกทั่วไปมากกว่าวิธีการประเมินบางส่วนก่อนหน้านี้ ตอนนี้หัวเรื่องของ "การคำนวณแบบ staged" เกี่ยวข้องกับปัญหาต่าง ๆ เช่น:ϕ ϕϕ

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

การคำนวณแบบฉากอาจมีความสำคัญมากในทางปฏิบัติ อันที่จริงคอมไพเลอร์ทุกตัวมีผลต่อการคำนวณแบบเป็นขั้น รับซอร์สโปรแกรมมันสร้างโปรแกรมเป้าหมายที่แปลแล้วและปรับให้เหมาะสมซึ่งสามารถรับอินพุตจริงและคำนวณผลลัพธ์ เป็นการยากที่จะเขียนโปรแกรมการคำนวณฉากในทางปฏิบัติเพราะเราต้องเล่นปาหี่หลายขั้นตอนและตรวจสอบให้แน่ใจว่าสิ่งที่ถูกต้องจะทำในเวลาที่เหมาะสม ทุกคนที่เขียนคอมไพเลอร์ได้ต่อสู้กับปัญหาดังกล่าว นอกจากนี้ยังเป็นการยากที่จะเขียนโปรแกรมที่เขียนโปรแกรมอื่น ๆ อาจเป็นโปรแกรมภาษาเครื่อง (คอมไพเลอร์), เคียวรี SQL (การจัดการฐานข้อมูล) หรือโค้ด HTML / Server Pages / Javascript (เว็บแอปพลิเคชัน) และแอปพลิเคชันอื่น ๆ


ϕϕ

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

1
ไม่แน่นอน ผู้ประเมินบางส่วนจะคอมไพล์โปรแกรมปกติให้กับโปรแกรม 2 สเตจจากนั้นรันสเตจแรกของมัน ในการเขียนโปรแกรมฉากคุณเขียนโปรแกรมหลายขั้นตอนด้วยตัวเอง
Uday Reddy

9

แม้ว่าคำตอบอื่น ๆ นั้นถูกต้องทางเทคนิคฉันไม่คิดว่าพวกเขาให้ความเข้าใจที่ถูกต้องว่าทำไมนักวิทยาศาสตร์คอมพิวเตอร์จึงสนใจฟังก์ชั่นจัดฉาก

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

มันจะดีถ้าเราสามารถกำจัดรหัสสำเร็จรูปทั้งหมด เราควรจะสามารถลดภาษาสเปคให้น้อยที่สุด ถ้าเราต้องการให้ตัวกระจายเหตุการณ์ที่ขับเคลื่อนด้วยเช่นการสื่อสารไปยังตัวแจกจ่ายอื่น ๆ ด้วยการออกแบบเธรดที่กำหนดเราควรจะสามารถระบุสิ่งนั้นให้แน่นหนาได้และผู้ฟัง IO และวัตถุคิวและการเชื่อมต่อเธรดทั้งหมดควรสามารถสร้างจากสเปคนั้น

ภาษาของโดเมนมีแนวโน้มที่จะเป็นตัวแทนที่เรากำลังมองหา เมื่อผู้คนทำงานในโดเมนซักพักหนึ่งภาษาที่พวกเขาใช้มีแนวโน้มที่จะลดความซ้ำซ้อนของข้อมูลและกลายเป็นข้อมูลจำเพาะแบบลีน ทฤษฎีการจัดเตรียมนี้จึงมีแนวโน้มที่จะกลายเป็นระบบการแปลจากภาษาโดเมนไปยังภาษาที่ใช้ในการประมวล

คอมไพเลอร์เป็น stagers ทางเทคนิค แต่มันพลาดเป้าหมาย เป้าหมายของการจัดเตรียมที่ทันสมัยคือการอนุญาตให้สร้างโปรแกรมที่สร้างโปรแกรมเพื่อเพิ่มการใช้ซ้ำและทำให้การสร้างโปรแกรมเป็นไปโดยอัตโนมัติทุกที่ที่ทำได้ มันจะดีถ้าความต้องการในการใช้งานหนึ่งวันของโปรแกรมนั้นเป็นโปรแกรม

โปรดดู "การเขียนโปรแกรมทั่วไป" โดย Czarnecki และ Eisenecker (ISBN-13: 978-0201309775)


@Raphael: นี่คือบทที่สามที่มีพื้นฐานเกี่ยวกับโดเมนและนำมาใช้ซ้ำ ดูแม้แต่การเพิ่มประสิทธิภาพที่คุณพูดถึง FFT ไม่ได้ดำเนินการโดยจัดเตรียมเพื่อให้ทำงานได้เร็วขึ้น มันถูกทำขึ้นเพื่อให้โปรแกรมเมอร์ไม่จำเป็นต้องคำนวณตารางค่าในแต่ละครั้งด้วยมือคัดลอกไปยังโปรแกรมและสร้างรายการใหญ่ เพื่อลดการทำงานให้น้อยที่สุดและนำขั้นตอนพื้นฐานมาใช้ซ้ำ เช่นเดียวกันกับการเปิดลูป ทำด้วยมือซ้ำข้อมูลและไม่สามารถนำกลับมาใช้ใหม่ได้
ex0du5

มุมมอง DSL นี้ดูเหมือนจะ จำกัด การ staging เป็นหนึ่งระดับ (คอมไพเลอร์ DSL หนึ่งตัวในโปรแกรม) ใช่ไหม?
กราฟิลส์

1
@ ราฟาเอล: มันขึ้นอยู่กับมุมมองของคุณ เห็นได้ชัดว่าแนวคิดนี้ไม่เพิ่มพลังในการคำนวณเมื่อมองว่าเป็นซอร์ส -> การแปลที่ปฏิบัติการได้ เราสามารถสร้างคอมไพเลอร์สำหรับภาษา DS และทำได้ จุดแข็งของมันมาจากไหนในการทำซ้ำ เมื่อสร้างห้องสมุดที่จะใช้และขยายโดยโครงการในอนาคตระยะธรรมชาติจะปรากฏขึ้นภายในขอบเขตห้องสมุด คุณอาจมีห้องสมุดที่แปลงคุณสมบัติของวัตถุให้เป็นแหล่งข้อมูลสำหรับการทำให้เป็นอนุกรมเต็มรูปแบบและจากนั้นอีกไลบรารีหนึ่งที่สร้างเลเยอร์การขนส่งที่สร้างขึ้นบนสเป็คการส่งบางอย่าง ...
ex0du5

1
@ ราฟาเอล: การแสดงละครอาจเป็นไปตามธรรมชาติด้วยหลายขั้นตอน หากโค้ดหนึ่งชิ้นมีความต้องการเปลี่ยนแปลงไปมากเมื่อเวลาผ่านไปซึ่งโค้ดอื่น ๆ มีความเสถียรมากกว่านั้นอาจเหมาะสมเนื่องจาก "การตัดเลเยอร์" เพื่อแยกการจัดเตรียมเป็นเลเยอร์ด้วยอินเทอร์เฟซที่เสถียรกว่า จากนั้นคุณสามารถส่งผลกระทบต่อระบบน้อยลงเมื่อมีการเปลี่ยนแปลงและให้เกียรติแบบฟอร์มการแสดงละครของหลักการแบบเปิด สิ่งเหล่านี้เป็นข้อกังวลในทางปฏิบัติที่ไม่มีความจำเป็นทางคณิตศาสตร์ แต่ทั้งหมดขึ้นอยู่กับการปฏิบัติจริง เราไม่ต้องการภาษาคอมไพเลอร์เดียวเราต้องการอนุญาตให้มีการวิวัฒนาการ
ex0du5

5

คำตอบนั้นอยู่ในมุมมองทางเทคนิคสำหรับบทความที่เป็นปัญหา [1] ปัญหาภายใต้การพิจารณาคือพื้นที่ของความตึงเครียดระหว่างรหัสทั่วไปและรหัสเฉพาะ:

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

แน่นอนว่าเราต้องการแก้ปัญหาความตึงเครียดนี้ซึ่งเป็นรหัสทั่วไปและการใช้งานเฉพาะ:

เราสามารถถามคำถาม: เป็นไปได้ไหมที่จะเขียนโค้ดเพื่อให้เป็นจุดประสงค์ทั่วไป แต่ก็มีความเชี่ยวชาญโดยอัตโนมัติกับสถานการณ์ที่เกิดขึ้นระหว่างดำเนินการหรือไม่?

สิ่งนี้ทำให้เกิดความคิดในการมีโปรแกรม (ทั่วไป) (ใหม่) เขียนตัวเองที่รันไทม์เพื่อรองรับสถานการณ์ที่เฉพาะเจาะจง:

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

ฉันเดาว่า JIT ของ Java เป็นตัวอย่างที่ดี แนวคิดหนึ่งที่เจาะจงคือการเขียนโปรแกรมแบบหลายขั้นตอนซึ่ง Lee อธิบายดังนี้:

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

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

Rompf และ Odersky พูดถึงการแปลงฟูริเยร์ที่รวดเร็วซึ่งเป็นตัวอย่างที่อาจเป็นประโยชน์


  1. สุนัขจิ้งจอกและสัตว์ชนิดหนึ่งที่มีขนแหลมคล้ายเม่น: มุมมองทางเทคนิคโดย Peter Lee (2012)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.