লিস্প প্রোগ্রামাররা গর্ব করে যে লিস্প একটি শক্তিশালী ভাষা যা আদিম ক্রিয়াকলাপগুলির একটি খুব ছোট সেট থেকে তৈরি করা যায় । যাকে ডায়ালেক্ট বলা হয় তার জন্য একজন দোভাষীকে গল্ফ করে সেই ধারণাটি অনুশীলন করি tinylisp
।
ভাষার স্পেসিফিকেশন
এই স্পেসিফিকেশনে, যার ফলাফলটি "অপরিজ্ঞাত" হিসাবে বর্ণিত হয়েছে এমন কোনও শর্ত আপনার দোভাষীতে কিছু করতে পারে: ক্র্যাশ, নিঃশব্দে ব্যর্থ হওয়া, এলোমেলো গব্বলডেগুক উত্পাদন করতে পারে, বা প্রত্যাশা অনুযায়ী কাজ করতে পারে। পাইথন 3 এ একটি রেফারেন্স বাস্তবায়ন এখানে পাওয়া যায় ।
বাক্য গঠন
Tinylisp মধ্যে টোকেন হয় (
, )
অথবা প্রথম বন্ধনী বা স্থান ব্যতীত এক বা একাধিক মুদ্রণযোগ্য ASCII অক্ষর কোন স্ট্রিং। (অর্থাত্ নিম্নোক্ত রেজেক্স:। [()]|[^() ]+
) সম্পূর্ণরূপে সংখ্যার সমন্বিত কোনও টোকেন হল একটি পূর্ণসংখ্যার আক্ষরিক। (লিডিং শূন্য ঠিক আছ।) কোন টোকেন অ-সংখ্যা রয়েছে, প্রতীক এমনকি সাংখ্যিক সুদর্শন উদাহরণ পছন্দ 123abc
, 3.14
এবং -10
। টোকেনগুলি পৃথক করার কারণে ইনসোফার ব্যতীত সমস্ত সাদা স্থান (কমপক্ষে, ASCII অক্ষরগুলি সহ) উপেক্ষা করা হবে।
একটি টিনাইলিস্প প্রোগ্রামটি বিভিন্ন ধারার ভাব নিয়ে গঠিত consists প্রতিটি অভিব্যক্তি হয় হয় একটি পূর্ণসংখ্যা, প্রতীক, বা একটি এস-এক্সপ্রেশন (তালিকা)। তালিকায় শূন্য বা আরও বেশি এক্সপ্রেশন থাকে যা বন্ধনীতে আবৃত। আইটেমগুলির মধ্যে কোনও বিভাজক ব্যবহৃত হয় না। এখানে প্রকাশের উদাহরণ রয়েছে:
4
tinylisp!!
()
(c b a)
(q ((1 2)(3 4)))
যে অভিব্যক্তিগুলি সুগঠিত হয় না (বিশেষত, এর সাথে মেলে না এমন প্রথম বন্ধনী) অপরিবর্তিত আচরণ দেয়। (রেফারেন্স বাস্তবায়ন স্বয়ংক্রিয়ভাবে বন্ধন বন্ধন বন্ধ করে দেয় এবং তুলনামূলকভাবে বন্ধন বন্ধন বন্ধ করে দেয়))
তথ্যের ধরণ
টিনাইলিস্পের ডেটা ধরণগুলি হল পূর্ণসংখ্যা, চিহ্ন এবং তালিকা। অন্তর্নির্মিত ফাংশন এবং ম্যাক্রোগুলি একটি ধরণের হিসাবে বিবেচিত হতে পারে, যদিও তাদের আউটপুট ফর্ম্যাটটি অপরিজ্ঞাত। একটি তালিকাতে যে কোনও ধরণের মান সংখ্যার সমন্বয় থাকতে পারে এবং গভীরভাবে গভীরভাবে বাসা বাঁধতে পারে। কমপক্ষে -2 ^ 31 থেকে 2 ^ 31-1 পর্যন্ত পূর্ণসংখ্যার সমর্থন করা উচিত।
খালি তালিকা ()
- যেমন নীল হিসাবে উল্লেখ করা হয় - এবং পূর্ণসংখ্যা হ'ল 0
মান যা যৌক্তিকভাবে মিথ্যা বলে বিবেচিত হয়; অন্যান্য সমস্ত পূর্ণসংখ্যা, অজানা তালিকাগুলি, বিল্টইনস এবং সমস্ত চিহ্নগুলি যৌক্তিকভাবে সত্য।
মূল্যায়ন
একটি প্রোগ্রামে প্রকাশগুলি ক্রমানুসারে মূল্যায়ন করা হয় এবং প্রত্যেকের ফলাফল স্টাডাউটে প্রেরণ করা হয় (পরে আরও আউটপুট ফর্ম্যাট করার ক্ষেত্রে)।
- একটি পূর্ণসংখ্যার আক্ষরিক নিজের কাছে মূল্যায়ন করে।
- খালি তালিকা
()
নিজেই মূল্যায়ন করে। - এক বা একাধিক আইটেমের একটি তালিকা তার প্রথম আইটেমটির মূল্যায়ন করে এবং এটিকে একটি ফাংশন বা ম্যাক্রো হিসাবে বিবেচনা করে, বাকী আইটেমগুলি আর্গুমেন্ট হিসাবে কল করে। আইটেমটি কোনও ফাংশন / ম্যাক্রো না হলে, আচরণটি সংজ্ঞায়িত।
- প্রতীক বর্তমান ফাংশনটিতে সেই নামের সাথে আবদ্ধ মান প্রদান করে একটি নাম হিসাবে মূল্যায়ন করে। যদি বর্তমান ফাংশনে নামটি সংজ্ঞায়িত না করা হয় তবে এটি বৈশ্বিক সুযোগে এটির সাথে আবদ্ধ মানটির মূল্যায়ন করে। যদি নামটি বর্তমান বা বৈশ্বিক সুযোগে সংজ্ঞায়িত না করা হয়, তবে ফলাফলটি অনির্ধারিত হয় (রেফারেন্স প্রয়োগকরণ একটি ত্রুটি বার্তা দেয় এবং শূন্য করে দেয়)।
অন্তর্নির্মিত ফাংশন এবং ম্যাক্রোগুলি
টিনাইলিস্পে সাতটি অন্তর্নির্মিত কার্য রয়েছে। কোনও ক্রিয়াকলাপ তাদের কিছু ক্রিয়াকলাপ প্রয়োগ করার আগে এবং ফলাফলটি ফেরত দেওয়ার আগে এর প্রতিটি তর্ককে মূল্যায়ন করে।
c
- কনস [ট্র্যাক্ট তালিকা]। দুটি আর্গুমেন্ট, একটি মান এবং একটি তালিকা নেয় এবং তালিকার সামনের অংশে মান যুক্ত করে প্রাপ্ত একটি নতুন তালিকা প্রদান করে।h
- মাথা ( গাড়ি , লিস্প পরিভাষায়)। একটি তালিকা নেয় এবং এতে প্রথম আইটেম দেয় বা শূন্য হলে শূন্য করে।t
- লেজ ( সিডিআর , লিস্প পরিভাষায়)। একটি তালিকা নেয় এবং নতুন আইটেমটি প্রথম আইটেম ব্যতীত সমস্ত থাকে, বা শূন্য হলে শূন্য করে।s
- বিয়োগ দুটি পূর্ণসংখ্যা নেয় এবং দ্বিতীয়টি প্রথম বিয়োগ করে দেয় returnsl
- কম। দুটি পূর্ণসংখ্যা গ্রহণ করে; প্রথমটি যদি দ্বিতীয়টির চেয়ে কম হয় তবে 1 প্রদান করে otherwisee
- সমান. একই ধরণের দুটি মান গ্রহণ করে (উভয় পূর্ণসংখ্যা, উভয় তালিকা বা উভয় প্রতীক); দু'টি সমান হলে (বা প্রতিটি উপাদানে অভিন্ন) 1 প্রদান করে, অন্যথায় 0। সমতার জন্য বিল্টিনগুলি পরীক্ষা করা অপরিজ্ঞাত (রেফারেন্স বাস্তবায়ন প্রত্যাশার মতো কাজ করে)।v
- eval। একটি অভিব্যক্তি উপস্থাপন করে একটি তালিকা, পূর্ণসংখ্যা বা প্রতীক নেয় এবং তা মূল্যায়ন করে। যেমন করণ(v (q (c a b)))
করাই সমান(c a b)
;(v 1)
দেয়1
।
"মান" এখানে কোনও তালিকা, পূর্ণসংখ্যা, প্রতীক, বা অন্তর্নির্মিত অন্তর্ভুক্ত রয়েছে অন্যথায় নির্দিষ্ট না করে। যদি কোনও ফাংশন নির্দিষ্ট ধরণের গ্রহণের জন্য তালিকাভুক্ত হয় তবে বিভিন্ন ধরণের প্রেরণ করা অপরিজ্ঞাত আচরণ, যেমনটি ভুল সংখ্যার যুক্তি (রেফারেন্স বাস্তবায়ন সাধারণত ক্র্যাশ হয়) পাস করে।
টিনাইলিস্পে তিনটি অন্তর্নির্মিত ম্যাক্রো রয়েছে। কোনও ম্যাক্রো, কোনও ফাংশনের বিপরীতে, তাদের উপর ক্রিয়াকলাপ প্রয়োগের আগে তার যুক্তিগুলির মূল্যায়ন করে না।
q
- উদ্ধৃতি। একটি অভিব্যক্তি নেয় এবং এটি মূল্যহীন প্রদান করে। উদাহরণস্বরূপ, মূল্যায়ন(1 2 3)
একটি ত্রুটি দেয় কারণ এটি1
একটি ফাংশন বা ম্যাক্রো হিসাবে কল করার চেষ্টা করে তবে(q (1 2 3))
তালিকাটি ফেরত দেয়(1 2 3)
। মূল্যায়নa
নাম বাউন্ড মান দেয়a
, কিন্তু(q a)
নাম নিজেই দেয়।i
- যদি। তিনটি এক্সপ্রেশন নেয়: একটি শর্ত, একটি iftrue এক্সপ্রেশন এবং একটি iffalse এক্সপ্রেশন। প্রথমে শর্তটি মূল্যায়ন করে। ফলাফল মিথ্যা (0
বা শূন্য) হলে, মূল্যায়ন করে এবং iffalse অভিব্যক্তি প্রদান করে। অন্যথায়, মূল্যায়ন করে এবং iftrue এক্সপ্রেশনটি প্রদান করে। মনে রাখবেন যে যে এক্সপ্রেশনটি ফেরত নেই তা কখনই মূল্যায়ন হয় না।d
- Def। একটি প্রতীক এবং একটি অভিব্যক্তি লাগে। এক্সপ্রেশনকে মূল্যায়ন করে এবং বিশ্বব্যাপী সুযোগে একটি নাম হিসাবে চিহ্নিত প্রদত্ত প্রতীকে এটি আবদ্ধ করে , তারপরে প্রতীকটি প্রত্যাবর্তন করে। একটি নাম নতুন করে সংজ্ঞায়িত করার চেষ্টা করা ব্যর্থ হওয়া উচিত (নিঃশব্দে, একটি বার্তা সহ, বা ক্রাশ করে; রেফারেন্স প্রয়োগকরণ একটি ত্রুটি বার্তা প্রদর্শন করে)। দ্রষ্টব্য: নামটি পাস করার আগে নামটি উদ্ধৃত করার প্রয়োজন নেইd
, যদিও এটি তালিকা বা প্রতীক যা আপনি মূল্যায়ন করতে চান না তা যদি প্রকাশের উদ্ধৃতি দেওয়া প্রয়োজন: যেমন(d x (q (1 2 3)))
,।
কোনও ম্যাক্রোর কাছে ভুল সংখ্যার যুক্তি অতিক্রম করা অসাম্পষ্ট আচরণ (রেফারেন্স বাস্তবায়ন ক্র্যাশ)। প্রথম আর্গুমেন্ট হিসাবে প্রতীক নয় এমন কিছু পাস d
করা অপরিজ্ঞাত আচরণ (রেফারেন্স বাস্তবায়ন একটি ত্রুটি দেয় না, তবে মানটি পরবর্তীকালে উল্লেখ করা যায় না)।
ব্যবহারকারী-সংজ্ঞায়িত ফাংশন এবং ম্যাক্রোগুলি
এই দশটি বিল্ট-ইনগুলি থেকে শুরু করে, নতুন ফাংশন এবং ম্যাক্রোগুলি তৈরি করে ভাষাটি বাড়ানো যেতে পারে। এগুলির কোনও ডেডিকেটেড ডেটা টাইপ নেই; এগুলি কেবল একটি নির্দিষ্ট কাঠামোর সাথে তালিকাগুলি:
- একটি ফাংশন দুটি আইটেমের একটি তালিকা। প্রথমটি হল এক বা একাধিক প্যারামিটার নামের একটি তালিকা বা একক নাম যা ফাংশনে পাস হওয়া কোনও আর্গুমেন্টের তালিকা পাবেন (এভাবে ভেরিয়েবল-আরটি ফাংশনের অনুমতি দেয়)। দ্বিতীয়টি হল একটি এক্সপ্রেশন যা ফাংশন বডি।
- একটি ম্যাক্রো হ'ল ফাংশন হিসাবে একই, এটি প্যারামিটার নাম (গুলি) এর আগে শূন্য করে, সুতরাং এটি একটি তিন-আইটেমের তালিকা তৈরি করে। (তিনটি আইটেমের তালিকাগুলি কল করার চেষ্টা করা যা শূন্যের সাথে শুরু হয় না তা সংজ্ঞায়িত আচরণ; রেফারেন্স বাস্তবায়ন প্রথম যুক্তিকে উপেক্ষা করে এবং তাদেরকে ম্যাক্রো হিসাবেও বিবেচনা করে))
উদাহরণস্বরূপ, নিম্নলিখিত অভিব্যক্তিটি এমন একটি ফাংশন যা দুটি পূর্ণসংখ্যা যোগ করে:
(q List must be quoted to prevent evaluation
(
(x y) Parameter names
(s x (s 0 y)) Expression (in infix, x - (0 - y))
)
)
এবং একটি ম্যাক্রো যা বেশ কয়েকটি যুক্তি গ্রহণ করে এবং প্রথমটিকে মূল্যায়ন করে এবং ফেরত দেয়:
(q
(
()
args
(v (h args))
)
)
ফাংশন এবং ম্যাক্রোগুলি সরাসরি বলা যেতে পারে, ব্যবহার করে নামের সাথে আবদ্ধ d
এবং অন্যান্য ফাংশন বা ম্যাক্রোগুলিতে প্রেরণ করা যায়।
যেহেতু ফাংশন সংস্থাগুলি সংজ্ঞা সময়ে কার্যকর করা হয় না, তাই পুনরাবৃত্ত ফাংশনগুলি সহজেই সংজ্ঞাযোগ্য:
(d len
(q (
(list)
(i list If list is nonempty
(s 1 (s 0 (len (t list)))) 1 - (0 - len(tail(list)))
0 else 0
)
))
)
নোট করুন, যদিও, উপরেরটি দৈর্ঘ্যের ক্রিয়াটি সংজ্ঞায়িত করার জন্য ভাল উপায় নয় কারণ এটি ব্যবহার করে না ...
টেইল-কল পুনরাবৃত্তি
টেল-কল পুনরাবৃত্তি লিস্পে একটি গুরুত্বপূর্ণ ধারণা। এটি লুপ হিসাবে নির্দিষ্ট ধরণের পুনরাবৃত্তি প্রয়োগ করে, কল স্ট্যাককে ছোট রাখে। আপনার টিনাইলিস্প দোভাষীকে অবশ্যই যথাযথ টেল-কল পুনরাবৃত্তি প্রয়োগ করতে হবে !
- যদি কোনও ব্যবহারকারী-সংজ্ঞায়িত ফাংশন বা ম্যাক্রোর রিটার্ন এক্সপ্রেশনটি অন্য কোনও ব্যবহারকারী-সংজ্ঞায়িত ফাংশন বা ম্যাক্রোর কাছে কল হয়, আপনার দোভাষীকে সেই কলটি মূল্যায়নের জন্য পুনরাবৃত্তি ব্যবহার করা উচিত নয়। পরিবর্তে, কলের চেইনটি সমাধান না হওয়া অবধি এটি বর্তমান ফাংশন এবং যুক্তিগুলিকে নতুন ফাংশন এবং যুক্তি এবং লুপের সাথে প্রতিস্থাপন করতে হবে।
- যদি কোনও ব্যবহারকারী-সংজ্ঞায়িত ফাংশন বা ম্যাক্রোর রিটার্ন এক্সপ্রেশন কল হয়
i
তবে নির্বাচিত শাখাটি অবিলম্বে মূল্যায়ন করবেন না। পরিবর্তে, এটি অন্য কোনও ব্যবহারকারী-সংজ্ঞায়িত ফাংশন বা ম্যাক্রোর কল কিনা তা পরীক্ষা করে দেখুন। যদি তাই হয় তবে উপরের মত ফাংশন এবং যুক্তিগুলি সরিয়ে আউট করুন। এটি নির্বিচারে গভীরভাবে নেস্ট করা ঘটনাগুলিতে প্রযোজ্যi
।
টেল পুনরুক্তি সরাসরি পুনরাবৃত্তি (একটি ফাংশন নিজে কল করে) এবং অপ্রত্যক্ষ পুনরাবৃত্তি (ফাংশন a
কল ফাংশন b
যা কল করে [ইত্যাদি] যা ফাংশন কল করে) উভয়ের জন্য অবশ্যই কাজ করবে a
।
একটি পুচ্ছ পুনরাবৃত্ত দৈর্ঘ্য ফাংশন (একটি সহায়ক ফাংশন সহ len*
):
(d len*
(q (
(list accum)
(i list
(len*
(t list)
(s 1 (s 0 accum))
)
accum
)
))
)
(d len
(q (
(list)
(len* list 0)
))
)
এই প্রয়োগটি ইচ্ছামত বৃহত তালিকার জন্য কাজ করে, কেবলমাত্র সর্বোচ্চ পূর্ণসংখ্যার আকার দ্বারা সীমাবদ্ধ।
ব্যাপ্তি
ফাংশন প্যারামিটারগুলি স্থানীয় ভেরিয়েবল (আসলে ধ্রুবক, যেহেতু এগুলি সংশোধন করা যায় না)। যে ফাংশনটির সেই কলটির মূল অংশটি কার্যকর করা হচ্ছে এবং কোনও গভীর কল চলাকালীন এবং ফাংশনটি ফেরার পরে সুযোগের বাইরে রয়েছে এগুলি এগুলির মধ্যে রয়েছে। তারা বিশ্বব্যাপী সংজ্ঞায়িত নামগুলি "ছায়া" করতে পারে, যার ফলে বিশ্বব্যাপী নামটি অস্থায়ীভাবে অনুপলব্ধ হয়ে যায়। উদাহরণস্বরূপ, নিম্নলিখিত কোডটি ৪ টি নয়, ৪১ টি রিটার্ন দেয়:
(d x 42)
(d f
(q (
(x)
(s x 1)
))
)
(f 6)
যাইহোক, নিম্নলিখিত কোডটি 41 রিটার্ন দেয় কারণ x
কল স্তরে 1 কল স্তরের 2 থেকে অ্যাক্সেসযোগ্য নয়:
(d x 42)
(d f
(q (
(x)
(g 15)
))
)
(d g
(q (
(y)
(s x 1)
))
)
(f 6)
যে কোনও সময়ে সুযোগের একমাত্র নাম হ'ল) ১) বর্তমানে সম্পাদনকারী ফাংশনের স্থানীয় নাম, যদি থাকে তবে, এবং ২) বিশ্বব্যাপী নাম।
জমা দেওয়ার প্রয়োজনীয়তা
ইনপুট এবং আউটপুট
আপনার ইন্টারপ্রেটার স্ট্যান্ডিন থেকে বা স্টিডিন বা কমান্ড-লাইন আর্গুমেন্টের মাধ্যমে নির্দিষ্ট করা ফাইল থেকে প্রোগ্রামটি পড়তে পারেন। প্রতিটি অভিব্যক্তি মূল্যায়ন করার পরে, এটির প্রকাশের ফলাফলটি একটি অনুবর্তনযোগ্য নিউলাইন দিয়ে স্টাডআউটে আউটপুট করা উচিত।
- আপনার বাস্তবায়নের ভাষার সবচেয়ে প্রাকৃতিক উপস্থাপনের জন্য পূর্ণসংখ্যাগুলি আউটপুট হওয়া উচিত। নেতিবাচক পূর্ণসংখ্যার অগ্রণী বিয়োগ চিহ্ন সহ আউটপুট হতে পারে।
- প্রতীকগুলি স্ট্রিং হিসাবে আউটপুট হওয়া উচিত, কোনও আশেপাশের উদ্ধৃতি বা পলায়ন ছাড়াই।
- তালিকাগুলি সমস্ত আইটেম স্পেস-বিভক্ত এবং বন্ধনীগুলিতে আবৃত হওয়াতে আউটপুট হওয়া উচিত। বন্ধনীগুলির অভ্যন্তরের একটি স্থান alচ্ছিক:
(1 2 3)
এবং( 1 2 3 )
উভয়ই গ্রহণযোগ্য ফর্ম্যাট। - অন্তর্নির্মিত ফাংশন এবং ম্যাক্রোগুলি আউটপুটিং অপরিবর্তিত আচরণ। (রেফারেন্স ব্যাখ্যাটি তাদের হিসাবে প্রদর্শিত হয়
<built-in function>
))
অন্যান্য
রেফারেন্স ইন্টারপ্রেটারে একটি REPL পরিবেশ এবং অন্যান্য ফাইল থেকে টিনাইলিস্প মডিউল লোড করার ক্ষমতা অন্তর্ভুক্ত; এগুলি সুবিধার জন্য সরবরাহ করা হয় এবং এই চ্যালেঞ্জের জন্য প্রয়োজন হয় না।
পরীক্ষার মামলা
পরীক্ষার কেসগুলি কয়েকটি গ্রুপে বিভক্ত করা হয় যাতে আরও জটিল বিষয়গুলির আগে কাজ করার আগে আপনি আরও সহজ পরীক্ষা করতে পারেন। তবে আপনি যদি তাদের সমস্ত ফাইলকে একত্রে ডাম্প করেন তবে তারা ঠিক কাজ করবে। শিরোনামগুলি এবং চালিত হওয়ার আগে প্রত্যাশিত আউটপুটটি সরাতে ভুলবেন না।
আপনি যদি যথাযথভাবে টেল-কল পুনরাবৃত্তি প্রয়োগ করে থাকেন তবে চূড়ান্ত (বহু-অংশ) পরীক্ষার কেস স্ট্যাকের ওভারফ্লো না করে ফিরে আসবে। রেফারেন্স বাস্তবায়ন আমার ল্যাপটপে প্রায় ছয় সেকেন্ডের মধ্যে এটি গণনা করে।
-1
না থাকলেও, আমি এখনও -1 করে মান -1 তৈরি করতে পারি (s 0 1)
।
F
ফাংশন উপলভ্য নয় G
যদি F
কল G
(গতিশীল scoping মত), কিন্তু তারা ফাংশন উপলভ্য নয় H
যদি H
একটি নেস্টেড ম ফাংশন পূর্বনির্ধারণ ভিতরে F
(আভিধানিক scoping মত) - দেখতে পরীক্ষা ক্ষেত্রে 5. সুতরাং এটি কলিং "আভিধানিক "বিভ্রান্তিকর হতে পারে।