คุณสมบัติของภาษาการเขียนโปรแกรมที่ทำให้การรวบรวมเป็นไปไม่ได้?


71

คำถาม:

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

ผู้เรียบเรียง: หลักการและการปฏิบัติโดย Parag H. Dave และ Himanshu B. Dave

หนังสือเล่มนี้ไม่มีเงื่อนงำเกี่ยวกับคำตอบ ฉันพยายามค้นหาคำตอบเกี่ยวกับแนวคิดการเขียนโปรแกรมภาษา (SEBESTA) แต่ก็ไม่มีประโยชน์ การค้นหาเว็บก็มีประโยชน์เล็กน้อยเช่นกัน คุณมีเงื่อนงำอะไรบ้าง


31
ชื่อเสียงPerl ไม่สามารถแยกได้ นอกเหนือจากนั้นการอ้างสิทธิ์นั้นดูเหมือนจะผิดเล็กน้อยโดยไม่มีข้อสันนิษฐานเพิ่มเติม: หากมีล่ามฉันสามารถรวบรวมล่ามและรหัสในปฏิบัติการที่เรียกใช้งานได้หนึ่งรายการ
Raphael

4
@ ราฟาเอล: เป็นความคิดที่ดี แต่ ... 1) คุณคิดว่ารหัสนั้นใช้ได้ก่อนที่จะถูกประหารชีวิต ที่ไม่ถือสำหรับการใช้งานแบบโต้ตอบ แน่นอนว่าคุณสามารถใช้การคอมไพล์แบบทันเวลากับโค้ดเนทีฟในคำสั่ง bash หรือเนื้อหาสแต็ก PostScript แต่เป็นแนวคิดที่ค่อนข้างบ้า 2) ความคิดของคุณไม่ได้รวบรวมรหัสจริง ๆ : ชุดรหัสไม่ใช่รุ่นที่รวบรวมของรหัส แต่ยังคงเป็นล่ามสำหรับรหัส
reinierpost

7
ในสมัยก่อนฉันมีโปรแกรมแก้ไข gwbasic ด้วยตัวเอง (gwbasic เก็บโปรแกรมพื้นฐานในรูปแบบของ bytecode) ขณะนี้ฉันไม่สามารถคิดวิธีที่มีสติในการรวบรวมสิ่งเหล่านั้นเป็นรหัสเครื่องในขณะที่ยังคงความสามารถในการแก้ไขด้วยตนเอง
PlasmaHH

15
@PlasmaHH: Self Modifying Codeย้อนกลับไปในปี 1948 คอมไพเลอร์ตัวแรกถูกเขียนขึ้นในปี 1952 แนวคิดของรหัสการแก้ไขตัวเองถูกคิดค้นขึ้นในรหัสเครื่องดั้งเดิม
Mooing Duck

