ফাংশনাল প্রোগ্রামিংয়ের সাথে কনস তালিকাগুলি কেন যুক্ত?


22

আমি লক্ষ করেছি যে বেশিরভাগ কার্যকরী ভাষা তাদের একমাত্র যুক্ত লিঙ্ক তালিকা (একটি "কনস" তালিকা) তাদের সবচেয়ে মৌলিক তালিকার ধরণ হিসাবে নিয়োগ করে। উদাহরণগুলির মধ্যে রয়েছে কমন লিস্প, হাস্কেল এবং এফ #। এটি মূলধারার ভাষাগুলির থেকে পৃথক, যেখানে নেটিভ তালিকার প্রকারগুলি অ্যারে হয়।

তা কেন?

কমন লিস্পের জন্য (গতিবেগের সাথে টাইপ করা হচ্ছে) আমি ধারণা পেয়েছি যে তালগুলি, গাছ ইত্যাদির ঘাঁটি হওয়ার পক্ষেও যথেষ্ট সাধারণ ধারণা এটি খুব ছোট কারণ হতে পারে।

স্থিতিযুক্ত টাইপ করা ভাষার জন্য, যদিও আমি একটি ভাল যুক্তি খুঁজে পাই না, আমি এমনকি পাল্টা যুক্তিগুলিও খুঁজে পেতে পারি:

  • কার্যকরী শৈলী অপরিবর্তনীয়তাকে উত্সাহ দেয়, তাই লিঙ্কযুক্ত তালিকার সন্নিবেশের স্বাচ্ছন্দতা কোনও সুবিধা কম,
  • কার্যকরী শৈলী অপরিবর্তনীয়াকে উত্সাহ দেয়, তেমনি ডেটা ভাগ করে নেওয়া; একটি অ্যারে লিঙ্কযুক্ত তালিকার চেয়ে "আংশিক" ভাগ করা আরও সহজ,
  • আপনি নিয়মিত অ্যারে তেমন প্যাটার্ন ম্যাচিংও করতে পারেন, এবং আরও ভাল (আপনি উদাহরণস্বরূপ ডান থেকে বামে সহজেই ভাঁজ করতে পারেন),
  • এর উপরে আপনি নিখরচায় অ্যাক্সেস পান,
  • এবং (একটি ব্যবহারিক সুবিধা) যদি ভাষাটি স্ট্যাটিকালি টাইপ করা থাকে তবে আপনি একটি নিয়মিত মেমরি লেআউট নিয়োগ করতে পারেন এবং ক্যাশে থেকে গতি বাড়িয়ে নিতে পারেন।

তাহলে লিঙ্কযুক্ত তালিকাগুলি কেন পছন্দ করবেন?


4
@ Sepp2k এর উত্তরে মন্তব্যগুলি থেকে আসা, আমি মনে করি an array is easier to share "partially" than a linked listআপনার অর্থ কী তা সম্পর্কে স্পষ্টতা দরকার। তাদের পুনরাবৃত্তিমূলক প্রকৃতির কারণে, আমি এটি বুঝতে পারছি বলে বিপরীতটি সত্য - আপনি কোনও নোড বরাবর পাশ করে আংশিকভাবে লিঙ্কযুক্ত তালিকাটি ভাগ করে নিতে পারেন, যখন একটি অ্যারে নতুন কপি তৈরি করতে সময় ব্যয় করতে পারে। অথবা ডেটা ভাগ করে নেওয়ার ক্ষেত্রে, দুটি লিঙ্কযুক্ত তালিকাগুলি একই প্রত্যয়কে নির্দেশ করতে পারে, যা অ্যারে দিয়ে কেবল প্লেইন সম্ভব নয়।
ইজকাটা

যদি কোনও অ্যারে নিজেকে অফসেট, দৈর্ঘ্য, বাফার ট্রিপল হিসাবে সংজ্ঞায়িত করে, তবে আপনি অফসেট + 1, দৈর্ঘ্য -1, বাফার দিয়ে একটি নতুন তৈরি করে অ্যারে ভাগ করে নিতে পারেন। বা সাবহারে হিসাবে বিশেষ ধরণের অ্যারে রাখুন।
ডাবিস ভান্ডারমির

