ক্লোজার: কনস (সিক) বনাম কনজ (তালিকা)


100

আমি জানি যে consএকটি সেক conjফিরিয়ে দেয় এবং একটি সংগ্রহ ফিরিয়ে দেয়। আমি এটিও জানি যে conjসংগ্রহটির সর্বোত্তম প্রান্তে আইটেমটি "যুক্ত" করে এবং consসর্বদা আইটেমটি সামনের দিকে "যুক্ত" করে। এই উদাহরণটি এই উভয় পয়েন্টকেই ব্যাখ্যা করে:

user=> (conj [1 2 3] 4) ; returns a collection
[1 2 3 4]
user=> (cons 4 [1 2 3]) ; returns a seq
(4 1 2 3)

ভেক্টর, মানচিত্র এবং সেটগুলির জন্য এই পার্থক্যগুলি আমার কাছে বোধগম্য। তবে তালিকার জন্য এগুলি অভিন্ন বলে মনে হচ্ছে।

user=> (conj (list 3 2 1) 4) ; returns a list
(4 3 2 1)
user=> (cons 4 (list 3 2 1)) ; returns a seq
(4 3 2 1)

conjবনাম বনাম consবিভিন্ন আচরণের প্রদর্শন করে এমন তালিকাগুলি ব্যবহার করে এমন কোনও উদাহরণ রয়েছে বা সেগুলি সত্যই বিনিময়যোগ্য? পৃথকভাবে বাক্যাংশযুক্ত, এমন কোনও উদাহরণ রয়েছে যেখানে একটি তালিকা এবং একটি সিক সমানভাবে ব্যবহার করা যায় না?

উত্তর:


153

একটি পার্থক্য হ'ল conjকোনও সংকলনে সন্নিবেশ করানোর জন্য যে কোনও সংখ্যা যুক্তি গ্রহণ করে, যখন consকেবল একটি লাগে:

(conj '(1 2 3) 4 5 6)
; => (6 5 4 1 2 3)

(cons 4 5 6 '(1 2 3))
; => IllegalArgumentException due to wrong arity

আর একটি পার্থক্য হ'ল রিটার্ন মানটির শ্রেণিতে:

(class (conj '(1 2 3) 4))
; => clojure.lang.PersistentList

(class (cons 4 '(1 2 3))
; => clojure.lang.Cons

মনে রাখবেন যে এগুলি আসলে বিনিময়যোগ্য নয়; বিশেষত, clojure.lang.Consপ্রয়োগ করে না clojure.lang.Counted, সুতরাং countএটি আর একটি ধ্রুবক সময় ক্রিয়াকলাপ নয় (এক্ষেত্রে এটি সম্ভবত হ্রাস 1 + 3 এ হবে - 1 প্রথম উপাদানটির তুলনায় লিনিয়ার ট্র্যাভার্সাল থেকে আসে, 3 (next (cons 4 '(1 2 3))একটি PersistentListএবং থেকে আসে এইভাবে Counted)।

নামগুলির পিছনে উদ্দেশ্যটি হ'ল, আমি বিশ্বাস করি, এর consঅর্থ দাঁড়ায় (সেক্রে ট্র্যাক্ট) 1 , যেখানে conjকনজ (কোনও সংকলনের উপর কোনও আইটেম) করা means দ্বারা নির্মিত seqহচ্ছে consএটি প্রথম আর্গুমেন্ট হিসাবে পাস উপাদান দিয়ে শুরু করে এবং তার next/ restঅংশ হিসাবে seqদ্বিতীয় যুক্তি প্রয়োগ থেকে ফলস্বরূপ জিনিস আছে ; উপরে প্রদর্শিত হিসাবে, পুরো জিনিস শ্রেণীর হয় clojure.lang.Cons। বিপরীতে,conj সর্বদা সংগ্রহের কাছে যেমন সংগ্রহটি যায় তেমন একই ধরণের একটি সংগ্রহ প্রদান করে। (মোটামুটিভাবে, কারণ 9 টি এন্ট্রি ছাড়িয়ে PersistentArrayMapযাওয়ার সাথে সাথে একটি রূপান্তরিত হবে PersistentHashMap))


1cons ditionতিহ্যগতভাবে , লিস্প বিশ্বে কনস (একটি যুগলকে ট্র্যাক্ট করে), তাই ক্লোজিউর লিসপ aতিহ্য থেকে তার consকার্যক্রমে একটি সেক নির্মাণের ক্ষেত্রে চলে যায় যা একটি traditionalতিহ্যবাহী নয় cdrcons"বিভিন্ন ধরণের মান একসাথে রাখার জন্য কিছু প্রকারের রেকর্ড বা অন্য রেকর্ড তৈরি করা" এর সাধারণ ব্যবহারটি বর্তমানে প্রোগ্রামিং ভাষা এবং তাদের প্রয়োগের অধ্যয়নের ক্ষেত্রে সর্বব্যাপী; "কনসোসিং এড়ানো" উল্লেখ করার সময় এর অর্থ কী।


4
কি দুর্দান্ত লেখা! কনস কনস টাইপ ছিল তা আমি জানতাম না। সাবাশ!
ড্যানিয়েল ইয়াঙ্কোভস্কি

ধন্যবাদ শুনে খুশি হলাম. :-)
মাইকেল মার্সিজিক

4
ঘটনাচক্রে, একটি বিশেষ কেস হিসাবে, (cons foo nil)একটি সিঙ্গলটন PersistentList(এবং একইভাবে conj) প্রদান করে।
মিশা মারকজেক

4
আর একটি দুর্দান্ত ব্যাখ্যা। তুমি সত্যিকার অর্থেই জাজি!
dbyrne

4
আমার অভিজ্ঞতায় তালিকাগুলিকে তালিকাগুলি হিসাবে বিবেচনা করা হয় এবং পারফরম্যান্সের ক্ষেত্রে সেকস হিসাবে গুরুত্বপূর্ণ নয়।
সিগ্র্যান্ড

11

আমার বোধগম্যতা হল আপনি যা বলছেন তা সত্য: একটি তালিকার সাথে কনজ একটি তালিকার পক্ষে সমতুল্য।

আপনি কনজকে "কোথাও somewhereোকান" অপারেশন হিসাবে এবং কনসকে "মাথায় sertোকানো" অপারেশন হিসাবে ভাবতে পারেন। একটি তালিকায়, এটি মাথায় toোকানো সর্বাধিক যৌক্তিক, সুতরাং কনজ এবং কনস এই ক্ষেত্রে সমতুল্য।


8

অন্য পার্থক্যটি হ'ল কারণ conjপ্রথম তর্ক হিসাবে ক্রম নেয় তাই কিছু সিকোয়েন্সে alterআপডেট করার সময় এটি খুব ভাল করে খেলে ref:

(dosync (alter a-sequence-ref conj an-item))

এটি মূলত (conj a-sequence-ref an-item)থ্রেড-নিরাপদ উপায়ে করে। এটি দিয়ে কাজ করবে না cons। আরও তথ্যের জন্য স্টু হ্যালোয় দ্বারা প্রোগ্রামিং ক্লোজারে কনকুরেন্সির উপর অধ্যায়টি দেখুন ।


2

আরেকটি পার্থক্য তালিকার আচরণ?

(list? (conj () 1)) ;=> true
(list? (cons 1 ())) ; => false

4
কনস সর্বদা একটি ক্রম প্রদান করে যা কনজ সরবরাহিত একই ধরণের ফেরত দেয়
নিং সান

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