10
@reierierpost Raphael กำลังยืนอยู่ในทางทฤษฎีเกี่ยวกับปัญหานี้ มันมีข้อดีของการแสดงข้อ จำกัด ทางแนวคิดของคำถาม การคอมไพล์คือการแปลจากภาษา S เป็นภาษา T. ภาษา T อาจเป็นส่วนขยายของ S ซึ่งสามารถแปลรหัสในภาษาอื่นได้ ดังนั้นการรวม S และล่ามเป็นโปรแกรมในภาษา T ดูเหมือนว่าไร้สาระต่อวิศวกร แต่มันแสดงให้เห็นว่าไม่ใช่เรื่องง่ายที่จะตั้งคำถามที่มีความหมาย คุณแยกกระบวนการรวบรวมที่ยอมรับได้จากกระบวนการที่ยอมรับไม่ได้ (เช่น Raphael's) ออกจากมุมมองทางวิศวกรรมได้อย่างไร
babou

คำตอบ:


61

ความแตกต่างระหว่างรหัสที่แปลและเรียบเรียงอาจเป็นนิยายตามที่ขีดเส้นใต้โดยความเห็นของราฟาเอล :

the claim seems to be trivially wrong without further assumptions: if there is
an interpreter, I can always bundle interpreter and code in one executable ...

ความจริงก็คือรหัสถูกตีความโดยซอฟต์แวร์โดยฮาร์ดแวร์หรือการรวมกันของทั้งสองและกระบวนการรวบรวมไม่สามารถบอกได้ว่ามันจะเป็น

สิ่งที่คุณเห็นว่าเป็นการรวบรวมเป็นกระบวนการแปลจากภาษาหนึ่ง (สำหรับต้นฉบับ) ไปยังภาษาอื่นT (สำหรับเป้าหมาย) และล่ามสำหรับSมักจะแตกต่างจากล่ามสำหรับTSTST

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

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

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

สิ่งหนึ่งที่อาจก่อให้เกิดปัญหา AFAIK เป็นอภิวัฏจักร นั่นคือเมื่อโปรแกรมจะจัดการโครงสร้างวากยสัมพันธ์ในภาษาต้นฉบับของตัวเองสร้างชิ้นส่วนของโปรแกรมที่จะถูก intepreted ราวกับว่าพวกเขาได้เป็นส่วนหนึ่งของโปรแกรมต้นฉบับ เนื่องจากคุณสามารถสร้างชิ้นส่วนโปรแกรมโดยพลการในภาษาSอันเป็นผลมาจากการคำนวณโดยพลการจัดการกับชิ้นส่วนวากยสัมพันธ์ที่ไม่มีความหมายฉันเดาว่าคุณสามารถทำให้มันเป็นไปไม่ได้เกือบ (จากมุมมองทางวิศวกรรม) เพื่อรวบรวมโปรแกรมเป็นภาษาTดังนั้น ตอนนี้สร้างชิ้นส่วนของT ดังนั้นจำเป็นต้องใช้ล่ามSหรืออย่างน้อยก็แปลจากSถึงSSTTSSสำหรับการรวบรวมชิ้นส่วนที่ถูกสร้างขึ้นใน S (ดูเอกสารนี้)TS

แต่ฉันไม่แน่ใจว่าวิธีการนี้จะเป็นทางการได้อย่างถูกต้อง (และไม่มีเวลาตอนนี้) และเป็นไปไม่ได้เป็นคำที่ยิ่งใหญ่สำหรับปัญหาที่ไม่เป็นทางการ

หมายเหตุเพิ่มเติม

เพิ่มหลังจาก 36 ชั่วโมง คุณอาจต้องการข้ามภาคต่อที่ยาวมากนี้

ความคิดเห็นจำนวนมากสำหรับคำถามนี้แสดงสองมุมมองของปัญหา: มุมมองเชิงทฤษฎีที่มองว่าไม่มีความหมายและมุมมองด้านวิศวกรรมที่น่าเสียดายที่ไม่เป็นทางการได้ง่าย

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

แผนภาพหลุมฝังศพ

หนึ่งใน formalization ต้น (ต้นปี 1960 ที่จะปลายปี 1990) เป็น T หรือ หลุมแผนภาพ ไดอะแกรมเหล่านี้นำเสนอในองค์ประกอบกราฟิกที่รวมกันได้คือภาษาการนำไปปฏิบัติของล่ามหรือผู้แปลภาษาต้นฉบับที่ถูกตีความหรือเรียบเรียงและภาษาเป้าหมายในกรณีของคอมไพเลอร์ เวอร์ชันที่ซับซ้อนยิ่งขึ้นสามารถเพิ่มคุณสมบัติได้ ภาพกราฟิกเหล่านี้สามารถมองเห็นได้เป็นสัจพจน์กฎการอนุมานใช้งานได้กับการสร้างตัวประมวลผลเชิงกลไกจากการพิสูจน์การมีอยู่ของพวกเขาจากสัจพจน์à la Curry-Howard (แม้ว่าฉันไม่แน่ใจว่าทำในยุคหกสิบเศษ :)

การประเมินบางส่วน

มุมมองที่น่าสนใจอีกประการหนึ่งคือกระบวนทัศน์การประเมินบางส่วน ฉันกำลังดูมุมมองที่เรียบง่ายของโปรแกรมในฐานะของการใช้งานฟังก์ชั่นที่คำนวณคำตอบที่ได้รับจากข้อมูลอินพุต แล้วล่าม สำหรับภาษาSเป็นโปรแกรมที่ใช้โปรแกรมP S เขียนในSและข้อมูลdสำหรับโปรแกรมที่และคำนวณผลตามความหมายของS การประเมินผลบางส่วนเป็นเทคนิคสำหรับโปรแกรมที่เชี่ยวชาญของทั้งสองมีปากเสียงเป็น1และ2เมื่อเพียงหนึ่งอาร์กิวเมนต์พูด1ผมSSพีSSdSa1a2a1เป็นที่รู้จักกัน เจตนาคือจะมีการประเมินผลได้เร็วขึ้นเมื่อคุณจนได้รับอาร์กิวเมนต์ที่สอง2 มันจะมีประโยชน์โดยเฉพาะอย่างยิ่งถ้า2เปลี่ยนแปลงบ่อยกว่า1เป็นค่าใช้จ่ายของการประเมินผลบางส่วนกับ1สามารถตัดจำหน่ายคำนวณทั้งหมดที่มีเพียง2มีการเปลี่ยนแปลงa2a2a1a1a2

นี่เป็นสถานการณ์ที่บ่อยครั้งในการออกแบบอัลกอริทึม (มักจะเป็นหัวข้อของความคิดเห็นแรกใน SE-CS) เมื่อมีการประมวลผลข้อมูลส่วนคงที่เพิ่มเติมก่อนเพื่อให้ต้นทุนของการประมวลผลล่วงหน้าสามารถตัดจำหน่ายในทุกการใช้งาน ของอัลกอริทึมที่มีส่วนต่าง ๆ ของข้อมูลอินพุตมากขึ้น

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

ทฤษฎีบท Smn

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

กำหนดเลขGödel ของฟังก์ชัน recursive คุณสามารถดูφเป็นฮาร์ดแวร์ของคุณเพื่อให้ได้รับจำนวนGödel P (อ่านรหัสวัตถุ ) ของโปรแกรมการφ พีเป็นฟังก์ชั่นที่กำหนดโดยP (เช่นคำนวณโดยรหัสวัตถุกับฮาร์ดแวร์ของคุณ )φφพีφพีพี

ในรูปแบบที่ง่ายที่สุดทฤษฎีบทดังกล่าวระบุไว้ในวิกิพีเดียดังต่อไปนี้ (ขึ้นอยู่กับการเปลี่ยนแปลงเล็ก ๆ ของสัญกรณ์):

กำหนดเลขGödel ของฟังก์ชัน recursive มีความเป็นดั้งเดิมฟังก์ชันเวียนσของทั้งสองมีปากเสียงกับคุณสมบัติดังต่อไปสำหรับทุกจำนวนGödel คิวของบางส่วนคำนวณฟังก์ชั่นFมีสองข้อโต้แย้งการแสดงออกφ σ ( Q , x ) ( Y )และf ( x , y )ถูกกำหนดไว้สำหรับการรวมกันของตัวเลขธรรมชาติxและyและค่าของมันจะเท่ากันสำหรับการรวมกันใด ๆ กล่าวอีกนัยหนึ่งความเสมอภาคในมิติของฟังก์ชั่นมีไว้สำหรับทุกคนφσQφσ(Q,x)(Y)(x,Y)xY : xφσ(Q,x)λY.φQ(x,Y).

ตอนนี้การรับเป็นล่ามI S , xเป็นซอร์สโค้ดของโปรแกรมp Sและyเป็น data dสำหรับโปรแกรมนั้นเราสามารถเขียน: QผมSxพีSYdφσ(ผมS,พีS)λd.φผมS(พีS,d).

อาจจะเห็นเป็นการดำเนินการของล่ามที่ฉันS บนฮาร์ดแวร์เช่นเป็นกล่องดำพร้อมที่จะตีความโปรแกรมที่เขียนในภาษาSφผมSผมSS

ฟังก์ชันอาจถูกมองว่าเป็นฟังก์ชันที่เชี่ยวชาญล่ามI SสำหรับโปรแกรมP Sเช่นเดียวกับการประเมินผลบางส่วน ดังนั้นจำนวนGödel σ ( ฉันS , P S )อาจจะเห็นมีรหัสวัตถุที่เป็นรุ่นที่รวบรวมของโปรแกรมP SσผมSPSσ(ผมS,พีS)พีS

ดังนั้นฟังก์ชั่น อาจถูกมองว่าเป็นฟังก์ชั่นที่รับอาร์กิวเมนต์ซอร์สโค้ดของโปรแกรม q S ที่ เขียนด้วยภาษา Sและส่งคืนเวอร์ชันรหัสวัตถุสำหรับโปรแกรมนั้นดังนั้น C Sคือสิ่งที่มักจะเรียกว่า คอมไพเลอร์CS=λQS.σ((ผมS,QS)QSSCS

ข้อสรุปบางอย่าง

อย่างไรก็ตามอย่างที่ฉันพูดว่า: "ทฤษฎีอาจเป็นคนโกหก" หรือที่จริงแล้วดูเหมือนจะเป็นหนึ่ง ปัญหาคือว่าเรารู้อะไรของฟังก์ชันσมีฟังก์ชั่นมากมายจริง ๆ และฉันเดาว่าการพิสูจน์ทฤษฎีบทอาจใช้คำจำกัดความง่าย ๆ สำหรับมันซึ่งอาจไม่ดีขึ้นจากมุมมองทางวิศวกรรมมากกว่าโซลูชันที่เสนอโดยราฟาเอล: เพื่อรวม แหล่งที่มาของรหัสQ Sกับล่ามฉัน S สิ่งนี้สามารถทำได้เสมอเพื่อให้เราสามารถพูดได้ว่า: การรวบรวมเป็นไปได้เสมอσQSผมS

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

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

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

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

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

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


3
" เป็นไปไม่ได้เป็นคำใหญ่" เป็นคำที่ใหญ่มาก =)
Brian S

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

@BrianS ไม่ไม่ใช่และเป็นไปไม่ได้ที่จะพิสูจน์เป็นอย่างอื่น)
Michael Gazonda