@ ইজকাটা অ্যারে সম্পর্কে কথা বলার সময়, আমরা খুব কমই কেবল একটি বাফারকে বোঝায় যেমন সিতে সংলগ্ন স্মৃতি শুরুর দিকে নির্দেশক We আমরা সাধারণত এমন কিছু কাঠামো বোঝি যা দৈর্ঘ্য এবং একটি মোড়ানো বাফার শুরুতে একটি পয়েন্টার সংরক্ষণ করে। এই জাতীয় ব্যবস্থার অধীনে, একটি স্লাইসিং অপারেশন একটি সাববারিকে ফিরিয়ে আনতে পারে, যার বাফার পয়েন্টার মাঝের দিকে বাফারে (সাব অ্যারের প্রথম উপাদানটিতে) পয়েন্ট করে এবং যার গণনাটি এমন যে শুরু + গণনা আপনাকে শেষ উপাদান দেয়। এই ধরনের কাটা অপারেশনগুলি সময় ও স্থানের ও (1)
আলেকজান্ডার - মনিকা

উত্তর:


22

সর্বাধিক গুরুত্বপূর্ণ বিষয়টি হ'ল আপনি ও (1) সময়ে একটি অপরিবর্তনীয় একক লিঙ্কযুক্ত তালিকার জন্য প্রেন্ডেন্ড করতে পারেন, যা আপনাকে ও (এন) সময়গুলিতে পুনরাবৃত্তভাবে এন-উপাদান তালিকা তৈরি করতে দেয়:

// Build a list containing the numbers 1 to n:
foo(0) = []
foo(n) = cons(n, foo(n-1))

আপনি যদি অপরিবর্তনযোগ্য অ্যারে ব্যবহার করে এটি করেন, রানটাইমটি চতুর্ভুজ হতে পারে কারণ প্রতিটি consক্রিয়াকলাপের পুরো অ্যারেটি অনুলিপি করতে হবে, যার ফলে একটি চতুর্ভুজ চলমান সময় বাড়ে।

কার্যকরী শৈলী অপরিবর্তনীয়াকে উত্সাহ দেয়, তেমনি ডেটা ভাগ করে নেওয়া; একটি অ্যারে লিঙ্কযুক্ত তালিকার চেয়ে "আংশিক" ভাগ করা সহজ

আমি "আংশিকভাবে" ভাগ করে নেওয়ার অর্থ ধরে নিচ্ছি যার অর্থ আপনি ও (1) সময়ের মধ্যে একটি অ্যারে থেকে সাবহারি নিতে পারবেন, তবে লিঙ্কযুক্ত তালিকার সাহায্যে আপনি কেবল ও (1) সময়তে লেজ নিতে পারবেন এবং সমস্ত কিছুর জন্য ও (এন) প্রয়োজন। ঐটা সত্য.

তবে অনেক ক্ষেত্রে লেজ নেওয়া যথেষ্ট। এবং আপনাকে বিবেচনা করতে হবে যে সস্তাভাবে সাবারি তৈরি করতে সক্ষম হওয়া যদি আপনাকে সস্তাভাবে অ্যারে তৈরির উপায় না থাকে তবে আপনাকে সাহায্য করে না। এবং (চতুর সংকলক অপ্টিমাইজেশন ছাড়াই) সস্তাভাবে ধাপে ধাপে কোনও অ্যারে তৈরির উপায় নেই।


এটি মোটেও সত্য নয়। আপনি মোড়কযুক্ত ও (1) এ অ্যারে যুক্ত করতে পারেন।
ডেড এমএমজি

10
@DeadMG হ্যাঁ, কিন্তু না অপরিবর্তনীয় অ্যারে।
sepp2k

