Scheme ծրագրավորման լեզվում պրոցեդուրաները սահմանվում են lambda
ծառայողական բառով, որին հետևում են արգումենտների ցուցակը և պրոցեդուրայի մարմինը կազմող արտահայտությունները։ Օրինակ, կարող եմ սահմանել տրված երկու թվերի քառակուսիների գումարը հաշվող պրոցեդուրա․
(lambda (x y) (+ (* x x) (* y y)))
Սա x
և y
ֆորմալ արգումենտներով պրոցեդուրա է։ Եթե ուզենամ այն կիրառել 3
կամ 4
արգումենտների նկատմամբ, ապա պետք է գրեմ․
((lambda (x y) (+ (* x x) (* y y))) 3 4) ; => 25
Այս անհարմար գրառումից խուսափելու համար կարող եմ պրոցեդուրային անուն տալ՝ define
ծառայողական բառի օգնությամբ այն կապելով որևէ սիմվոլի հետ.
(define sum-squares (lambda (x y) (+ (* x x) (* y y))))
Եվ արդեն կարող եմ պրոցեդուրան արգումենտների նկատմամբ կիրառել sum-squares
անունով։
(sum-squares 3 4) ; => 25
Պրոցեդուրայի սահմանումն ավելի համառոտ կարելի է գրել առանց lambda
ծառայողական բառի օգտագործման՝ define
սահմանման առաջին արգումենտը դարձնելով ցուցակ, որի առաջին տարրը սահմանվող պրոցեդուրայի անունն է, իսկ հաջորդողները՝ ֆորմալ արգումենտները։ Օրինակ,
(define (sum-squares x y) (+ (* x x) (* y y)))
Ես նախնտրում եմ lambda
-ի օգտատգործմամբ տարբերակը։ Կարծում եմ, որ դա ավելի համահունչ է define
բառի հետ։
Հիմա, ենթադրենք, պետք է սահմանել պրոցեդուրա, որը իրար է գումարում տրված թվերը։ Առաջին միտքն այն է, որ սհամանել մեկ արգումենտով պրեցեդուրա և նրան փոխանցել թվերի ցուցակը։ Օրինակ այսպես.
(define sum-list (lambda (l) (if (null? l) 0 (+ (car l) (sum-list (cdr l))))))
Սա ռեկուրսիվ պրոցեդուրա է, որ 0
է վերադարձնում դատարկ ցուցակի դեպքում, իսկ ոչդատարկ ցուցակների համար ցուցակի առաջին տարրը գումարում է պոչի տարրերի գումարին։ Այս պրոցեդուրան պետք է կիրառել հետևյալ կերպ.
(sum-list '()) ; => 0 (sum-list '(1)) ; => 1 (sum-list '(1 2 3 4)) ; => 10
Բայց ավելի բնական կլիներ, եթե ես կարողանայի գրել այսպիսի արտահայտություններ.
(sum) ; => 0 (sum 1) ; => 1 (sum 1 2 3 4) ; => 10
Այլ կերպ ասած՝ ունենալ պրոցեդուրա, որի արգումենտների քանակը ֆիքսված չէ. դրանք կարող են կա՛մ բացակայել, կա՛մ լինել անորոշ քանակի։
Երբ lambda
կառուցվածքի առաջին արգումենտը տրված է որպես ատոմ (այլ ոչ թե որպես ցուցակ), ապա պրոցեդուրայի արգումենտը համարվում է անորոշ քանակի։ Օրինակ, հիշատակված sum
պրոցեդուրան, օգտագործելով sum-list
պրոցեդուրան, կարելի է սահմանել հետևյալ կերպ.
(define sum (lambda nums (sum-list nums)))
Երբ այս կերպ սահմանված պրոցեդուրան կիրառվում է արգումենտների նկատմամբ, այդ արգումենտներից կազմվում է ցուցակ և փոխանցվում է պրոցեդուրային։ Բնականաբար, պրոցեդուրայի մարմնում պետք է ֆորմալ արգումետի հետ աշխատել որպես ֆունկցիա։ Օրինակ, եթե sum
պրոցեդուրան սահմանելու լինեի առանց sum-list
պրոցեդուրայի օգտագործման, ապա պետք է գրեի.
(define sum (lambda nums (if (null? nums) 0 (+ (car nums) (apply sum (cdr nums))))))
apply
հրամանն օգտագործված է այն պատճառով, որ sum
պրոցեդուրայի ռեկուրսիվ կանչի ժամանակ (cdr nums)
ցուցակը նրան փոխանցվելու է որպես նոր ցուցակի միակ տարր։
No comments:
Post a Comment