@supercat ยังไม่ได้นิยาม 'ความหมาย' ของโครงสร้างภาษาคืออะไร?
Rhymoid

ฉันชอบแนวคิดของการดูคอมไพเลอร์ / ล่ามว่าเป็นการประมวลผลบางส่วน!
Bergi

17

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

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

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

evalเป็นคุณลักษณะที่ต้องการ - ล่ามขั้นสูงสุด แต่มีคุณสมบัติอื่น ๆ ที่ต้องการบางสิ่งที่สั้น ๆ ของล่าม พิจารณาขั้นตอนทั่วไปของคอมไพเลอร์:

  1. วจีวิภาค
  2. การตรวจสอบประเภท
  3. การสร้างรหัส
  4. การเชื่อมโยง

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

การพูดโดยทั่วไปการไตร่ตรองมีแนวโน้มที่จะทำให้ภาษายากที่จะคอมไพล์โค้ดเนม ดั้งเดิม eval เป็นกรณีที่รุนแรงของการสะท้อน; หลายภาษาไม่ได้ไปไกลขนาดนั้น แต่ถึงกระนั้นก็มีความหมายที่กำหนดไว้ในแง่ของเครื่องเสมือนอนุญาตให้ตัวอย่างรหัสเพื่อดึงชั้นเรียนด้วยชื่อตรวจสอบการสืบทอดรายการรายการวิธีการเรียกวิธีการ ฯลฯJavaกับJVMและC #ด้วย. NETเป็นสองตัวอย่างที่มีชื่อเสียง วิธีที่ตรงไปตรงมาที่สุดในการใช้ภาษาเหล่านี้คือการคอมไพล์พวกเขาให้เป็นbytecodeแต่มีคอมไพเลอร์เนทีฟ (หลายตัวในเวลา ) ที่รวบรวมอย่างน้อยชิ้นส่วนของโปรแกรมที่ไม่ได้ใช้เครื่องมือสะท้อนขั้นสูง

