শাব্দিক অক্টোবর
এক পর্যায়ে আমি একটি ম্যাট্রিক্সে পড়ছিলাম যা সঠিক সারি এবং কলামগুলি বজায় রাখতে নেতৃস্থানীয় শূন্যগুলি ব্যবহার করত। গাণিতিকভাবে এটি সঠিক, যেহেতু নেতৃত্বের শূন্য স্পষ্টতই অন্তর্নিহিত মানকে পরিবর্তন করে না। এই ম্যাট্রিক্সের সাথে কোনও ভেরি সংজ্ঞায়নের চেষ্টাগুলি অবশ্য রহস্যজনকভাবে ব্যর্থ হবে:
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})
এবং সুতরাং আপনার বেনামি ফাংশনের মূল হিসাবে কোনও আক্ষরিক মান ([]]: এ, 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 বৃহত্তর মানচিত্রের জন্য যা সঞ্চালিত দ্রুত,।
প্রাথমিক বাইন্ডিং সরবরাহের জন্য একটি লুপের পরিবর্তে পুনরাবৃত্তি পয়েন্ট হিসাবে কোনও ফাংশন ব্যবহার করা
যখন আমি শুরু করলাম তখন আমি এই জাতীয় প্রচুর ফাংশন লিখেছিলাম:
(defn p3
([] (p3 775147 600851475143 3))
([i n times]
(if (and (divides? i n) (fast-prime? i times)) i
(recur (dec i) n times))))
যখন লুপটি এই নির্দিষ্ট ক্রিয়াকলাপটির জন্য আরও সংক্ষিপ্ত এবং মুশকিল হত:
(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)
সুগারযুক্ত সংস্করণ ব্যবহার করে প্রচুর ফোলাভাব বের হয়। মন্তব্যে, যমজ উল্লেখ করেছেন যে আপনি আরও স্পষ্ট হতে বিগডেক এবং বিগিন্ট ফাংশনগুলি ব্যবহার করতে পারেন , তবুও সংক্ষিপ্ত থাকতে পারেন।
নেমস্পেসের জন্য জাভা প্যাকেজ নামকরণ রূপান্তর ব্যবহার করে
এটি আসলে প্রতি সেটের জন্য ভুল নয়, বরং এমন কিছু যা আইডিয়োমেটিক কাঠামো এবং একটি সাধারণ ক্লোজার প্রকল্পের নামকরণের বিরুদ্ধে। আমার প্রথম পর্যাপ্ত ক্লোজার প্রকল্পটির নাম স্থান ঘোষণা - এবং সংশ্লিষ্ট ফোল্ডার কাঠামো ছিল - এর মতো:
(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 এর পূর্ণসংখ্যা এবং দীর্ঘ উভয় দৃষ্টান্তই পূর্বনির্ধারিতভাবে একই মুদ্রিত, আপনার মানচিত্র কেন কোনও মান ফেরত দেয় না তা সনাক্ত করা কঠিন। এটি বিশেষত সত্য যখন আপনি আপনার কীটি কোনও ফাংশনটির মাধ্যমে পাস করেন যা সম্ভবত আপনার অজানা, একটি দীর্ঘ সময় দেয়।
এটি লক্ষ করা উচিত যে জাভা.ইটিল.ম্যাপ ইন্টারফেসের সাথে মানচিত্রের মানচিত্রের জন্য ক্লোজারের = এর পরিবর্তে জাভার সমান () ব্যবহার করা অপরিহার্য।
আমি স্টুয়ার্ট হ্যালোয়ে দ্বারা প্রোগ্রামিং ক্লোজার, লূক ভ্যান্ডারহার্টের ব্যবহারিক ক্লোজার এবং আইআরসি- তে আমার অজস্র ক্লোজার হ্যাকার এবং আমার উত্তরগুলি সহ সহায়তা করার জন্য মেলিং তালিকা ব্যবহার করছি।