2.3 Modularity
The single most important method for controlling the complexity of building
large software systems is modularity, the decomposition of programs into com-
posable components. The vast bulk of research in programming languages may
be seen as an attempt to address this basic principle. The dominance of type
systems as a tool for language design stems directly from Reynolds's dictum
that a type system is a syntactic discipline for enforcing levels of abstraction.
Roughly speaking, one component of a system should depend only on the type,
or the specication, of another, and not on its implementation.
This general approach works well for behavioral, or correctness, properties,
but breaks down completely for complexity, or eciency, properties. In technical
terms this is a tension between extensionality and intensionality. Extensionally,
a function is a pure I/O behavior, and has no complexity properties|it is a
mathematical function that happens to be computable. Intensionally, a function
is a program to which we may ascribe complexity|it is a piece of code to which
we may associate an extension.
Eective modularity depends crucially on the extensional viewpoint: one
programmer may work against an interface whose code does not even exist, or
may change radically over time. To minimize integration problems the assump-
tions about the other component should be concerned only with its behavior,
and not the details of its code. But understanding the eciency of a program
depends crucially on the intensional viewpoint: one must understand the code
of another component in order to assess its complexity and how it may interact
with the code in a component of interest.
Put another way, algorithms tend not to compose well. A good example is
provided by dynamic algorithms [Acar et al., 2006] whose behavior is dened
in terms of small changes" to the input, with the goal to achieve an ecient
computation of the correspondingly altered output. But unfortunately dynamic
algorithms do not compose! For example, if small" changes to the input to
the rst induce large" changes to its output (in the sense of small" dened
for the second), then the composition can be very inecient, even when the
components are very ecient.
A related example is how to specify the complexity of higher-order programs.
Consider the familiar filter function that takes a predicate (function from
the element type to the boolean type) as argument and selects from a given
list all the elements of that satisfy the predicate. It is very dicult to make
statements about the complexity of filter in general, because the behavior
of the predicate can vary wildly on each argument. We can restrict attention
to only well-behaved" predicates, which may work well for this example, but
in general when using higher-order programming it is dicult to make general
statements about the complexity of higher-order functions.
More generally, algorithms are usually evaluated as if the algorithm were the
entire program, rather than a subroutine in a larger application. The analysis is
in terms of a measure of the input (say, the number of nodes or edges of a nite
graph), and the complexity of the operations on the data structure are given in
4
2.3 รูปแบบ
วิธีสำคัญที่สุดเดียวสำหรับการควบคุมความซับซ้อนของอาคาร
ระบบซอฟต์แวร์ขนาดใหญ่คือต้นแบบ , การสลายตัวของโปรแกรมในคอม -
posable ส่วนประกอบ มากของการวิจัยในการเขียนโปรแกรมภาษาอาจ
จะเห็นเป็นความพยายามที่จะแก้ไขหลักการพื้นฐานนี้ ความเด่นของชนิด
ระบบเป็นเครื่องมือสำหรับการออกแบบภาษาลำต้นโดยตรงจาก Reynolds เป็นคำแถลง
ที่เป็นประเภทของระบบเป็นแบบสำหรับการบังคับใช้วินัยระดับนามธรรม
ประมาณพูด องค์ประกอบหนึ่งของระบบจะขึ้นอยู่เฉพาะในประเภท ,
หรือ speci ไอออนบวกของอื่น และไม่ได้อยู่ในการใช้งาน .
วิธีการทั่วไปนี้ทำงานได้ดีสำหรับพฤติกรรม หรือความถูกต้อง , คุณสมบัติ ,
แต่แบ่งลง ทั้งหมดที่ซับซ้อน หรือ E ประสิทธิภาพ คุณสมบัติ . ในทางเทคนิค
เงื่อนไขนี้เป็นแรงระหว่าง extensionality และ intensionality . extensionally
, ฟังก์ชันเป็นบริสุทธิ์ I / O พฤติกรรม และไม่มีคุณสมบัติที่ซับซ้อน | เป็น
คณิตศาสตร์ฟังก์ชันที่เกิดขึ้นจะคำนวณ . intensionally ฟังก์ชัน
เป็นโปรแกรมที่เราอาจให้เหตุผลซับซ้อน | มันเป็นชิ้นส่วนของรหัสที่
เราอาจเชื่อมโยงส่วนขยายE ective ต้นแบบขึ้นอยู่กับส่วนใหญ่ในมุมมองแบบขยาย :
โปรแกรมเมอร์อาจทำงานกับอินเตอร์เฟซที่มีรหัสไม่มีอยู่จริงหรือ
อาจเปลี่ยนแปลงอย่างรุนแรงตลอดเวลา เพื่อลดปัญหาการ assump -
ยินดีด้วยกับองค์ประกอบอื่น ๆควรจะกังวลเท่านั้นที่มีพฤติกรรม
และไม่มีรายละเอียดของรหัสของ แต่ความเข้าใจและประสิทธิภาพของโปรแกรม
ขึ้นอยู่ส่วนใหญ่ในมุมมอง intensional : ต้องเข้าใจรหัส
ส่วนประกอบอื่นเพื่อประเมินความซับซ้อนของมันและวิธีการมันอาจโต้ตอบ
กับรหัสในส่วนของดอกเบี้ย
วางวิธีอื่นและมักจะไม่เขียนดี ตัวอย่างที่ดีคือ
โดยขั้นตอนวิธีแบบไดนามิก [ รถ et al . , 2006 ] ที่มีพฤติกรรมเป็น เดอ เน็ด
ในแง่ของการเปลี่ยนแปลงเล็ก ๆ " เพื่อป้อนข้อมูลโดยมีเป้าหมายเพื่อให้บรรลุ e cient
การคำนวณการต้องกันออก แต่น่าเสียดายที่แบบไดนามิก
ขั้นตอนวิธีไม่แต่ง ! ตัวอย่างเช่น ถ้าการเปลี่ยนแปลงขนาดเล็กเพื่อป้อนให้
RST ชักจูง N ใหญ่ " การเปลี่ยนแปลงผลผลิตของตน ( ในความรู้สึกของเล็ก " เดอ เน็ด
สำหรับวินาที ) แล้วจัดองค์ประกอบได้อย่างสะดวก cient แม้เป็นส่วนประกอบมาก
e
cient .ที่เกี่ยวข้อง เช่น มีการระบุความซับซ้อนของโปรแกรม 5 .
พิจารณากรองที่ใช้ประโยคคุ้นเคยฟังก์ชัน ( ฟังก์ชันจาก
องค์ประกอบประเภทชนิดบูลีน ) เป็นอาร์กิวเมนต์และเลือกจากให้
รายการองค์ประกอบทั้งหมดที่ตรงกับภาคแสดง มันเป็นสิ่งที่ดี ศาสนาให้
งบเกี่ยวกับความซับซ้อนของตัวกรองทั่วไป เนื่องจากพฤติกรรม
ของประโยคสามารถแตกต่างกันเหยงในแต่ละอาร์กิวเมนต์ เราสามารถ จำกัด การประพฤติดีเท่านั้นที่ให้ความสนใจ
" ภาคแสดงซึ่งอาจทำงานได้ดีสำหรับตัวอย่างนี้ แต่โดยทั่วไป เมื่อใช้โปรแกรมขั้นสูง
เป็น ดิ ศาสนาเพื่อให้ทั่วไป
งบเกี่ยวกับความซับซ้อนของฟังก์ชันขั้นสูง .
มากขึ้นโดยทั่วไปและมักจะประเมินว่าถ้าอัลกอริทึมมี
โปรแกรมทั้งหมดแทนที่จะเป็น subroutine ในโปรแกรมขนาดใหญ่ โดย
ในแง่ของการวัดของข้อมูล ( เช่นจำนวนของโหนดหรือขอบของ ไนท์
กราฟ ) และความซับซ้อนของการดำเนินการในโครงสร้างข้อมูลที่ยกให้เป็น
4
การแปล กรุณารอสักครู่..