การตรวจสอบประเภทกำหนดว่าโปรแกรมนั้นถูกต้องหรือไม่ ภาษาที่แตกต่างกันมีมาตรฐานที่แตกต่างกันสำหรับการวิเคราะห์ที่ดำเนินการ ณ เวลารวบรวมเทียบกับเวลาดำเนินการ: ภาษาที่รู้จักกันในชื่อ "พิมพ์แบบคงที่" ถ้าทำการตรวจสอบจำนวนมากก่อนที่จะเริ่มเรียกใช้รหัสและ "พิมพ์แบบไดนามิก" ถ้าไม่ บางภาษามีคุณสมบัติการส่งแบบไดนามิกหรือคุณสมบัติ unmarshall-and-typecheck คุณลักษณะเหล่านี้จำเป็นต้องมีการฝังตัวตรวจสอบชนิดในสภาพแวดล้อมรันไทม์ นี่คือมุมฉากของข้อกำหนดในการรวมตัวสร้างโค้ดหรือล่ามในสภาพแวดล้อมรันไทม์

¹ การฝึก: กำหนดภาษาที่ไม่สามารถตีความได้


(1) ฉันไม่เห็นด้วยกับการรวมล่ามกับซอร์สโค้ดที่นับเป็นการรวบรวม แต่โพสต์ที่เหลือของคุณยอดเยี่ยม (2) ตกลงทั้งหมดเกี่ยวกับการประเมิน (3) ฉันไม่เห็นสาเหตุที่การไตร่ตรองจะทำให้ภาษายากต่อการคอมไพล์เป็นโค้ดเนทีฟ Objective-C มีเงาสะท้อนและ (ฉันถือว่า) มันถูกคอมไพล์โดยทั่วไป (4) โน้ตที่เกี่ยวข้องกับ Vaguely โดยทั่วไปแล้วเทมเพลต C ++ จะแปลความหมายแทนการคอมไพล์แล้วดำเนินการ
Mooing Duck

