ক্লোজুর বিকাশকারীদের [বন্ধ] এড়াতে সাধারণ প্রোগ্রামিংয়ের ভুল


92

ক্লোজার ডেভেলপাররা কিছু সাধারণ ভুলগুলি কী কী এবং আমরা কীভাবে সেগুলি এড়াতে পারি?

উদাহরণ স্বরূপ; ক্লোজুরে আগত নতুনরা মনে করেন যে contains?ফাংশনটি একইভাবে কাজ করে java.util.Collection#contains। যাইহোক, contains?কেবলমাত্র মানচিত্র এবং সেটগুলির মতো সূচী সংগ্রহগুলি ব্যবহার করার সময় একইভাবে কাজ করবে এবং আপনি একটি প্রদত্ত কীটি সন্ধান করছেন:

(contains? {:a 1 :b 2} :b)
;=> true
(contains? {:a 1 :b 2} 2)
;=> false
(contains? #{:a 1 :b 2} :b)
;=> true

সংখ্যাসূচকভাবে সূচকযুক্ত সংগ্রহগুলি (ভেক্টর, অ্যারে) ব্যবহার করার সময় contains? কেবলমাত্র পরীক্ষা করা হয় যে প্রদত্ত উপাদান সূচকের বৈধ পরিসরের মধ্যে রয়েছে (শূন্য-ভিত্তিক):

(contains? [1 2 3 4] 4)
;=> false
(contains? [1 2 3 4] 0)
;=> true

যদি কোনও তালিকা দেওয়া হয় contains?তবে কখনই সত্য হয় না।


4
জাস্ট এফআইআই , যে ক্লোজার ডেভস java.util. সন্ধানের জন্য সন্ধান করছে # সংকলনে # টাইপ কার্যকারিতা রয়েছে , ক্লোজার কন্ট্রিবি.সেক-ইউটিস / অন্তর্ভুক্ত দেখুন? দস্তাবেজগুলি থেকে: ব্যবহার: (অন্তর্ভুক্ত? সংঘর্ষ x)। ট্র্যাঙ্কে লিনিয়ার সময়ে সমান কিছু (= সহ) সমান কিছু থাকলে সত্যটি ফেরত দেয়।
রবার্ট ক্যাম্পবেল

11
আপনি মনে করছেন যে এই প্রশ্নগুলি সম্প্রদায় উইকি

4
আমি পছন্দ করি কিভাবে পার্ল প্রশ্নটি অন্য সকলের সাথে ধাপের বাইরে থাকতে হবে :)
ইথার

8
ক্লোজার ডেভস কন্টেন্ট সন্ধানের জন্য, আমি র‌্যাম্পবেলের পরামর্শ অনুসরণ না করার পরামর্শ দিই। seq-utils দীর্ঘদিন থেকে অবহেলিত হয়ে গেছে এবং সেই ফাংশনটি কখনই শুরু হয় তা কার্যকর হয়নি। আপনি ক্লোজারের someফাংশন ব্যবহার করতে পারেন বা আরও ভাল, কেবল containsনিজের ব্যবহার করুন । ক্লোজার সংগ্রহগুলি বাস্তবায়ন করে java.util.Collection(.contains [1 2 3] 2) => true
রায়্ন

উত্তর:


70

শাব্দিক অক্টোবর

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

java.lang.NumberFormatException: Invalid number: 08

যা পুরোপুরি আমাকে হতবাক করেছিল। কারণটি হ'ল ক্লোজুর আক্ষরিক হিসাবে পূর্ণ শূন্যের সাথে আক্ষরিক পূর্ণসংখ্যার মানগুলি বিবেচনা করে এবং অক্টালে 08 নম্বর নেই।

আমার আরও উল্লেখ করা উচিত যে ক্লোজুর 0x উপসর্গের মাধ্যমে traditionalতিহ্যগত জাভা হেক্সাডেসিমাল মানগুলিকে সমর্থন করে । আপনি "বেস + আর + মান" স্বরলিপি ব্যবহার করে 2 এবং 36 এর মধ্যে যে কোনও বেস ব্যবহার করতে পারেন, যেমন 2r101010 বা 36r16 যা 42 বেস টেন।


একটি বেনাম ফাংশন আক্ষরিক মধ্যে আক্ষরিক ফেরত দেওয়ার চেষ্টা করা

