สิ่งที่คุณถามเป็นหลักคือความแตกต่างระหว่างพลังการคำนวณและสิ่งที่เรียกว่าพลังการแสดงออก (หรือเพียงแค่การแสดงออก ) ของภาษา (หรือระบบการคำนวณ)
พลังการคำนวณ
กำลังการคำนวณหมายถึงสิ่งที่ชนิดของปัญหาภาษาที่สามารถคำนวณ ชั้นที่รู้จักมากที่สุดของการใช้พลังงานในการคำนวณคือสิ่งที่เทียบเท่ากับทัวริงเครื่องสากล มีระบบการคำนวณอื่น ๆ มากมายเช่นRandom Access Machines , calcul-แคลคูลัส , แคลคูลัสSK combinator , ฟังก์ชัน rec-recursive , WHILE
โปรแกรมและอื่น ๆ อีกมากมาย และเมื่อปรากฎว่าสิ่งเหล่านี้สามารถจำลองซึ่งกันและกันซึ่งหมายความว่าพวกเขาทั้งหมดมีพลังการคำนวณเหมือนกัน
สิ่งนี้ก่อให้เกิดวิทยานิพนธ์ทัวริสต์ของโบสถ์ (ตั้งชื่อตามโบสถ์อลองโซที่สร้าง calcul-แคลคูลัสและอลันทัวริงผู้สร้างเครื่องจักรทัวริงสากล) คริสตจักรทัวริง - วิทยานิพนธ์เป็นสมมติฐานในการคำนวณด้วยสองด้าน:
- ระบบคอมพิวเตอร์ทั้งหมดที่มีความสามารถในการคำนวณทั่วไปมีประสิทธิภาพเท่าเทียมกันและ
- มนุษย์ที่ติดตามอัลกอริทึมสามารถคำนวณฟังก์ชั่นได้อย่างแม่นยำที่ทัวริงเครื่องจักร (และระบบอื่น ๆ ) สามารถคำนวณได้
ที่สองมีความสำคัญในสาขาปรัชญาของจิตใจมากกว่าวิทยาศาสตร์คอมพิวเตอร์
อย่างไรก็ตามมีสองสิ่งที่คริสตจักรทัวริง - วิทยานิพนธ์ไม่ได้พูดซึ่งเกี่ยวข้องกับคำถามของคุณ:
- การจำลองสถานการณ์ต่าง ๆ นั้นมีประสิทธิภาพเพียงใดและ
- วิธีที่สะดวกในการเข้ารหัสของปัญหาคือ
ตัวอย่างง่าย ๆ สำหรับ (1): บน Random Access Machine การคัดลอกอาร์เรย์จะใช้เวลาตามสัดส่วนกับความยาวของอาร์เรย์ บนเครื่องทัวริง แต่มันต้องใช้สัดส่วนเวลากลับไปตารางของความยาวของอาร์เรย์เพราะเครื่องทัวริงไม่ได้มีการเข้าถึงหน่วยความจำแบบสุ่มก็สามารถย้ายข้ามเทปเซลล์หนึ่งในช่วงเวลาที่ ดังนั้นจึงจำเป็นต้องย้ายองค์ประกอบnของอาร์เรย์nครั้งเพื่อคัดลอก ดังนั้นรูปแบบการคำนวณที่แตกต่างกันอาจมีลักษณะการทำงานที่แตกต่างกันแม้ในกรณี asymptotic ที่เราพยายามสรุปจากรายละเอียดการใช้งาน
ตัวอย่างสำหรับ (2) มากมาย: ทั้ง calcul-แคลคูลัสและPythonเป็นทัวริงสมบูรณ์ แต่คุณอยากจะเขียนโปรแกรมใน Python หรือ calcul-แคลคูลัสมากกว่าไหม
นอกจากนี้ยังมีรอยย่นที่สามที่ฉันมีรอบจนกระทั่งตอนนี้: ระบบดั้งเดิมเหล่านั้นทั้งหมดได้รับการออกแบบโดยนักตรรกวิทยานักปรัชญาหรือนักคณิตศาสตร์ไม่ใช่นักวิทยาศาสตร์คอมพิวเตอร์ ... เพียงเพราะคอมพิวเตอร์และวิทยาศาสตร์คอมพิวเตอร์ไม่ได้อยู่ เหล่านี้ไปทั้งหมดกลับไปยังต้น 1930S แม้กระทั่งก่อนที่Konrad Zuse 's มากทดลองครั้งแรก (ซึ่งไม่ได้ตั้งโปรแกรมและ / หรืออยู่แล้วทัวริงสมบูรณ์) พวกเขาพูดถึง "ฟังก์ชั่นคำนวณตัวเลขธรรมชาติเท่านั้น"
ตอนนี้กลายเป็นว่ามีหลายสิ่งที่คุณสามารถแสดงเป็นฟังก์ชั่นกับตัวเลขธรรมชาติ - หลังจากทั้งหมดคอมพิวเตอร์ที่ทันสมัยของเราได้รับโดยที่น้อยกว่ามาก (โดยทั่วไป 3-4 ฟังก์ชั่นของตัวเลข 0 และ 1 และนั่นคือ ) แต่ตัวอย่างเช่นระบบปฏิบัติการคำนวณอะไรได้บ้าง?
ความคิดของ I / O, ผลข้างเคียง, การโต้ตอบกับสภาพแวดล้อมไม่ได้ถูกรวบรวมโดยแนวคิดของ "ฟังก์ชันเหนือจำนวนธรรมชาติ" และมันก็เป็นสิ่งที่สำคัญเนื่องจากSimon Peyton Jonesเคยกล่าวไว้ว่า"ฟังก์ชั่นล้วนๆที่ไม่มีผลข้างเคียงใด ๆ เลยก็คือทำให้ซีพียูของคุณร้อนแรง"ซึ่งสมาชิกผู้ฟังตอบ"จริง ๆ แล้วมันคือด้าน - ผลเช่นกัน! "
Edwin Bradyผู้ออกแบบของIdris (เพียงครึ่งเดียว) ใช้เรื่องตลก (ฉันไม่รู้ว่าเขาประดิษฐ์หรือไม่) คำว่า "Tetris-complete" เพื่อแสดงความแตกต่างระหว่าง "สามารถคำนวณฟังก์ชันใด ๆ ที่คำนวณได้บนตัวเลขธรรมชาติ" และ "สามารถ ถูกใช้เพื่อเขียนโปรแกรมที่ไม่น่าสนใจซึ่งมีปฏิสัมพันธ์กับสิ่งแวดล้อม " เขาแสดงให้เห็นถึงสิ่งนี้มากขึ้นโดยการติดตั้งSpace Invaders ที่โคลนใน Idrisแต่เขาบอกว่าเขามั่นใจว่า Tetris จะลดการบุกรุกของ Space
สิ่งที่จะชี้ให้เห็นก็คือว่าไม่เพียง แต่เป็นทัวริง-เท่าเทียมกันไม่จำเป็นต้องมากพอที่จะพูดคุยเกี่ยวกับการเขียนโปรแกรมจริง "ประโยชน์" มันอาจ OTOH ยังไม่ได้necesssary เช่นSQL กลายเป็นทัวริงเทียบเท่ากับ ANSI SQL: 1999แต่ก็ยังมีประโยชน์ก่อนหน้านั้น ในความเป็นจริงบางคนอาจโต้แย้งว่าการทำให้ทัวริงเทียบเท่าไม่ได้เพิ่มประโยชน์ใด ๆ เลย มีภาษาเฉพาะโดเมนจำนวนมากที่ไม่เทียบเท่าทัวริง ข้อมูลคำอธิบายภาษามักจะไม่ได้ (และไม่ควร) ภาษาโดยรวมนั้นไม่สามารถเทียบเท่าทัวริงได้ แต่คุณยังสามารถเขียนลูปเหตุการณ์เว็บเซิร์ฟเวอร์หรือระบบปฏิบัติการในภาษาเหล่านั้นได้ นอกจากนี้ยังมีภาษาที่เทียบเท่ากับทัวริง แต่นี่ถือว่าเป็นความผิดพลาดจริง ๆ
ดังนั้นโดยสรุปทัวริงนั้นไม่น่าสนใจอย่างมากเว้นแต่คุณต้องการวิเคราะห์โปรแกรมแบบคงที่
ลึกซึ้ง
สมมติว่าระบบการคำนวณของเรามีประสิทธิภาพเพียงพอที่จะแก้ปัญหาของเราได้สิ่งที่เราต้องทำต่อไปคือการแสดงอัลกอริทึมของเราในการแก้ปัญหานั้นในสัญกรณ์ทางการสำหรับระบบนั้น กล่าวอีกนัยหนึ่ง: เราต้องเขียนโปรแกรมด้วยภาษาคอมพิวเตอร์บางภาษา นั่นคือสิ่งที่ความคิดในการแสดงออกมา
มันหมายถึงเป็นหลักว่า "ง่าย" หรือ "สนุก" คือการเขียนโปรแกรมของเราในภาษาการเขียนโปรแกรมของเราโดยเฉพาะ อย่างที่คุณเห็นความคิดนั้นค่อนข้างคลุมเครือส่วนตัวและทางจิตวิทยามากกว่าทางเทคนิค
อย่างไรก็ตามมีความพยายามที่คำจำกัดความที่แม่นยำยิ่งขึ้น หนึ่งที่มีชื่อเสียงที่สุด (และหนึ่งที่เข้มงวดที่สุดที่ฉันรู้จัก) คือโดยMatthias Felleisenในกระดาษของเขาในพลังการแสดงออกของภาษาการเขียนโปรแกรม (สองหน้าแรกมีการแนะนำที่อ่อนโยนส่วนที่เหลือของกระดาษมีเนื้อมากขึ้น)
สัญชาตญาณหลักคือ: เมื่อแปลโปรแกรมจากภาษาเป็นภาษาอื่นการเปลี่ยนแปลงบางอย่างที่คุณต้องทำมีอยู่ในตัวเครื่อง (เช่นเช่นการเปลี่ยนFOR
ลูปเป็นWHILE
ลูปหรือลูปเป็นเงื่อนไขGOTO
) และบางคนต้องการการเปลี่ยนแปลงทั่วโลก โครงสร้างของโปรแกรม
เมื่อคุณสามารถแทนที่หนึ่งคุณลักษณะของภาษาหนึ่งด้วยคุณลักษณะที่แตกต่างกันของภาษาที่แตกต่างกันโดยการแปลงเฉพาะที่จากนั้นคุณสมบัติเหล่านี้จะกล่าวว่าจะไม่มีผลต่อพลังการแสดงออก นี่เรียกว่าน้ำตาลซินแทคติค
ในทางกลับกันหากต้องการเปลี่ยนแปลงโครงสร้างส่วนกลางของโปรแกรมภาษาที่คุณกำลังแปลจะถูกกล่าวว่าไม่สามารถแสดงคุณลักษณะได้ และภาษาที่คุณกำลังแปลมีการกล่าวว่าจะแสดงออกมากขึ้น (ด้วยความเคารพคุณลักษณะนี้)
โปรดทราบว่าสิ่งนี้ให้คำจำกัดความของความหมายของการแสดงออกอย่างเป็นกลาง โปรดทราบด้วยว่าแนวคิดนี้ขึ้นอยู่กับบริบทและคุณลักษณะนั้นเป็นการเปรียบเทียบ ดังนั้นหากทุกโปรแกรมในภาษาAสามารถแปลเป็นภาษาB ที่มีการเปลี่ยนแปลงในท้องถิ่นเท่านั้นและมีอย่างน้อยหนึ่งโปรแกรมในภาษาBซึ่งไม่สามารถแปลเป็น A ที่มีการเปลี่ยนแปลงในท้องถิ่นเท่านั้นภาษาBจึงมีความหมายมากกว่าภาษาอย่างเคร่งครัด. อย่างไรก็ตามสถานการณ์ที่เป็นไปได้มากขึ้นคือหลายโปรแกรมในทั้งสองภาษาสามารถแปลไปมาได้ แต่มีบางโปรแกรมในทั้งสองภาษาที่ไม่สามารถแปลเป็นภาษาอื่นได้ นี่หมายความว่าไม่มีภาษาใดที่แสดงออกได้ชัดเจนกว่าภาษาอื่น ๆ อย่างเคร่งครัดพวกเขามีคุณสมบัติที่แตกต่างกันซึ่งอนุญาตให้โปรแกรมต่าง ๆ แสดงออกได้หลายวิธี
สิ่งนี้ให้คำจำกัดความที่เป็นทางการเกี่ยวกับความหมายของคำว่า "มีความหมายมากขึ้น" แต่ก็ยังไม่ได้จับความคิดทางจิตวิทยาที่อยู่เบื้องหลังปรากฏการณ์ ตัวอย่างเช่นน้ำตาลทรายตามโมเดลนี้ไม่เพิ่มพลังการแสดงออกของภาษาเพราะสามารถแปลได้โดยใช้การเปลี่ยนแปลงในท้องถิ่นเท่านั้น แต่เรารู้จากประสบการณ์ที่มีFOR
, WHILE
และIF
สามารถใช้ได้ถึงแม้ว่าพวกเขาจะมีน้ำตาลเพียงประโยคสำหรับเงื่อนไขGOTO
ที่ทำให้การแสดงเจตนาของเราได้ง่ายขึ้น
ความจริงก็คือภาษาต่าง ๆ มีคุณสมบัติที่แตกต่างกันซึ่งทำให้การแสดงวิธีคิดต่าง ๆ เกี่ยวกับปัญหาง่ายขึ้นหรือยากขึ้น และบางคนอาจค้นหาวิธีหนึ่งในการแสดงเจตนาของพวกเขาได้ง่ายขึ้นและวิธีอื่นก็แตกต่างกัน
ตัวอย่างที่ฉันพบในแท็ก Ruby บน StackOverflow: ผู้ใช้หลายคนที่ทำตามแท็ก Ruby อ้างว่าลูปง่ายต่อการเข้าใจมากกว่าการเรียกซ้ำและการเรียกซ้ำเป็นเพียงสำหรับโปรแกรมเมอร์ขั้นสูงและลูปเท่านั้นที่เข้าใจง่ายสำหรับผู้ใช้ใหม่ ผู้มาใหม่ที่สมบูรณ์ซึ่งเขียนโค้ดแบบนี้โดยสังหรณ์ใจ:
def rock_paper_scissors
get_user_input
determine_outcome
print_winner
rock_paper_scissors # start from the top
end
ซึ่งมักจะนำไปสู่หลาย ๆ คนที่แสดงความคิดเห็นว่า "สิ่งนี้ไม่ได้ผล" และ "พวกเขาทำผิด" และ "วิธีที่ถูกต้อง" คือ:
def rock_paper_scissors
loop do
get_user_input
determine_outcome
print_winner
end
end
เห็นได้ชัดว่ามีบางคนที่การเรียกซ้ำหางเป็นวิธีที่เป็นธรรมชาติมากขึ้นในการแสดงแนวคิดของ "การวนซ้ำ" มากกว่าการสร้างแบบวนซ้ำ
สรุป
ความจริงที่ว่าสองภาษานั้นเทียบเท่ากับทัวริงบอกว่าสิ่งหนึ่งและที่แน่นอน: พวกเขาสามารถคำนวณชุดฟังก์ชั่นชุดเดียวกันกับตัวเลขธรรมชาติเช่นเดียวกับเครื่องทัวริง แค่นั้นแหละ.
ไม่ได้พูดอะไรเกี่ยวกับความเร็วในการคำนวณฟังก์ชันเหล่านั้น มันไม่ได้พูดอะไรเกี่ยวกับความง่ายในการแสดงฟังก์ชั่นเหล่านั้น และมันไม่ได้พูดอะไรเกี่ยวกับสิ่งอื่นที่พวกเขาสามารถทำได้นอกเหนือจากการคำนวณฟังก์ชั่นในจำนวนที่เป็นธรรมชาติ (เช่นการลิงก์ไปยังไลบรารี C การอ่านอินพุตจากผู้ใช้เขียนเอาต์พุตไปที่หน้าจอ)
นั่นหมายความว่าคลาสของปัญหาที่แต่ละภาษาการเขียนโปรแกรมสามารถแก้ไขได้ตามภาษาแตกต่างกันไปถึงแม้ว่าภาษาเหล่านี้จะถูกทำให้สมบูรณ์
ใช่.
- มีปัญหาที่ไม่ครอบคลุมโดยคำว่า "ทัวริงสมบูรณ์" (ซึ่งเกี่ยวข้องกับตัวเองด้วยฟังก์ชั่นการใช้คอมพิวเตอร์ในจำนวนธรรมชาติ) เช่นการพิมพ์ไปที่หน้าจอ สองภาษาสามารถทัวริงสมบูรณ์ แต่หนึ่งสามารถอนุญาตให้พิมพ์ไปที่หน้าจอและอื่น ๆ ไม่ได้
- แม้ว่าทั้งสองภาษาสามารถแก้ปัญหาเดียวกันได้ แต่ก็ไม่ได้พูดอะไรเกี่ยวกับความซับซ้อนของการเข้ารหัสและความง่ายในการแสดงการเข้ารหัสนี้ เช่น C สามารถแก้ปัญหาทุกปัญหา Haskell ทำได้เพียงเขียนล่าม Haskell ใน C ... แต่คุณต้องเขียนล่าม Haskell ก่อนเพื่อแก้ปัญหาด้วยวิธีนี้!