เพิ่งเกิดขึ้นกับฉัน Lua รวบรวม evalเพียงแค่รวบรวม bytecode และจากนั้นเป็นขั้นตอนที่แยกต่างหากไบนารีรันโค้ดไบต์ และมันมีการสะท้อนกลับในไบนารี่ที่คอมไพล์ด้วย
Mooing Duck

บนเครื่องของ Harvard Architecture การคอมไพล์ควรให้โค้ดที่ไม่ต้องเข้าถึงเป็น "data" ฉันจะวางตัวข้อมูลจากไฟล์ต้นฉบับซึ่งจะต้องถูกเก็บไว้เป็นข้อมูลมากกว่ารหัสไม่ได้ "รวบรวม" ไม่มีอะไรผิดปกติกับคอมไพเลอร์ที่ประกาศเช่นint arr[] = {1,2,5};และสร้างส่วนเริ่มต้นข้อมูลที่มี [1,2,5] แต่ฉันจะไม่อธิบายพฤติกรรมของมันในขณะที่แปล [1,2,5] เป็นรหัสเครื่อง หากโปรแกรมเกือบทั้งหมดต้องเก็บเป็นข้อมูลส่วนใดของโปรแกรมที่จะ "รวบรวม"
supercat

2
@supercat นั่นคือสิ่งที่นักคณิตศาสตร์และนักวิทยาศาสตร์คอมพิวเตอร์หมายถึงเรื่องไม่สำคัญ มันเหมาะกับคำนิยามทางคณิตศาสตร์ แต่ไม่มีอะไรน่าสนใจเกิดขึ้น
Gilles

@Gilles: หากคำว่า "คอมไพล์" ถูกสงวนไว้สำหรับการแปลเป็นคำสั่งเครื่อง (โดยไม่มีการเก็บรักษา "data" ที่เกี่ยวข้อง) และยอมรับว่าในภาษาที่คอมไพล์แล้วพฤติกรรมของการประกาศอาเรย์จะไม่ "รวบรวม" อาเรย์ มีบางภาษาที่ไม่สามารถรวบรวมเศษส่วนที่มีความหมายของรหัสได้
supercat

13