এইটা কাজ করে:

user> (defn foo [key val]
    {key val})
#'user/foo
user> (foo :a 1)
{:a 1}

সুতরাং আমি বিশ্বাস করি এটি কাজ করবে:

(#({%1 %2}) :a 1)

তবে এতে ব্যর্থ হয়:

java.lang.IllegalArgumentException: Wrong number of args passed to: PersistentArrayMap

কারণ # () পাঠক ম্যাক্রো প্রসারিত হয়

(fn [%1 %2] ({%1 %2}))  

আদিতে প্রথম বন্ধনে আবৃত মানচিত্রের সাথে। এটি যেহেতু এটি প্রথম উপাদান, তাই এটি একটি ফাংশন হিসাবে ধরা হয় (যা আক্ষরিক মানচিত্র আসলে) তবে কোনও প্রয়োজনীয় যুক্তি (যেমন একটি কী) সরবরাহ করা হয় না। সংক্ষেপে বলা যায়, বেনামী ফাংশন আক্ষরিক নেই না প্রসারিত

(fn [%1 %2] {%1 %2})  ; notice the lack of parenthesis

এবং সুতরাং আপনার বেনামি ফাংশনের মূল হিসাবে কোনও আক্ষরিক মান ([]]: এ, 4,%) থাকতে পারে না।

মন্তব্যে দুটি সমাধান দেওয়া হয়েছে। ব্রায়ান কার্পার সিক্যুয়েন্স বাস্তবায়ন কনস্ট্রাক্টর (অ্যারে-ম্যাপ, হ্যাশ-সেট, ভেক্টর) এর মতো ব্যবহার করার পরামর্শ দেয়:

