มีใบเสนอราคาโดยRalph William Gosper, Jrที่พูดว่า:
โครงสร้างข้อมูลเป็นเพียงภาษาการเขียนโปรแกรมที่โง่
สิ่งนี้หมายความว่าอย่างไร อนิจจาทั้งหมดที่ฉันสามารถพบได้ใน Google เกี่ยวกับมันคือการคัดลอก / วางอย่างไม่ลดละของราคาเสนอโดยไม่มีบริบทใด ๆ
มีใบเสนอราคาโดยRalph William Gosper, Jrที่พูดว่า:
โครงสร้างข้อมูลเป็นเพียงภาษาการเขียนโปรแกรมที่โง่
สิ่งนี้หมายความว่าอย่างไร อนิจจาทั้งหมดที่ฉันสามารถพบได้ใน Google เกี่ยวกับมันคือการคัดลอก / วางอย่างไม่ลดละของราคาเสนอโดยไม่มีบริบทใด ๆ
คำตอบ:
ดูเหมือนว่าหัวใจของคำสั่งคือ:
โครงสร้างข้อมูลเป็นเพียง ... ภาษาการเขียนโปรแกรม
ซึ่งค่อนข้างจริงถ้าคุณคิดเกี่ยวกับมัน ท้ายที่สุดคอมไพเลอร์ก็ต้องพึ่งพาทรานสฟอร์มท์นี้ตลอดเวลา พวกเขาใช้ภาษาโปรแกรมแปลงเป็นโครงสร้างข้อมูลทำการแปลงบางส่วนของข้อมูลนั้นแล้วเปลี่ยนผลลัพธ์เป็นภาษาโปรแกรมอื่น
ในความเป็นจริงถ้าคุณต้องการคุณสามารถทำให้สิ่งที่บ้าเหมือนโครงสร้างข้อมูล C ที่ช่วยให้คุณเขียนรหัส C โดยการเรียกวิธีการต่าง ๆ - เช่น (ในประเภท C # เพราะนั่นคือสิ่งที่ฉันใช้ตอนนี้):
var C = ใหม่ HorribleCObject (); C.Function <int> ("main", typeof (char [] []), typeof (int)) .Variable ("i", typeof (int), 0) .While ("i", Func (i) => i <10)) .Call ("printf", "% d", "i") .PostIncrement ( "ฉัน") .EndWhile (); .Return (0) .EndFunction ();
ตอนนี้ตามที่อ้างถึงอย่างเต็มรูปแบบ: ทำไมสิ่งที่จะเป็นเช่นนั้นโง่เมื่อเทียบกับ (พูด) เขียนใน C ตัวเอง? มันควรจะชัดเจนว่านี่คือ verbose และไม่เกือบเท่าที่ชัดเจนใน C (และในทางปฏิบัติอาจไม่สนับสนุนขอบเขตทั้งหมดของ C ที่สามารถทำได้ - typedefs จะยุ่งยาก); ดังนั้นโครงสร้างข้อมูลนี้เป็นเพียงภาษาโปรแกรม "โง่" ซึ่งฝังอยู่ในภาษาโปรแกรม "ของจริง" ตรรกะเดียวกันนั้นสามารถใช้กับโครงสร้างข้อมูลใด ๆ ที่คุณนึกออก รายการที่เชื่อมโยงเป็นเพียงรุ่น "โง่" ของ Lisp และแผนที่แฮชเป็นเพียงรุ่น "โง่" ของภาษา Hash Programming (Hasp?) ในทางทฤษฎี
อย่างไรก็ตามเป็นสิ่งที่เราไม่ต้องการเขียน Hasp เสมอเพื่อโต้ตอบกับแผนที่แฮชของเรา เป็นปัญหาที่ทุกภาษาเฉพาะโดเมนมี - ในด้านหนึ่ง DSL ที่ใช้งานได้ดีนั้นทรงพลังพอที่จะแสดงทุกอย่างที่โมเดลพื้นฐานสามารถทำได้ ในทางกลับกันคุณต้องใช้ DSL ในสถานที่แรกจากนั้นคนอื่นต้องเรียนรู้ นั่นต้องใช้เวลาและความพยายามที่พวกเขาอาจไม่ต้องการใช้ ท้ายที่สุดฉันแค่ต้องการใส่ของลงในแผนที่แฮชแล้วตรวจสอบสิ่งอื่นที่อยู่ในนั้นฉันไม่ต้องการที่จะเรียนรู้ความซับซ้อนทั้งหมดของ Hash Oriented Programming
ดังนั้นโดยไม่ต้องคิดอะไรเราใช้ภาษาการเขียนโปรแกรมที่มีความเฉพาะเจาะจงสูงและชาญฉลาดทางทฤษฎีและกลั่นมันให้เหลือเพียงไม่กี่การดำเนินการที่โง่เขลาในโครงสร้างข้อมูล รายการที่เชื่อมโยงมีวิธีการง่าย ๆ แผนที่แฮชมีบางคนอื่น เราเพิกเฉยต่อการดำเนินการอื่น ๆ ที่มีประสิทธิภาพยิ่งขึ้นซึ่งคุณสามารถทำได้เหนือโครงสร้างข้อมูล (การใช้งาน LinkedList ส่วนใหญ่ไม่มีฟังก์ชั่น. Map หรือ. ForEach และฉันไม่สามารถจินตนาการได้ว่าคุณจะทำอะไรใน Hasp) เพื่อนำไปใช้อย่างชัดเจนในภาษาโปรแกรมหลัก - ซึ่งเป็นสิ่งที่โปรแกรมเมอร์ส่วนใหญ่จะคุ้นเคย
โครงสร้างข้อมูลนั้นโดยพื้นฐานแล้วเป็นส่วนขยายที่โง่เขลาของภาษาแม่ของพวกเขาในพื้นที่ปัญหาที่พวกเขาแสดงแนวคิด ส่วนขยายที่ชาญฉลาดเพียงพอจะต้องใช้ภาษาการเขียนโปรแกรมใหม่ที่เฉพาะเจาะจงและคนส่วนใหญ่จะไม่ต้องการที่จะเรียนรู้ว่า
โครงสร้างข้อมูลเป็นตัวแทนของภาษาการเขียนโปรแกรม แต่ไม่ใช่ "คมชัด" โดยเฉพาะอย่างยิ่ง
สามารถมองเห็นได้จาก "โหนดไดอะแกรม" เช่นเดียวกับในบทความ wiki ด้านล่าง:
http://en.wikipedia.org/wiki/Root_node#Terminology
อย่างไรก็ตามโครงสร้างข้อมูลนั้นไม่สมบูรณ์ในฐานะภาษาการเขียนโปรแกรมเพราะมันขาดไวยากรณ์และความคิดที่สมบูรณ์ที่จะเข้าใจได้ง่ายสำหรับโปรแกรมเมอร์ "ภาษา" ของโครงสร้างข้อมูลอาจถูกเปรียบเทียบกับเด็กที่พูดอะไรบางอย่างเช่น "ฉันเย็นชาเอาเสื้อคลุม"
"ภาษา" แตกหัก แต่สามารถเข้าใจได้ เด็กพูดว่า "เขา / เขาเย็นชาและต้องการเสื้อผ้าเพิ่มอีก คำพูดของเด็กเป็นภาษาอังกฤษ "โง่" และโครงสร้างข้อมูลที่เกี่ยวข้องกับภาษาโปรแกรม
ผมเชื่อว่าสิ่งที่บิลกอสเปอร์ตั้งใจคือการที่ทุกโครงสร้างข้อมูลเป็นเพียงการเขียนโปรแกรมโครงสร้างที่มีการบังคับใช้อย่าง จำกัด สิ่งนี้เกี่ยวข้องกับแนวคิดที่ว่า"การออกแบบภาษาคือการออกแบบห้องสมุดและการออกแบบห้องสมุดคือการออกแบบภาษา" [1]
วิธีหนึ่งในการคิดเกี่ยวกับปัญหานี้คือการพิจารณาโครงสร้างข้อมูลบนพื้นฐานของอัลกอริทึม ลืมเกี่ยวกับข้อกำหนดในการจัดเก็บหรือพิมพ์คำอธิบายประกอบในขณะนี้เพราะสิ่งเหล่านี้เป็นสิ่งเสริม
ตัวอย่างเช่นคุณสามารถประมวลผลอาเรย์แบบเชื่อมโยง (เรียกว่า a map
ในบางภาษา) ได้สองวิธี: โดยใช้ดัชนีบางชนิดที่เก็บไว้ในหน่วยความจำหรือโดยใช้นิพจน์กรณีแบบง่าย
ใน Haskell คุณสามารถแปลงอาเรย์แบบเชื่อมโยงเป็นโครงสร้างข้อมูล ...
let assocArray = [("a", 1),("b", 2),("c", 3)]
let key = "b"
lookup key assocArray
... หรือโดยใช้นิพจน์เคส ...
let key = "b"
case key of
"a" -> 1
"b" -> 2
"c" -> 3
... หรือมากกว่านั้นโดยตรง ...
let key = "b"
if key == "a"
then 1
else if key == "b"
then 2
else if key == "c"
then 3
else undefined
มันง่ายที่จะเห็นว่าการทำมิเรอร์ชนิดนี้ระหว่างโครงสร้างข้อมูลและโค้ดนั้นเป็นไปได้โดยการดูแคลคูลัสแลมบ์ดา ค่าใด ๆ สามารถแสดงโดยฟังก์ชันในแคลคูลัสแลมบ์ดาและแคลคูลัสเองนั้นเป็นสากล (ทัวริงสมบูรณ์)
[1] ขอบคุณสำหรับคำพูดของ Bjarne Stroustrup
พิจารณา Javascript โดยที่ข้อมูลทั้งหมดเป็นรหัส พิจารณา LISP โดยที่ data ทั้งหมดคือ code และ code ทั้งหมดเป็น data
ในการเริ่มต้นสิ้นสุดและทุกที่ในระหว่างข้อมูลเป็นเพียงบิต การที่เราพยายามทำการเติมบิตด้วยข้อความและสัญลักษณ์เพื่อให้สามารถอ่านได้ง่ายและมนุษย์แปลงได้เป็นเลเยอร์ของนามธรรมที่ต้องการ a) คุณเรียนรู้ภาษาคำจำกัดความและ b) คุณเรียนรู้การรั่วไหลของสิ่งที่เป็นนามธรรม
ตัวอย่างเช่นใน C # การเรียนรู้ความแตกต่างระหว่างโครงสร้างและคลาสคุณต้องเรียนรู้ความแตกต่างในการเปรียบเทียบความเท่าเทียมกันระหว่างประเภทค่าและประเภทอ้างอิง ontology ทุกข้อมูลต้องการชุดของกฎที่คุณต้องเรียนรู้และปฏิบัติตาม และเช่นเดียวกับภาษาใด ๆ มันช่วยให้คุณสามารถเข้าใจความคิดทั่วไปได้อย่างรวดเร็ว แต่ยิ่งคุณต้องการเข้าใกล้ความจริงที่แท้จริงของเรื่องนี้มากเท่าไหร่คุณก็ยิ่งมองไบนารีตัวเองได้มากขึ้นเท่านั้น
ในที่สุดเมื่อเราพิจารณาต้นไม้ B-tree หรือโครงสร้างข้อมูลที่คล้ายกันการนำโครงสร้างของต้นไม้และการดำเนินการประเภทอื่น ๆ ในนั้นต้องใช้ไวยากรณ์ชนิดพิเศษที่ไม่สามารถถ่ายโอนข้ามต้นไม้โครงสร้างหรือภาษา