ฉันคิดว่าผู้เขียนคิดว่าการรวบรวมหมายถึง

  • ซอร์สโปรแกรมไม่จำเป็นต้องแสดงในเวลาทำงานและ
  • ไม่จำเป็นต้องมีคอมไพเลอร์หรือล่ามในเวลาทำงาน

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

  1. หากคุณสามารถซักถามค่าของตัวแปรในขณะใช้งานโดยอ้างอิงถึงตัวแปรตามชื่อของมัน (ซึ่งเป็นสตริง) ดังนั้นคุณจะต้องใช้ชื่อตัวแปรที่อยู่รอบ ๆ ขณะใช้งาน

  2. หากคุณสามารถเรียกฟังก์ชัน / โพรซีเดอร์ ณ รันไทม์โดยอ้างอิงตามชื่อของมัน (ซึ่งเป็นสตริง) ดังนั้นคุณจะต้องใช้ชื่อฟังก์ชัน / โพรซีเดอร์ในเวลาทำงาน

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

เสียงกระเพื่อมมีคุณสมบัติทั้งสาม ดังนั้นระบบเสียงกระเพื่อมมักจะมีล่ามโหลดอยู่ตอนรันไทม์ ภาษา Java และ C # มีชื่อฟังก์ชันในขณะใช้งานและตารางเพื่อค้นหาความหมาย อาจเป็นภาษาพื้นฐานและ Python ก็มีชื่อตัวแปรในเวลาทำงาน (ฉันไม่แน่ใจ 100% เกี่ยวกับเรื่องนี้)


เกิดอะไรขึ้นถ้า "ล่าม" ถูกรวบรวมเป็นรหัส? ตัวอย่างเช่นการใช้ตารางสรุปข้อมูลเพื่อเรียกใช้เมธอดเสมือนนี่เป็นตัวอย่างของการตีความหรือการรวบรวม?
Erwin Bolwidt

2
"ไม่จำเป็นต้องมีคอมไพเลอร์หรือล่ามในเวลาทำงาน" ใช่มั้ย ถ้าเป็นจริงแล้วในแง่ลึก C ก็ไม่สามารถ "รวบรวม" บนแพลตฟอร์มส่วนใหญ่ได้เช่นกัน รันไทม์ C ไม่มีอะไรให้ทำมากนัก: เริ่มต้น, ตั้งค่าสแต็กและอื่น ๆ , และปิดการatexitประมวลผล แต่มันก็ยังต้องมี
นามแฝง

1
"ระบบเสียงกระเพื่อมมีล่ามโหลดอยู่ตลอดเวลา" - ไม่จำเป็น. ระบบเสียงกระเพื่อมจำนวนมากมีคอมไพเลอร์ที่รันไทม์ บางคนไม่เคยเป็นล่ามเลย
Jörg W Mittag

2
นีซลอง แต่en.wikipedia.org/wiki/Lisp_machine#Technical_overview พวกเขารวบรวมเสียงกระเพื่อมและถูกออกแบบมาเพื่อรันผลลัพธ์อย่างมีประสิทธิภาพ
Peter A. Schneider

@ ชื่อแฝง: รันไทม์ C เป็นไลบรารีไม่ใช่คอมไพเลอร์หรือล่าม
Mooing Duck

8

เป็นไปได้ว่าคำตอบปัจจุบันคือ "การคิดมาก" คำสั่ง / คำตอบ อาจเป็นสิ่งที่ผู้เขียนอ้างถึงเป็นปรากฏการณ์ต่อไปนี้ หลายภาษามีคำสั่ง "eval" เช่นเดียวกับ; เช่นดูจาวาสคริปต์ evalและพฤติกรรมของมันมักจะศึกษาเป็นส่วนพิเศษของทฤษฎี CS (เช่นพูดเสียงกระเพื่อม) ฟังก์ชั่นของคำสั่งนี้คือการประเมินสตริงในบริบทของการกำหนดภาษา ดังนั้นมันจึงมีความคล้ายคลึงกับ "built in compiler" คอมไพเลอร์ไม่สามารถรู้เนื้อหาของสตริงจนกระทั่งรันไทม์ ดังนั้นการรวบรวมผลลัพธ์ eval ในรหัสเครื่องจึงไม่สามารถรวบรวมได้