"আংশিকভাবে ভাগ করা" - আমি মনে করি যে দু'টি কনস তালিকা একই প্রত্যয় তালিকার দিকে ইঙ্গিত করতে পারে (আপনি এটি কেন চান) ডান, এবং আপনি অনুলিপি ছাড়াই তালিকার শুরুটির পরিবর্তে অন্য ফাংশনে মিডপয়েন্টটি পাস করতে পারেন এটি (আমি এটি বহুবার করেছি)
ইজকাটা

@ ইজকাটা ওপি আংশিকভাবে অ্যারে ভাগ করে নেওয়ার কথা বলছিল, তালিকা নয়। আপনি কখনই আংশিক ভাগ করে নেওয়ার বিষয়টি বর্ণনা করছেন তা আমি কখনও শুনিনি । এটা শুধু ভাগ করে নেওয়া।
sepp2k

1
@ ইজকাটা ওপি "অ্যারে" শব্দটি হুবহু তিনবার ব্যবহার করেছে। একবার বলার জন্য যে এফপি ভাষাগুলি লিঙ্কযুক্ত তালিকাগুলি ব্যবহার করে যেখানে অন্যান্য ভাষাগুলি অ্যারে ব্যবহার করে। একবার বলার জন্য যে অ্যারেগুলি লিঙ্কযুক্ত তালিকার চেয়ে আংশিক ভাগ করে নেওয়ার ক্ষেত্রে ভাল এবং একবার বলার জন্য অ্যারে ঠিক তেমনি মেলানোও যেতে পারে (সংযুক্ত তালিকাগুলি হিসাবে)। সব ক্ষেত্রেই তিনি অ্যারে এবং লিঙ্কযুক্ত তালিকার বিপরীতে আছেন (বিন্দুযুক্ত তালিকার চেয়ে অ্যারে প্রাথমিক তথ্য কাঠামো হিসাবে আরও কার্যকর হবে, এটি তার প্রশ্নে নেতৃত্ব দেয় যে কেন লিঙ্কযুক্ত তালিকাগুলি এফপিতে অগ্রাধিকার দেওয়া হয়) তার ফলে আমি কীভাবে দেখছি না বিনিময়যোগ্য পদটি ব্যবহার করা যেতে পারে।
sepp2k

4

আমি মনে করি এটি কার্যকরী কোডে সহজেই প্রয়োগ করা তালিকার তালিকায় নেমে আসে।

পরিকল্পনা:

(define (cons x y)(lambda (m) (m x y)))

Haskell,:

data  [a]  =  [] | a : [a]

অ্যারেগুলি আরও কঠোর এবং প্রয়োগ করা প্রায় তত সুন্দর নয়। আপনি যদি এগুলি অত্যন্ত দ্রুত হতে চান তবে সেগুলি নিম্ন স্তরের লিখতে হবে।

অতিরিক্ত হিসাবে, পুনরাবৃত্তি অ্যারেগুলির চেয়ে তালিকায় আরও ভাল কাজ করে। আপনি অ্যারে তালিকাভুক্ত বনাম একটি তালিকা পুনরাবৃত্তভাবে কতবার / গ্রাহক করেছেন তা বিবেচনা করুন।


আমি আপনার স্কিম সংস্করণটিকে লিঙ্কিত তালিকাগুলির বাস্তবায়ন হিসাবে আখ্যায়িত করতে সঠিক বলব না। আপনি এটি ফাংশন ব্যতীত অন্য কিছু সঞ্চয় করতে ব্যবহার করতে পারবেন না। এছাড়াও অ্যারেগুলি (বা মেমরি খণ্ড) এর জন্য অন্তর্নির্মিত সমর্থন নেই এমন কোনও ভাষায় প্রয়োগ করা কঠিন (আসলে অসম্ভব), যখন লিঙ্কযুক্ত তালিকাগুলি প্রয়োগ করতে কেবল স্ট্রাক্ট, শ্রেণি, রেকর্ড বা বীজগণিত তথ্য টাইপের মতো কিছু প্রয়োজন। এটি কার্যকরী প্রোগ্রামিং ভাষার ক্ষেত্রে নির্দিষ্ট নয়।
sepp2k