(#(array-map %1 %2) :a 1)

যখন ড্যান দেখায় যে আপনি বহিরাগত বন্ধনী আবরণে পরিচয় ফাংশনটি ব্যবহার করতে পারেন :

(#(identity {%1 %2}) :a 1)

ব্রায়ানের পরামর্শ আসলে আমার পরবর্তী ভুলের দিকে নিয়ে আসে ...


হ্যাশ-মানচিত্র বা অ্যারে-মানচিত্রের কথা চিন্তা করে অপরিবর্তনীয় কংক্রিট মানচিত্রের প্রয়োগ নির্ধারণ করে

নিম্নোক্ত বিবেচনা কর:

user> (class (hash-map))
clojure.lang.PersistentArrayMap
user> (class (hash-map :a 1))
clojure.lang.PersistentHashMap
user> (class (assoc (apply array-map (range 2000)) :a :1))
clojure.lang.PersistentHashMap

আপনি সাধারণত একটি Clojure মানচিত্রের কংক্রিট বাস্তবায়ন সম্পর্কে চিন্তা করতে হবে না হবে, আপনার যা জানা উচিত যে ফাংশন যা একটি মানচিত্র হত্তয়া - মত অ্যাসো বা সংযোগমূলক অব্যয় - একটি গ্রহণ করতে পারেন PersistentArrayMap এবং রিটার্ন একটি PersistentHashMap বৃহত্তর মানচিত্রের জন্য যা সঞ্চালিত দ্রুত,।


প্রাথমিক বাইন্ডিং সরবরাহের জন্য একটি লুপের পরিবর্তে পুনরাবৃত্তি পয়েন্ট হিসাবে কোনও ফাংশন ব্যবহার করা

যখন আমি শুরু করলাম তখন আমি এই জাতীয় প্রচুর ফাংশন লিখেছিলাম:

; Project Euler #3
(defn p3 
  ([] (p3 775147 600851475143 3))
  ([i n times]
    (if (and (divides? i n) (fast-prime? i times)) i
      (recur (dec i) n times))))

যখন লুপটি এই নির্দিষ্ট ক্রিয়াকলাপটির জন্য আরও সংক্ষিপ্ত এবং মুশকিল হত:

; Elapsed time: 387 msecs
(defn p3 [] {:post [(= % 6857)]}
  (loop [i 775147 n 600851475143 times 3]
    (if (and (divides? i n) (fast-prime? i times)) i
      (recur (dec i) n times))))

লক্ষ্য করুন যে আমি ফাঁকা আর্গুমেন্ট, "ডিফল্ট কনস্ট্রাক্টর" ফাংশন বডি (p3 775147 600851475143 3) একটি লুপ + প্রাথমিক বাঁধার সাথে প্রতিস্থাপন করেছিআবৃত্ত এখন লুপ বাইন্ডিং (Fn পরামিতি পরিবর্তে) rebinds এবং (FN পরিবর্তে লুপ,) ফিরে পুনরাবৃত্তির বিন্দু জাম্প।


রেফারেন্সিং "ফ্যান্টম" ওয়ারগুলি

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


লুপের জন্য অপরিহার্যর মতো তালিকা বোধগম্যতার জন্য চিকিত্সা করা

মূলত আপনি কেবল নিয়ন্ত্রিত লুপ সম্পাদন না করে বিদ্যমান তালিকার উপর ভিত্তি করে একটি অলস তালিকা তৈরি করছেন। Clojure এর doseq আসলে অনুজ্ঞাসূচক foreach লুপিং নির্মান আরো অনুরূপ।

তারা কীভাবে আলাদা তার একটি উদাহরণ হ'ল নির্বিচার পূর্বাভাস ব্যবহার করে কোন উপাদানগুলি পুনরাবৃত্তি করে তা ফিল্টার করার ক্ষমতা:

user> (for [n '(1 2 3 4) :when (even? n)] n)
(2 4)

user> (for [n '(4 3 2 1) :while (even? n)] n)
(4)

তারা পৃথক হওয়ার আরেকটি উপায় হ'ল তারা অসীম অলস অনুক্রমগুলিতে পরিচালনা করতে পারে:

user> (take 5 (for [x (iterate inc 0) :when (> (* x x) 3)] (* 2 x)))
(4 6 8 10 12)

তারা প্রথমে ডানদিকের এক্সপ্রেশনটির উপরে পুনরাবৃত্তি করে এবং এর বাম দিকে কাজ করে একাধিক বাঁধাইয়ের এক্সপ্রেশন পরিচালনা করতে পারে:

user> (for [x '(1 2 3) y '(\a \b \c)] (str x y))
("1a" "1b" "1c" "2a" "2b" "2c" "3a" "3b" "3c")

কোন বিরতি বা অকাল প্রস্থান অবিরত আছে।


স্ট্রাক্টের অতিরিক্ত ব্যবহার use

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

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


আনসোগার্ড বিগডিসিমাল কনস্ট্রাক্টর ব্যবহার করে

আমার প্রচুর বিগডিসিমাল দরকার ছিল এবং এটি কুৎসিত কোড লিখছিলাম:

(let [foo (BigDecimal. "1") bar (BigDecimal. "42.42") baz (BigDecimal. "24.24")]

যখন বাস্তবে ক্লোজুর এম- তে সংখ্যার সাথে যুক্ত করে বিগডিসিমাল আক্ষরিক সমর্থন করে :

(= (BigDecimal. "42.42") 42.42M) ; true

সুগারযুক্ত সংস্করণ ব্যবহার করে প্রচুর ফোলাভাব বের হয়। মন্তব্যে, যমজ উল্লেখ করেছেন যে আপনি আরও স্পষ্ট হতে বিগডেক এবং বিগিন্ট ফাংশনগুলি ব্যবহার করতে পারেন , তবুও সংক্ষিপ্ত থাকতে পারেন।


নেমস্পেসের জন্য জাভা প্যাকেজ নামকরণ রূপান্তর ব্যবহার করে

এটি আসলে প্রতি সেটের জন্য ভুল নয়, বরং এমন কিছু যা আইডিয়োমেটিক কাঠামো এবং একটি সাধারণ ক্লোজার প্রকল্পের নামকরণের বিরুদ্ধে। আমার প্রথম পর্যাপ্ত ক্লোজার প্রকল্পটির নাম স্থান ঘোষণা - এবং সংশ্লিষ্ট ফোল্ডার কাঠামো ছিল - এর মতো:

(ns com.14clouds.myapp.repository)

যা আমার সম্পূর্ণরূপে যোগ্যতাসম্পন্ন কার্যকারিতা রেফারেন্সগুলিকে ফুলে ফেঁপে উঠেছে:

(com.14clouds.myapp.repository/load-by-name "foo")

জিনিসগুলিকে আরও জটিল করার জন্য, আমি একটি স্ট্যান্ডার্ড মাভেন ডিরেক্টরি কাঠামো ব্যবহার করেছি :

|-- src/
|   |-- main/
|   |   |-- java/
|   |   |-- clojure/
|   |   |-- resources/
|   |-- test/
...

যা "স্ট্যান্ডার্ড" ক্লোজার কাঠামোর চেয়ে জটিল:

|-- src/
|-- test/
|-- resources/

এটি লিনিনজেন প্রকল্পগুলির ডিফল্ট এবং ক্লোজুরে নিজেই।


মানচিত্রগুলি কী মেলানোর জন্য ক্লোজারের = এর চেয়ে জাভার সমান () ব্যবহার করে

মূলত আইআরসি-র চৌজার দ্বারা প্রতিবেদন করা , জাভা এর সমান () এর ব্যবহারের ফলে কিছু অপ্রতিরোধ্য ফলাফল বাড়ে:

user> (= (int 1) (long 1))
true
user> ({(int 1) :found} (int 1) :not-found)
:found
user> ({(int 1) :found} (long 1) :not-found)
:not-found

যেহেতু 1 এর পূর্ণসংখ্যা এবং দীর্ঘ উভয় দৃষ্টান্তই পূর্বনির্ধারিতভাবে একই মুদ্রিত, আপনার মানচিত্র কেন কোনও মান ফেরত দেয় না তা সনাক্ত করা কঠিন। এটি বিশেষত সত্য যখন আপনি আপনার কীটি কোনও ফাংশনটির মাধ্যমে পাস করেন যা সম্ভবত আপনার অজানা, একটি দীর্ঘ সময় দেয়।

এটি লক্ষ করা উচিত যে জাভা.ইটিল.ম্যাপ ইন্টারফেসের সাথে মানচিত্রের মানচিত্রের জন্য ক্লোজারের = এর পরিবর্তে জাভার সমান () ব্যবহার করা অপরিহার্য।


আমি স্টুয়ার্ট হ্যালোয়ে দ্বারা প্রোগ্রামিং ক্লোজার, লূক ভ্যান্ডারহার্টের ব্যবহারিক ক্লোজার এবং আইআরসি- তে আমার অজস্র ক্লোজার হ্যাকার এবং আমার উত্তরগুলি সহ সহায়তা করার জন্য মেলিং তালিকা ব্যবহার করছি।


4
পাঠক ম্যাক্রোগুলির সকলেরই একটি সাধারণ ফাংশন সংস্করণ রয়েছে। আপনি (#(hash-set %1 %2) :a 1)এই ক্ষেত্রে বা করতে পারেন (hash-set :a 1)
ব্রায়ান কার্পার 21

4
আপনি পরিচয় সহ অতিরিক্ত বন্ধনীগুলি 'অপসারণ' করতে পারেন: (# (পরিচয় {% 1% 2}): একটি 1)

4
এছাড়াও আপনি ব্যবহার করতে পারে do: (#(do {%1 %2}) :a 1)
মিচা মার্সেকেক

@ মাইকেল - আমি পূর্ববর্তী বেশী যতটা এই সমাধান মত কারণ না Do যে বোঝা একটি পার্শ্ব প্রতিক্রিয়া, স্থান গ্রহণ করা হয় যখন আসলে এই এখানে ঘটনা না।
রবার্ট ক্যাম্পবেল

@ আরআরসি c সিজেড: আচ্ছা, বাস্তবে এখানে কোনও বেনামি ফাংশন ব্যবহার করার দরকার নেই, যেহেতু hash-mapসরাসরি (যেমন (hash-map :a 1)বা হিসাবে (map hash-map keys vals)) ব্যবহার করা বেশি পঠনযোগ্য এবং কোনও নির্দিষ্ট এবং অদ্যাবধি কোনও নামকৃত কার্যক্রমে অ-প্রয়োগহীন এমনটি বোঝায় না সংঘটিত হচ্ছে (যা ব্যবহারটি #(...)বোঝায় যে, আমি এটি আবিষ্কার করি)। প্রকৃতপক্ষে, বেনামে fns অতিরিক্ত ব্যবহার করা নিজের মধ্যে চিন্তা করার একটি গোঁচা। :-) ওঃও, আমি মাঝে মাঝে doঅতি-সংক্ষিপ্ত বেনামে ফাংশন ব্যবহার করি যা পার্শ্ব-প্রতিক্রিয়ামুক্ত ... এটি স্পষ্টতই প্রবণতা পায় যে এগুলি এক নজরে রয়েছে। স্বাদের বিষয়, আমি অনুমান করি।
মিচা মারকিজিক

42

অলস সিক্সগুলির মূল্যায়ন জোর করতে ভুলে যাচ্ছি

অলস বর্গগুলির মূল্যায়ন করা হয় না যদি না আপনি তাদের মূল্যায়ন করতে বলেন। আপনি এটি কিছু মুদ্রণের আশা করতে পারেন, তবে তা হয় না।

user=> (defn foo [] (map println [:foo :bar]) nil)
#'user/foo
user=> (foo)
nil

mapমূল্যায়ন করা হয় না, এটা চুপটি বাতিল হচ্ছে, কারণ এটি অলস আছে। তোমাদের মধ্যে একজন ব্যবহার করতে হবে doseq, dorun, doallপার্শ্ব প্রতিক্রিয়া জন্য অলস সিকোয়েন্স মূল্যায়ন জোর ইত্যাদি।

user=> (defn foo [] (doseq [x [:foo :bar]] (println x)) nil)
#'user/foo
user=> (foo)
:foo
:bar
nil
user=> (defn foo [] (dorun (map println [:foo :bar])) nil)
#'user/foo
user=> (foo)
:foo
:bar
nil

mapREPL এ খালি ব্যবহার করা দেখতে দেখতে যেমন কাজ করে তবে এটি কেবল কাজ করে কারণ REPL অলস সিক্সের মূল্যায়নকে নিজেরাই বাধ্য করে। এটি বাগটি লক্ষ্য করা আরও শক্ত করে তুলতে পারে, কারণ আপনার কোডটি আরপিএলে কাজ করে এবং উত্স ফাইল থেকে বা কোনও ফাংশনের অভ্যন্তরে কাজ করে না।

user=> (map println [:foo :bar])
(:foo
:bar
nil nil)

4
+1 এটি আমাকে খানিকটা, তবে আরও कपटीভাবে: আমি (map ...)ভেতর থেকে মূল্যায়ন করছিলাম (binding ...)এবং ভাবছিলাম যে কেন নতুন বাঁধাই করা মানগুলি প্রয়োগ হয় না।
অ্যালেক্স বি

20

আমি ক্লোজার নুব আরও উন্নত ব্যবহারকারীদের আরও আকর্ষণীয় সমস্যা থাকতে পারে।

অসীম অলস ক্রমগুলি মুদ্রণের চেষ্টা করছে।

আমি জানতাম যে আমি আমার অলস ধারাগুলি দিয়ে কী করছি তবে ডিবাগিংয়ের উদ্দেশ্যে আমি কিছু মুদ্রণ / প্রিন / পিআর কল sertedোকালাম, অস্থায়ীভাবে ভুলে গিয়েছিলাম আমি কী প্রিন্ট করছি। মজার বিষয়, আমার পিসি সব কেন ঝুলছে?

অত্যাবশ্যকভাবে ক্লোজারকে প্রোগ্রাম করার চেষ্টা করছি।

পুরোপুরি refএস বা atomগুলি তৈরি করতে এবং কোড লিখতে কিছু প্রলোভন রয়েছে যা নিয়মিতভাবে তাদের রাজ্যের সাথে ব্যঙ্গ করে। এটি করা যেতে পারে, তবে এটি ভাল ফিট নয়। এটিতেও খারাপ অভিনয় থাকতে পারে এবং একাধিক কোর থেকে খুব কমই উপকৃত হতে পারে।

ক্লোজুরি 100% কার্যক্রমে প্রোগ্রাম করার চেষ্টা করছি।

এটির পিছনে দিক: কিছু অ্যালগরিদম সত্যিই কিছুটা পরিবর্তনযোগ্য অবস্থা চায়। ধর্মীয়ভাবে যেকোন মূল্যে পরিবর্তনযোগ্য অবস্থা এড়ানো এর ফলে ধীর বা বিশ্রী অ্যালগরিদম হতে পারে। সিদ্ধান্ত নিতে সিদ্ধান্ত নেওয়া এবং কিছুটা অভিজ্ঞতার দরকার পড়ে।

জাভাতে খুব বেশি করার চেষ্টা করছি।

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


13

ইতিমধ্যে উল্লিখিত অনেকগুলি জিনিস। আমি কেবল আরও একটি যুক্ত করব।

জাভা বুলিয়ান অবজেক্টগুলিকে সর্বদা সত্য হিসাবে বিবেচনা করে যদি ক্লোজার মানটি মিথ্যা হয়। তাই আপনি যদি যে আয় একটি জাভা বুলিয়ান মান, মেক একটি জাভা জমি কার্যকারিতা থাকতে নিশ্চিত করুন যে আপনি এটা সরাসরি চেক করবেন না (if java-bool "Yes" "No") বরং (if (boolean java-bool) "Yes" "No")

আমি Clojure.contrib.sql লাইব্রেরি দ্বারা এটি পুড়ে গিয়েছি যা জাভা বুলিয়ান অবজেক্ট হিসাবে ডাটাবেস বুলিয়ান ক্ষেত্রগুলি ফেরত দেয়।


8
নোট যে (if java.lang.Boolean/FALSE (println "foo"))foo মুদ্রণ না। (if (java.lang.Boolean. "false") (println "foo"))যদিও, যদিও (if (boolean (java.lang.Boolean "false")) (println "foo"))না ... বেশ বিভ্রান্তিকর সত্যই!
মিশা মারকিজিক

এটি Clojure 1.4.0 তে প্রত্যাশিত হিসাবে কাজ করছে বলে মনে হচ্ছে: (দাবি (=: মিথ্যা (যদি বুলিয়ান / মিথ্যা: সত্য: মিথ্যা)))
জাকুব হল

সম্প্রতি এটি করার মাধ্যমে আমি এটির দ্বারাও জ্বলে উঠলাম (ফিল্টার: মাইকি সংঘর্ষ) যেখানে: মুলির মান যেখানে বুলিয়ানস - ক্লোজারের তৈরি সংগ্রহের সাথে প্রত্যাশার মতো কাজ করে, তবে ডিফল্ট জাভা সিরিয়ালাইজেশন ব্যবহার করে সিরিয়ালযুক্ত করার সময় ডিজাইরিয়াল সংগ্রহের সাথে নয় - কারণ সেগুলি বুলিয়ানগুলি ডিসেরায়ালাইজড নতুন বুলিয়ান () হিসাবে এবং দুঃখের সাথে (নতুন বুলিয়ান (সত্য)! = java.lang.Boolean / সত্য)
হেন্ডেকাগন

4
ক্লোজুরে বুলিয়ান মানগুলির মূল নিয়মগুলি কেবল মনে রাখবেন - nilএবং falseএটি মিথ্যা এবং অন্য সমস্ত কিছু সত্য। একটি জাভা Booleanহয় না nilএবং এটি হয় না false(কারণ এটি কোনও বস্তু), সুতরাং আচরণটি সামঞ্জস্যপূর্ণ।
এরিকপ্রাইস

13

আপনার মাথা লুপগুলিতে রাখা।
আপনি প্রথম উপাদানটির রেফারেন্স রাখার সময় যদি কোনও সম্ভাব্য খুব বড়, বা অসীম, অলস ক্রমের উপাদানগুলি লুপ করেন তবে আপনার স্মৃতিশক্তি চলে যাওয়ার ঝুঁকি রয়েছে।

ভুলে যাওয়া কোনও টিসিও নেই।
নিয়মিত টেল-কলগুলি স্ট্যাকের জায়গা গ্রাস করে এবং আপনি যদি সাবধান না হন তবে সেগুলি উপচে পড়বে। ক্লোজওর রয়েছে 'recurএবং 'trampolineএমন অনেকগুলি ক্ষেত্রে পরিচালনা করতে পারেন যেখানে অন্যান্য ভাষায় অপ্টিমাইজড টেল-কলগুলি ব্যবহৃত হত, তবে এই কৌশলগুলি ইচ্ছাকৃতভাবে প্রয়োগ করতে হবে।

বেশ-অলস ক্রমগুলি।
আপনি 'lazy-seqবা 'lazy-cons(বা উচ্চ স্তরের অলস API গুলির উপর ভিত্তি করে) একটি অলস সিকোয়েন্স তৈরি করতে পারেন, তবে আপনি যদি এটিকে আবদ্ধ করেন 'vecবা ক্রমটি উপলব্ধি করে এমন কোনও অন্য ক্রিয়াকলাপের মাধ্যমে এটি পাস করেন তবে এটি আর অলস হবে না। স্ট্যাক এবং হিপ উভয়ই এর দ্বারা ভাসমান হতে পারে।

রেফারেন্সে পরিবর্তনীয় জিনিস রাখা।
আপনি প্রযুক্তিগতভাবে এটি করতে পারেন, তবে কেবলমাত্র রেফের মধ্যে অবজেক্ট রেফারেন্সটি এসটিএম দ্বারা পরিচালিত হয় - উল্লিখিত বস্তু এবং তার ক্ষেত্রগুলি নয় (যদি না তারা অপরিবর্তনীয় হয় এবং অন্য রেফগুলিতে নির্দেশ না করে)। সুতরাং যখনই সম্ভব, কেবল রেফগুলিতে কেবল অপরিবর্তনীয় বিষয়গুলিকে পছন্দ করুন। একই জিনিস পরমাণুর জন্য যায়।


4
আসন্ন উন্নয়ন শাখা স্থানীয়ভাবে অ্যাক্সেসযোগ্য হয়ে যাওয়ার পরে কোনও ফাংশনে অবজেক্টের রেফারেন্সগুলি মুছে প্রথম আইটেমটি হ্রাস করার দিকে অনেক এগিয়ে যায়।
আর্থার আলফল্ট

9

loop ... recurমানচিত্র যখন করবে সিকোয়েন্সগুলি প্রক্রিয়া করতে ব্যবহার করে ।

(defn work [data]
    (do-stuff (first data))
    (recur (rest data)))

বনাম

(map do-stuff data)

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


4
এই দুটি সংস্করণ আসলে সমতুল্য নয়। আপনার workফাংশন সমান (doseq [item data] (do-stuff item))। (ঘটনাটি ছাড়াও, কাজের লুপটি কখনই শেষ হয় না))
কোটারাক

হ্যাঁ, প্রথমটি তার যুক্তিগুলিতে অলসতা ভঙ্গ করে। ফলস্বরূপ seq একই মান হবে যদিও এটি আর অলস Seq না।
আর্থার আলফল্ট

+1! আমি কেবলমাত্র একটি অন্য দিন খুঁজে বের করতে অসংখ্য ছোট পুনরাবৃত্ত ফাংশন লিখেছিলাম যা ব্যবহার mapএবং / অথবা দ্বারা এই সমস্তগুলি সাধারণ করা যায় reduce
মাইকে3996

5

সংগ্রহের ধরণের কিছু ক্রিয়াকলাপের জন্য বিভিন্ন আচরণ রয়েছে:

user=> (conj '(1 2 3) 4)    
(4 1 2 3)                 ;; new element at the front
user=> (conj [1 2 3] 4) 
[1 2 3 4]                 ;; new element at the back

user=> (into '(3 4) (list 5 6 7))
(7 6 5 3 4)
user=> (into [3 4] (list 5 6 7)) 
[3 4 5 6 7]

স্ট্রিংগুলির সাথে কাজ করা বিভ্রান্তিকর হতে পারে (আমি এখনও তাদের বেশিরভাগই পাই না)। বিশেষত, স্ট্রিংগুলি অক্ষরের ক্রমগুলির মতো নয়, যদিও সিক্যুয়েন্স ফাংশনগুলি তাদের উপর কাজ করে:

user=> (filter #(> (int %) 96) "abcdABCDefghEFGH")
(\a \b \c \d \e \f \g \h)

একটি স্ট্রিং ফিরে পেতে, আপনার এটি করতে হবে:

user=> (apply str (filter #(> (int %) 96) "abcdABCDefghEFGH"))
"abcdefgh"

3

অনেকগুলি প্যারান্থেসিস, বিশেষত শূন্য জাভা পদ্ধতির কল সহ যা এনপিইতে ফলাফল:

public void foo() {}

((.foo))

বহিরাগত প্যারান্থেসিস থেকে এনপিইতে ফলাফল আসে কারণ অভ্যন্তরীণ প্যারান্থিসগুলি শূন্য করতে মূল্যায়ন করে।

public int bar() { return 5; }

((.bar)) 

ডিবাগ করা সহজ ফলাফল:

java.lang.Integer cannot be cast to clojure.lang.IFn
  [Thrown class java.lang.ClassCastException]
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.