คำตอบอื่น ๆ ชี้ให้เห็นว่าความแตกต่างของการตีความ VS ภาษาเรียบเรียงสามารถเบลออย่างมีนัยสำคัญในหลาย ๆ กรณี ESP กับภาษาที่ทันสมัยมากขึ้นเช่นการพูด Java กับ"เพียงแค่ในคอมไพเลอร์เวลา"หรือที่รู้จักว่า"ฮอตสปอต" (เครื่องยนต์จาวาสคริปต์เช่นV8มากขึ้นใช้เทคนิคเดียวกันนี้) ฟังก์ชั่น "เหมือน eval" เป็นหนึ่งในนั้นแน่นอน


2
V8 เป็นตัวอย่างที่ดี มันเป็นคอมไพเลอร์บริสุทธิ์ไม่มีการตีความใด ๆ เกิดขึ้น แต่ก็ยังคงสนับสนุนความหมายเต็มรูปแบบของ ECMAScript evalรวมทั้งไม่ จำกัด
Jörg W Mittag

1
ลัวะทำสิ่งเดียวกัน
Mooing Duck

3

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

นอกจากนี้ยังมีล่ามจำนวนมากที่ตั้งโปรแกรมในซิลิคอนซึ่งปกติเรียกว่า "CPU" และมักจะมีประโยชน์ในการแปลรหัสเครื่อง (ยังไม่มีอยู่, ไม่อยู่ในมือ, ... ) เช่น Linux 'x86_64 ถูกเขียนและทดสอบครั้งแรกในอีมูเลเตอร์ มีการแจกแจงเต็มรูปแบบในมือเมื่อชิปมาถึงตลาดแม้กระทั่งสำหรับผู้ใช้งานช่วงเริ่มต้น / ผู้ทดสอบ Java มักจะรวบรวมรหัส JVM ซึ่งเป็นล่ามซึ่งจะไม่ยากเกินไปที่จะเขียนในซิลิคอน

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

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

ความแตกต่าง "คอมไพเลอร์" และ "ล่าม" นี้แตกต่างกันอย่างสิ้นเชิงจริง ๆที่ไหนสักแห่งในกองซ้อนมีล่ามที่ดีที่สุดซึ่งใช้ "รหัส" และดำเนินการ "โดยตรง" อินพุตจากโปรแกรมเมอร์ผ่านการแปลงไปตามเส้นซึ่งสิ่งเหล่านั้นเรียกว่า "การรวบรวม" เป็นเพียงการวาดเส้นที่ไม่มีกฎเกณฑ์ในทราย


1

ความจริงก็คือว่ามีความแตกต่างใหญ่ระหว่างการตีความบางโปรแกรมพื้นฐานและการดำเนินการแอสเซมเบลอร์ และมีพื้นที่ในระหว่างกับ P-code / ไบต์รหัสที่มีหรือไม่มีคอมไพเลอร์ (เพียงในเวลา) ดังนั้นฉันจะพยายามสรุปบางประเด็นในบริบทของความเป็นจริงนี้

  • หากวิธีการแยกวิเคราะห์ซอร์สโค้ดขึ้นอยู่กับเงื่อนไขของการรันการเขียนคอมไพเลอร์อาจเป็นไปไม่ได้หรือยากมากจนไม่มีใครสนใจ

  • รหัสที่ปรับเปลี่ยนตัวเองนั้นเป็นไปไม่ได้ในการรวบรวม

  • โปรแกรมที่ใช้ฟังก์ชั่น eval-like มักไม่สามารถรวบรวมล่วงหน้าได้ (ถ้าคุณพิจารณาว่า string ที่ป้อนเข้าเป็นส่วนหนึ่งของโปรแกรม) แม้ว่าคุณจะใช้งานโค้ด eval'ed ซ้ำ ๆ มันก็อาจจะยัง มีประโยชน์ในการมีฟังก์ชั่นคล้าย eval ของคุณเรียกคอมไพเลอร์ บางภาษามี API สำหรับคอมไพเลอร์เพื่อให้ง่าย

  • ความสามารถในการอ้างถึงสิ่งต่าง ๆ ตามชื่อไม่ได้ จำกัด การรวบรวม แต่คุณจำเป็นต้องมีตาราง (ดังที่กล่าวไว้) ฟังก์ชั่นการโทรตามชื่อ (เช่น IDispatch) ต้องใช้ระบบประปาอย่างมากจนถึงจุดที่ฉันคิดว่าคนส่วนใหญ่ยอมรับว่าเรากำลังพูดถึงล่ามฟังก์ชั่นการโทรอย่างมีประสิทธิภาพ

  • การพิมพ์ที่อ่อนแอ (คำจำกัดความของคุณคืออะไร) ทำให้การรวบรวมยากขึ้นและอาจทำให้ประสิทธิภาพลดลง แต่มักจะเป็นไปไม่ได้ยกเว้นค่าที่แตกต่างกันจะทำให้การแยกวิเคราะห์แตกต่างกัน มีสเกลการเลื่อนอยู่ที่นี่: หากคอมไพเลอร์ไม่สามารถอนุมานชนิดที่แท้จริงได้, มันจะต้องปล่อยกิ่งก้าน, การเรียกใช้ฟังก์ชันและสิ่งนั้นจะไม่อยู่ที่นั่น, ฝังบิตของล่ามในปฏิบัติการได้อย่างมีประสิทธิภาพ


