এই অনুশীলনীতে শর্ত নিয়ে আলোচনা করা হয়েছে, অর্থাৎ একটি মানের ভিত্তিতে দুই বা ততোধিক কর্মপন্থার মধ্যে একটি বেছে নেওয়া। এটি Annalyn's Infiltration অনুশীলনীতে আপনার দেখা বুলিয়ান এবং Currency Conversion অনুশীলনীর ইন্টিজার পাটিগণিতের উপর ভিত্তি করে গড়ে উঠেছে।
এগুলো সবই math ভোকাবুলারিতে থাকে (=-এর জন্য kernel ভোকাবুলারিতে):
= ( x y -- ? ) ! equal
< ( x y -- ? ) ! less than
<= ( x y -- ? ) ! less than or equal
> ( x y -- ? ) ! greater than
>= ( x y -- ? ) ! greater than or equal
3 3 = . ! => t
2 3 < . ! => t
3 3 <= . ! => t
3 4 = not . ! => t (inequality: combine = with not)
zero? (math ভোকাবুলারিতে) হলো কমন 0 = পরীক্ষার একটি সংক্ষিপ্ত রূপ, এটি সংখ্যাটি গ্রহণ করে এবং সেটি শূন্য ছিল কি না তা পুশ করে:
zero? ( n -- ? ) ! t when n is 0
between? (math.order ভোকাবুলারিতে) পরীক্ষা করে একটি মান কোনো সীমা-অন্তর্ভুক্ত রেঞ্জের মধ্যে পড়ে কি না। কোনো কাজ একটি সংখ্যা কোন ব্যান্ডে পড়ে তার উপর নির্ভর করলে এটি সুবিধাজনক:
between? ( x lo hi -- ? ) ! lo <= x <= hi (inclusive)
5 1 10 between? . ! => t
0 1 10 between? . ! => f
10 1 10 between? . ! => t (inclusive at both ends)
এটি সাধারণত cond প্রেডিকেট হিসেবে দেখতে পাবেন, যেমন dup 1 4 between?, যেখানে একটি মানের বদলে রেঞ্জ ধরে শাখা বেছে নেওয়া হয়।
উপরের তুলনার শব্দগুলো বুলিয়ান তৈরি করে; কোনো বুলিয়ানের উপর কাজ করতে হলে সেই শর্তভিত্তিক শব্দটিকে এক বা একাধিক কোটেশন দিতে হয়। একটি কোটেশন হলো বর্গাকার বন্ধনীতে মোড়া কোডের একটি ছোট টুকরা, [ ... ]। এটি লিখলে কোডটি রান হওয়ার বদলে স্ট্যাকের উপর একটি মান হিসেবে পুশ হয়, তারপর if-এর মতো শব্দ ঠিক করে কোন কোটেশনটি রান করবে।
[ neg ] ! a quotation that negates the top of the stack
[ ] ! the empty quotation — does nothing
পরের একটি অনুশীলনীতে কোটেশন নিয়ে বিস্তারিত আলোচনা আছে; আপাতত [ ... ] মানে হলো "এই শাখার জন্য রান করার কোড"।
if, when, unless
if (kernel ভোকাবুলারিতে) একটি বুলিয়ান এবং দুটি কোটেশন নেয়। বুলিয়ানটি ট্রুথি হলে এটি প্রথম কোটেশনটি রান করে, আর ফলসি হলে দ্বিতীয়টি:
if ( ? then-quot else-quot -- )
: abs ( x -- y ) dup 0 < [ neg ] [ ] if ;
when কেবল তখনই তার কোটেশন রান করে যখন বুলিয়ানটি ট্রুথি; আর unless কেবল তখনই যখন সেটি ফলসি:
when ( ? quot -- )
unless ( ? quot -- )
if*, when* এবং unless*
কার্নেলের তিনটি ভ্যারিয়েন্ট বুলিয়ানটিকে এমন একটি মান হিসেবে ধরে, যা ট্রুথি হলে রেখে দেওয়া যায়, অর্থাৎ যখন কোনো শব্দ "জিনিসটি, নাহলে f" ফেরত দেয় তখন এটি কাজে লাগে:
if* ( ? true false -- ) ! truthy: true is called WITH ? on stack
when* ( ? true -- ) ! truthy: true is called WITH ? on stack
unless* ( ? false -- ) ! falsy: false runs and pushes a default
if* হলো দুই-শাখার রূপ। ট্রুথি শাখাটি কল করা হয় এমনভাবে যে মানটি তখনও স্ট্যাকে থাকে; আর ফলসি শাখাটি কল করা হয় মানটি ছাড়াই:
42 [ ] [ "nothing" ] if* . ! prints 42
f [ ] [ "nothing" ] if* . ! prints "nothing"
unless* হলো "মান, নাহলে ডিফল্ট" এই প্রচলিত ইডিয়মের আদর্শ রূপ। মানটি ট্রুথি হলে সেটি অপরিবর্তিত থাকে; আর যদি সেটি f হয়, তবে মানটি ফেলে দেওয়া হয় এবং কোটেশনটি রান হয়ে একটি বিকল্প মান পুশ করে:
"hello" [ "anonymous" ] unless* . ! => "hello"
f [ "anonymous" ] unless* . ! => "anonymous"
when* হলো if*-এর এক-শাখার রূপ: মানটি ট্রুথি হলেই এটি তার কোটেশনটি রান করে, আর তখন মানটি স্ট্যাকে থাকে; মানটি f হলে এটি কেবল মানটি ফেলে দেয়। "জিনিসটি, নাহলে f" ধরনের ফলাফলকে f-এর কেস আলাদা করে সামলানোর ঝামেলা ছাড়াই একটি চলমান মানের সঙ্গে জুড়ে দিতে এটিই বেছে নিন:
0 41 [ + ] when* . ! => 41 (truthy: 41 added to the running total)
0 f [ + ] when* . ! => 0 (falsy: f dropped, total left untouched)
condআপনার যখন বেছে নেওয়ার জন্য একাধিক বিকল্প কাজ থাকে, তখন cond (combinators ভোকাবুলারিতে) স্বাভাবিক পছন্দ। এটি { predicate body } জোড়ার একটি অ্যারে নেয় এবং যে প্রথম প্রেডিকেটটি ট্রুথি মান দেয়, তার বডিটি রান করে:
USING: combinators ;
: classify ( n -- label )
{
{ [ dup 0 < ] [ drop "negative" ] }
{ [ dup 0 = ] [ drop "zero" ] }
[ drop "positive" ]
} cond ;
কয়েকটি বিষয় খেয়াল করার মতো:
dup ... <test> হলো প্রচলিত ইডিয়ম।drop করে ফলাফল পুশ করার মধ্য দিয়ে শুরু করে।এই অনুশীলনীতে আপনি একটি গাড়ির কারখানার অ্যাসেম্বলি লাইনের উৎপাদন বিশ্লেষণ করার কোড লিখবেন। অ্যাসেম্বলি লাইনের গতি 0 (বন্ধ) থেকে 10 (সর্বোচ্চ) পর্যন্ত হতে পারে।
এর সর্বনিম্ন অশূন্য গতিতে (1), প্রতি ঘণ্টায় 221টি গাড়ি উৎপাদিত হয়। গতি বাড়ার সাথে সাথে উৎপাদন রৈখিকভাবে বাড়ে, তাই 4 গতিতে লাইনটি প্রতি ঘণ্টায় 4 * 221 = 884টি গাড়ি উৎপাদন করে। তবে বেশি গতি ত্রুটিপূর্ণ গাড়ি উৎপাদনের সম্ভাবনা বাড়িয়ে দেয়, যেগুলোকে পরে বাদ দিতে হয়।
আপনার সামনে চারটি কাজ আছে। প্রতিটি কাজ স্ট্যাক থেকে একটি ইন্টিজার প্যারামিটার নেয়, যেটি হলো অ্যাসেম্বলি লাইনের গতি।
production-status ডিফাইন করুন যাতে গতি 0 হলে "stopped" রিটার্ন করে এবং অন্য যেকোনো গতির জন্য "running" রিটার্ন করে:
0 production-status .
! => "stopped"
3 production-status .
! => "running"
success-rate ডিফাইন করুন যাতে ত্রুটি ছাড়া একটি পণ্য উৎপাদিত হওয়ার সম্ভাবনা রিটার্ন করে:
0: 0.0
1 থেকে 4: 1.0
5 থেকে 8: 0.9
9: 0.8
10: 0.77
10 success-rate .
! => 0.77
production-rate-per-hour ডিফাইন করুন যাতে সফলতার হার হিসাবের মধ্যে নিয়ে অ্যাসেম্বলি লাইনের প্রতি ঘণ্টার উৎপাদন হার রিটার্ন করে।
এর জন্য প্রথমে base-speed ডিফাইন করতে হবে, যেটি ধ্রুবক 221।
6 production-rate-per-hour .
! => 1193.4
রিটার্ন করা মানটি ফ্লোট ধরনের।
working-items-per-minute ডিফাইন করুন যাতে রিটার্ন করে প্রতি মিনিটে কতটি সচল গাড়ি উৎপাদিত হয়। ফলাফলটি একটি ইন্টিজার, আংশিক গাড়ি গণনা করা হয় না।
6 working-items-per-minute .
! => 19
Exercism-এ সাইন আপ করুন, Factor ট্র্যাকের 47টি কনসেপ্ট163টি অনুশীলনী আর সত্যিকারের মানুষের মেন্টরিং দিয়ে শিখুন ও দক্ষ হয়ে উঠুন, সম্পূর্ণ বিনামূল্যে।