Chúng ta đã xem xét các thành phần cơ bản của một ngôn ngữ lập trình: Chúng ta đã sử dụng
các phép toán số học nguyên thủy ( + – * /), sự kết hợpcủa các phép toán này, và tính trừu tượng hóa các phép toán tổng hợp bằng cách định nghĩa chúng như là các thủ tục phức hợp. Những điều đó chưa đủ để chúng ta có thể nói rằng chúng ta biết cách để lập trình.
Một lập trình viên chuyên nghiệp cần có
Trường hợp của chúng ta tương tự như của người mới chơi cờ họ đã học được các quy tắc di chuyển của các quân cờ trong cờ vua, nhưng lại không biết gì về sự sơ hở tiến quân, chiến thuật hoặc chiến lược đánh cờ điển hình. Giống như người mới chơi cờ, chúng ta vẫn chưa biết các mô hình sử dụng phổ biến trong lập trình. Chúng ta thiếu kiến thức về những dự án và chiến lược lập trình nào đáng thực hiện (các procedures có vài trò cụ thể nào). Chúng ta thiếu kinh nghiệm để dự đoán kết quả của việc thực hiện một vài bước thay đổi hoặc lỗi tiềm tàng có thể xảy ra (trong việc thực hiện một thủ tục).
Khả năng hình dung được hậu quả của các tiến trình được xem là kĩ năng rất quan trọng để trở thành một lập trình viên chuyên nghiệp, cũng giống như trong bất kỳ hoạt động tổng hợp, sáng tạo nào. Chẳng hang, để trở thành một nhiếp ảnh gia chuyên nghiệp, bạn phải học cách nhìn một khung cảnh và biết độ tối của mỗi vùng sẽ xuất hiện trên bản in cho mỗi lựa chọn phơi sáng và điều kiện phát triển. Khi đó bạn mới có thể lý giải truy xuất ngược lại việc để có được kết quả mong muốn như lập kế hoạch đóng khung, ánh sáng, độ phơi sáng và phát triển để đạt được các hiệu ứng mong muốn.
Đối với lập trình cũng vậy, bạn lên kế hoạch cho một chuỗi các hoạt động được thực hiện bởi một quy trình và nơi bạn kiểm soát quá trình đó bằng cách cho nó vào luồng của chương trình. Để trở thành chuyên gia lập trình, chúng ta phải học cách hình dung các quá trình được tạo ra bởi các loại thủ tục khác nhau. Chỉ sau khi chúng ta phát triển một kỹ năng như vậy liệu chúng ta có thể học cách xây dựng các chương trình mạnh mẽ thể hiện hành vi như mong muốn.
Một procedure là một mô hình cho sự phát triển cục bộ của một tiến trình tính toán. Nó cụ thể hóa cách mỗi giai đoạn của tiến trình được xây dựng dựa trên giai đoạn trước đó. Chúng ta muốn làm một bảng tổng thể về các procedure, toàn cục, các hành xử của một tiến trình về sựu cải tiến có thể được cụ thể hóa bởi một procedure. Điều này nhìn chung rất khó thực hiện, nhưng ít nhất chúng ta có thể cố gắng mô tả một số mô hình điển hình của quá trình cải tiến.
Trong phần này, chúng ta sẽ xem xét một số “mô hình” phổ biến cho các quy trình được tạo ra bởi các thủ tục đơn giản. Chúng ta cũng sẽ nghiên cứu về tỉ lệ mà các quá trình này tiêu tốn nguồn lực tính toán về thời gian và bộ nhớ. Các thủ tục chúng ta sẽ xem xét rất đơn giản.
Đệ quy và quá trình lặp tuyến tính.
Chúng ta xem xét thuật toán tính giai thừa của một số như sau:
n! = n · (n − 1) · (n − 2) · · · 3 · 2 · 1.
Có nhiều cách để tính toán giai thừa của một số. Một cách phổ biến là quan sát giai thừa của một số dương bất kì là n! = n*(n-1)!;
n! = n · [(n − 1) · (n − 2) · · · 3 · 2 · 1] = n · (n − 1)!.
Hơn nữa, chúng ta tính giai thừa n! bằng giai thừa của (n-1) và nhân kết quả đó với n. Nếu chúng ta quy ước rằng 1! = 1 , và có thể chuyển thuật toán tính giai thừa thành một procedure.
(define (factorial n) (if (= n 1) 1 (* n (factorial (- n 1)))))
Chúng ta cũng có thể sử dụng mô hình thay thế để xem quy trình tính toán của 6!, như trong hình bên dưới.