@ sepp2k "ফাংশন ব্যতীত অন্য কিছু সঞ্চয় করুন" এর অর্থ কী ?
পাব্বি

1
আমার অর্থ হ'ল তালিকাগুলি যেভাবে নির্ধারিত সেগুলি কোনও ফাংশন নয় এমন কোনও জিনিস সংরক্ষণ করতে পারে না। যদিও এটি আসলে সত্য নয়। ডুনো, কেন আমি এটা ভেবেছি। এর জন্যে দুঃখিত.
sepp2k

2

এককভাবে লিঙ্কযুক্ত তালিকা হ'ল সহজ ধ্রুবক ডেটা কাঠামো

নিখুঁতভাবে কার্যকরী প্রোগ্রামিংয়ের জন্য ক্রমাগত ডেটা স্ট্রাকচার প্রয়োজনীয়।


1
এই নিছক পুনরাবৃত্তি বিন্দু তৈরি এবং ব্যাখ্যা বলে মনে হয় উপরের উত্তর যে বছর 4 বছরেরও বেশি আগে পোস্ট করা হয়েছে
মশা

3
@ গ্যানাট: শীর্ষের উত্তরটি ধ্রুবক ডেটা স্ট্রাকচারের কথা উল্লেখ করে না, বা এককভাবে সংযুক্ত তালিকাগুলি হ'ল সহজতম ধ্রুবক ডেটা কাঠামো, বা পারফরম্যান্স খাঁটি কার্যকরী প্রোগ্রামিংয়ের জন্য এগুলি প্রয়োজনীয়। আমি উপরের উত্তরটি নিয়ে কোনও ওভারল্যাপ খুঁজে পাচ্ছি না।
মাইকেল শ

2

আপনার যদি কোনও আবর্জনা সংগ্রহের ভাষা থাকে তবে আপনি সহজেই কনস নোডগুলি ব্যবহার করতে পারেন।

কনস নোডগুলি পুনরাবৃত্ত কল এবং অপরিবর্তনীয় মানগুলির কার্যকরী প্রোগ্রামিং শৈলীর সাথে অনেকগুলি মেলে। সুতরাং এটি মানসিক প্রোগ্রামার মডেল ভাল ফিট করে।

এবং historicalতিহাসিক কারণগুলি ভুলে যাবেন না। কেন তাদের এখনও কনস নোড বলা হয় এবং আরও খারাপ এখনও গাড়ি এবং সিডিআর অ্যাকসেসর হিসাবে ব্যবহার করে? লোকেরা এটি পাঠ্য বই এবং কোর্স থেকে শিখে এবং তারপরে এটি ব্যবহার করে।

আপনি ঠিক বলেছেন, বাস্তব বিশ্বে অ্যারেগুলি ব্যবহার করা অনেক সহজ, কেবলমাত্র অর্ধেক মেমরি স্পেস ব্যবহার করে এবং ক্যাশে স্তর মিস করার কারণে অনেক পারফরম্যান্টর। অপরিহার্য ভাষাগুলি ব্যবহার করার কোনও কারণ নেই।


1

লিঙ্কযুক্ত তালিকাগুলি নিম্নলিখিত কারণে গুরুত্বপূর্ণ:

একবার আপনি 3 এর মতো একটি সংখ্যা নিয়ে যান এবং এটিকে পরবর্তী উত্তরক্রমের মতো করে রূপান্তর করেন succ(succ(succ(zero)))এবং তারপরে এটির বিকল্প ব্যবহার করুন {succ=List node with some memory space}এবং{zero = end of list} , আপনি একটি লিঙ্কযুক্ত তালিকা (দৈর্ঘ্যের 3) দিয়ে শেষ করবেন।

আসল গুরুত্বপূর্ণ অংশটি সংখ্যা, প্রতিস্থাপন এবং মেমরির স্থান এবং শূন্য।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.