1

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

กล่าวอีกนัยหนึ่งภาษาสามารถเป็นตัวแทนของระบบเมตาดาต้าของตัวเอง (ดูMetaprogramming )

โปรดทราบว่าการสะท้อนภาษาในแง่ของการสืบค้นเกี่ยวกับ meta-data ของซอร์สโค้ดที่แน่นอนและอาจแก้ไข meta-data เท่านั้น (sth เช่น Java's หรือกลไกการสะท้อนของ PHP) ไม่ได้เป็นปัญหาสำหรับคอมไพเลอร์เนื่องจากมันมีอยู่แล้ว meta-data ณ เวลารวบรวมและสามารถทำให้สามารถใช้งานได้กับโปรแกรมที่คอมไพล์ได้ตามต้องการหากจำเป็น

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


LISP เป็นตัวอย่างที่น่ากลัวอย่างที่คิดว่าเป็น Sprt
vonbrand

@ vonbrand อาจจะ แต่แสดงทั้งแนวคิด homoiconicity และ data-code duality
Nikos M.

-1

ฉันรู้สึกว่าคำถามดั้งเดิมไม่ได้เกิดขึ้นอย่างดี ผู้เขียนคำถามอาจต้องการถามคำถามที่แตกต่างกันบ้าง: คุณสมบัติของภาษา progamming ช่วยอำนวยความสะดวกในการเขียนคอมไพเลอร์ได้อย่างไร

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


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

-1

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

การคอมไพล์ซอร์สโค้ดในโค้ดเครื่องนั้นเป็นไปไม่ได้ถ้าคุณยังไม่มีซอร์สโค้ด

ล่ามเพิ่มความยืดหยุ่นและโดยเฉพาะอย่างยิ่งพวกเขาเพิ่มความยืดหยุ่นในการเรียกใช้รหัสที่ไม่สามารถใช้ได้เมื่อมีการรวบรวมโครงการพื้นฐาน


2
"ฉันทำรหัสต้นฉบับหาย" ไม่ใช่คุณสมบัติของภาษาการเขียนโปรแกรม แต่เป็นของโปรแกรมใดโปรแกรมหนึ่งดังนั้นจึงไม่ตอบคำถาม และแน่นอนคุณต้องอ้างอิงสำหรับการเรียกร้องที่หลีกเลี่ยงการสูญเสียของรหัสที่มาคือ "เหตุผลหลักว่าทำไมภาษาตีความอยู่" หรือแม้กระทั่งเหตุผลที่พวกเขามีอยู่
David Richerby

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

@DavidRicherby และ Raphael ฉันพูดว่าผู้เขียนโพสต์นี้แสดงถึง (สิ่งที่ฉันอธิบายในคำตอบของฉัน) เป็นคุณลักษณะการปรับเปลี่ยนด้วยตนเองซึ่งแน่นอนว่าเป็นภาษาที่สร้างโดยการออกแบบและไม่ใช่สิ่งประดิษฐ์ของโปรแกรมเฉพาะบางอย่าง
Nikos M.
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.