জ্যাঙ্ক সি ++

জ্যাঙ্ক সি ++

আপনি যদি ভাবছেন যে একক দেব এক চতুর্থাংশে বিরামবিহীন সি ++ ইন্টারপের জন্য কতটা তৈরি করতে পারে তবে আপনি সন্ধান করতে চলেছেন। এপ্রিলে, জ্যাঙ্ক মোটেও সি ++ এ পৌঁছাতে অক্ষম ছিল। এই পোস্টের শেষের দিকে, আমি আজ কী কাজ করে তার কিছু বাস্তব বিশ্বের উদাহরণ দেখাব। যদিও এর আগে, আমি এই ত্রৈমাসিকে স্পনসরশিপের জন্য আপনাকে ধন্যবাদ বলতে চাই, কেবল আমার পৃথক গিটহাব স্পনসর দ্বারা নয়, ক্লোজুরিস্টদের একসাথেও। আমি আপনাকে ধন্যবাদ বলতে চাই ভ্যাসিল ভ্যাসিলিভ এবং ল্যাং হেমস জ্যাঙ্কের জন্য ক্ল্যাং এবং এলএলভিএম -এ প্রয়োজনীয় প্রযুক্তি তৈরির জন্য আসলে এই সমস্ত যাদু করার জন্য। এর মধ্যে প্রবেশ করা যাক!

মেমরি ম্যানেজমেন্ট

গত মাসে, আমি মাধ্যমে ম্যানুয়াল মেমরি ম্যানেজমেন্ট প্রয়োগ করেছি cpp/new এবং cpp/delete। এটি জ্যাঙ্কের জিসি বরাদ্দকারী (বর্তমানে বিডিডাব্লুজিসি) ব্যবহার করে পরিবর্তে ব্যবহার করে mallocসুতরাং ব্যবহার cpp/delete সাধারণত প্রয়োজন হয় না। তবে, যদি cpp/delete তারপরে ব্যবহৃত হয় মেমরি সংগ্রহটি আগ্রহী এবং আরও নির্জনবাদী হতে পারে।

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

(let (i (cpp/int. 500)
      p (cpp/new cpp/int i))
  (assert (= i (cpp/* p))))

সত্য এবং মিথ্যা

কোনও অন্তর্নিহিত জ্যাঙ্ক অবজেক্ট কাস্টিং এড়াতে আমরা এখন ব্যবহার করতে পারি cpp/true এবং cpp/falseযা সোজা আপ সি ++ বুলস। ব্যবহারের তুলনায় উত্পন্ন আইআর যতটা সম্ভব হাতা রাখার চেষ্টা করার সময় এগুলি কাজে আসে true বা false এবং জ্যাঙ্ককে ক্লোজুর ল্যান্ড থেকে সি ++ জমিতে স্বয়ংক্রিয় রূপান্তর করা। এগিয়ে যাচ্ছেন, জ্যাঙ্ক এর জন্য সমর্থন যুক্ত করবে #cpp রিডার ম্যাক্রোস, সি ++ আক্ষরিক প্রাপ্তির সহজ উপায় হিসাবে, অনুরূপ #js ক্লোজারস্ক্রিপ্টে এবং #dart ক্লোজারচার্টে।

জটিল ধরণের স্ট্রিং

সাধারণ ক্লোজুর সিনট্যাক্স ব্যবহার করে প্রচুর সম্ভাব্য ধরণের প্রতিনিধিত্ব করা সম্ভব। এই মাসে, আমি প্রতীকগুলির মধ্যে পয়েন্টার প্রকারগুলি অন্তর্ভুক্ত করার জন্য এটিও প্রসারিত করেছি। উদাহরণস্বরূপ, cpp/int** আপনাকে একটি সি ++ দেবে int ** প্রকার। যাইহোক, যখন স্পেস বা কমাগুলির প্রয়োজন হয় যেমন টেমপ্লেটগুলির সাথে, ক্লোজুরের প্রতীকগুলি খুব সীমাবদ্ধ হয়ে যায়। এই ক্ষেত্রে, আমরা এখন ব্যবহার করতে পারি (cpp/type "std::map<std::string, int>")। এটি এমন এক ধরণের মূল্যায়ন করবে যা জন্য টাইপ পজিশনে ব্যবহার করা যেতে পারে cpp/cast, cpp/newএবং তাই।

জটিল টাইপ কনস্ট্রাক্টর

নতুন কমপ্লেক্স টাইপ সিনট্যাক্সের সাথে আমরা একটি সমস্যায় পড়েছি। ক্লোজুর ব্যবহার করে ক . একটি কনস্ট্রাক্টর কল জানাতে প্রত্যয়, তবে আমরা একটি অন্তর্ভুক্ত করতে চাই না . প্রত্যয় cpp/type স্ট্রিং যেহেতু এটি বৈধ সি ++ সিনট্যাক্স নয়। এটি প্রতিকারের জন্য, জ্যাঙ্ক এখন চিকিত্সা করে . প্রকারভেদে প্রত্যয় al চ্ছিক হতে। আপনি যদি কোনও ধরণের কল করেন তবে এটি একটি কনস্ট্রাক্টর কল হিসাবে বিবেচিত হয়। প্রথমে এটি করার জন্য ক্লোজার্টার্ট চিৎকার করুন।

(let (l1 (cpp/long 5)
      l2 ((cpp/type "long") 5))
  (assert (cpp/== l1 l2)))

অস্বচ্ছ বাক্স

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

এই মাসে, আমি এর জন্য একটি কাঠামো তৈরি করেছি, যাকে বলা হয় অস্বচ্ছ বাক্সগুলি। ধারণাটি হ’ল আপনি যে কোনও কাঁচা নেটিভ পয়েন্টার নিতে পারেন এবং এটি ব্যবহার করে একটি জ্যাঙ্ক অবজেক্টে বক্স করতে পারেন cpp/box। সেখান থেকে, সেই বস্তুটি জ্যাঙ্কের ডেটা স্ট্রাকচারগুলির সাথে ব্যবহার করা যেতে পারে, চারপাশে পাস করা হয়েছে, তুলনা করে (পয়েন্টার মান অনুসারে) ইত্যাদি ইত্যাদি আপনি যখন এটিকে আবার টানতে চান, সেখানে একটি বিশেষ থাকে cpp/unbox ডেটার ধরণ নির্দিষ্ট করার সময় এটি করতে ফর্ম। এটি সি বা সি ++ এ যেমন এটি সঠিকভাবে এটি করা সম্পূর্ণ আপনার উপর নির্ভর করে। এটি দেখতে কেমন লাগে তা এখানে cpp/newকিছু ভান সি ++ কে/ভি স্টোরের জন্য। নোট করুন যে আমাদের প্রকারটি নির্দিষ্ট করার দরকার নেই cpp/boxযেহেতু সংকলকটি ইতিমধ্যে প্রকারটি জানে।

(ns example.kv)

(def db (delay (cpp/box (cpp/new cpp/my.db))))

(defn get! (k)
  (let (db (cpp/unbox cpp/my.db* @db))
    (cpp/.get db (str k))))

প্রাক-সংকলিত শিরোনাম (পিসিএইচ)

জ্যাঙ্ক রানটাইমের সাথে বিরামবিহীন সি ++ ইন্টারপের জন্য জেআইটি প্রক্রিয়া জ্যাঙ্কের সি ++ শিরোনামে ক্ল্যাং প্রয়োজন। এটি ব্যয়বহুল এবং স্টার্টআপ সময়কে প্রভাবিত করতে পারে, তাই আমি এই শিরোনামগুলির প্রাক -সংকলন সেট আপ করেছি। এটি প্রতি মেশিন করা দরকার, তাই আপনি যখন প্রথমে জ্যাঙ্ক চালান তখন জ্যাঙ্ক ইনস্টল করার পরে এটি করবে। জ্যাঙ্ক আপডেট হওয়ার সাথে সাথে এটি স্বয়ংক্রিয়ভাবে প্রয়োজন অনুযায়ী পিসিএইচটি পুনরায় সংকলন করবে।

স্থিতিশীলতা

জ্যাঙ্কের বিরামবিহীন ইন্টারপ ভাঙার উপায়গুলি খুঁজে বের করার জন্য প্রচুর কাজ চলে গেছে। সি ++ এত বড় ভাষা, আমার কাছে কয়েকশো ইন্টারপ পরীক্ষা রয়েছে। গত মাসে, আমি বিভিন্ন ক্র্যাশগুলি অ্যারে, গ্লোবাল পয়েন্টার, স্ট্যাটিক রেফারেন্স, ফাংশন পয়েন্টার, ভেরিয়াডিক সি ফাংশন কল এবং পিসিএইচএস সম্পর্কিত ক্ল্যাং এবং এলএলভিএম-সম্পর্কিত উভয় সমস্যা, আইআর অপ্টিমাইজেশন ইত্যাদি উভয়কেই দেখেছি, এটি একটি চলমান অনুসরণ, এটি ইন্টারপ টেকের রক্তপাতের প্রান্তে কীভাবে কাজ করে তা হ’ল আমি কীভাবে স্বীকৃতি তৈরি করি।

স্ট্যাটিক টাইপিং

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

অন্তরায়

আমি জ্যাঙ্ক সি ++ জিনিস করার কিছু ব্যবহারিক উদাহরণ প্রদর্শন করার আগে, দয়া করে জ্যাঙ্কের মেইলিং তালিকায় সাবস্ক্রাইব করার বিষয়টি বিবেচনা করুন। আপনি জ্যাঙ্কের রিলিজ, জ্যাঙ্ক-সম্পর্কিত আলোচনা, কর্মশালা এবং আরও অনেক কিছু নিয়ে আপ টু ডেট থাকার বিষয়টি নিশ্চিত করার সর্বোত্তম উপায় হতে চলেছে।

ব্যবহারিক উদাহরণ

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

হ্যালো ওয়ার্ল্ড মাধ্যমে স্ট্রিম

মূলত প্রতিটি সি ++ বিকাশকারী অন্তর্ভুক্ত করে শুরু হয় iostream এবং ব্যবহার std::cout। এখানে, আমাদের সম্পর্কে চিন্তা করার দরকার নেই operator << ফিরে আসা ক std::ostream& এবং এটি কোনও জ্যাঙ্ক অবজেক্টে রূপান্তরযোগ্য নয়, যেহেতু এটি বিবৃতি অবস্থানে রয়েছে। আমাদের যদি না থাকে nil ফাংশন শেষে, আমরা একটি সংকলক ত্রুটি পেতে চাই, যেহেতু জ্যাঙ্ক স্বয়ংক্রিয়ভাবে এটি বক্স করার চেষ্টা করবে std::ostream& এবং দেখতে পাবেন যে এটি করার কোনও উপায় নেই।

(cpp/raw "#include <iostream>")

(defn -main (& args)
  (cpp/<< cpp/std.cout (cpp/cast cpp/std.string "Hello, world!\n"))
  nil)

আমাদের এখনও করার ক্ষমতা নেই #cpp "Hello, world\n"একটি কাঁচা সি স্ট্রিং পেতে, তবে এটি শীঘ্রই আসছে। এটি একা প্রচুর সাধারণ স্ট্রিং ব্যবহারের ক্ষেত্রে পরিষ্কার করবে।

JSON সুন্দর প্রিন্টার

ঠিক আছে, জটিলতাটি কিছুটা ক্র্যাঙ্ক করে, আসুন একটি তৃতীয় পক্ষের গ্রন্থাগার নিয়ে আসি। আধুনিক সি ++ এর জন্য json সম্ভবত সেখানে সর্বাধিক জনপ্রিয় সি ++ জসন লাইব্রেরি রয়েছে। এটি কেবল শিরোনাম, সুতরাং আমরা যদি কেবল স্ট্যান্ডেলোন শিরোনামটি ডাউনলোড করি তবে আমরা এটি অন্তর্ভুক্ত করতে পারি। এটিকে একটি সম্পূর্ণ প্রোগ্রামে পরিণত করার জন্য, আমরাও প্রবেশ করতে পারি std::ifstream ফাইল পড়ার জন্য। এই প্রোগ্রামটি একটি জেএসএন ফাইলকে যুক্তি হিসাবে গ্রহণ করবে, এটি পার্স করবে এবং তারপরে স্টাডআউটে সুন্দর মুদ্রিত জসনকে আউটপুট করবে।

(cpp/raw "#include <fstream>")
(cpp/raw "#include \"json.hpp\"")

(defn -main (& args)
  (let (file (cpp/std.ifstream. (cpp/cast cpp/std.string (first args)))
        json (cpp/nlohmann.json.parse file))
    (println (cpp/.dump json 2))))

এই উদাহরণটি সম্পর্কে আমি যে জিনিসটি সবচেয়ে বেশি পছন্দ করি তা হ’ল আমরা কীভাবে ক্লোজুরে এবং সি ++ এর মধ্যে মূলত প্রতিটি লাইনে বুনছি। তবুও এটি সমস্ত কাজ করে।

Ftxui

আমি আরও একটি খাঁজ আপ জিনিস ক্র্যাঙ্ক করতে যাচ্ছি, যেহেতু জিনিসগুলি মজাদার হচ্ছে। এখানে একটি কার্যনির্বাহী প্রোগ্রাম যা ব্যবহার করে ftxui ফ্লেক্সবক্স ব্যবহার করে টার্মিনাল আউটপুট বের করতে। যাইহোক, ক্লোজার উপায়ে, আমরা একটি খাঁটি ডেটা হিচাপ ইন্টারফেস সরবরাহ করি এবং বাস্তবায়নটি বাকী অংশগুলি পরিচালনা করে। এখানে, আমরা অস্বচ্ছ বক্সিংয়ের সুবিধা গ্রহণ করি, জ্যাঙ্ক ফাংশনগুলির মধ্যে ftxui বস্তুগুলি সরাতে, আমরা তৈরি করি std::vector অবজেক্টস, এবং আমরা এটি পরিষ্কার করার জন্য এক টন ক্লোজুরে গুডির উপর নির্ভর করি। এত শীতল!

(cpp/raw "#include <ftxui/dom/elements.hpp>")
(cpp/raw "#include <ftxui/screen/screen.hpp>")
(cpp/raw "#include <ftxui/screen/string.hpp>")

(declare vbox)
(declare hbox)

(defn hiccup->element (h)
  (case (first h)
    :text (cpp/box (->> (str (second h))
                        cpp/ftxui.text
                        (cpp/new cpp/ftxui.Element)))
    :filler (cpp/box (cpp/new cpp/ftxui.Element (cpp/ftxui.filler)))
    :vbox (apply vbox (rest h))
    :hbox (apply hbox (rest h))))

(defmacro defbox (name f)
  `(defn ~name (& hiccup#)
     (let (elements# (cpp/ftxui.Elements.))
       (doseq (h# hiccup#)
         (let (e# (cpp/* (cpp/unbox cpp/ftxui.Element* (hiccup->element h#))))
           (cpp/.push_back elements# e#)))
       (cpp/box (cpp/new cpp/ftxui.Element (~f elements#))))))
(defbox hbox cpp/ftxui.hbox)
(defbox vbox cpp/ftxui.vbox)

(defn render-hiccup (hiccup)
  (let (document (->> (hiccup->element hiccup)
                      (cpp/unbox cpp/ftxui.Element*)
                      cpp/*)
        screen (cpp/ftxui.Screen.Create (cpp/ftxui.Dimension.Fixed 60)
                                        (cpp/ftxui.Dimension.Fixed 20)))
    (cpp/ftxui.Render screen document)
    (cpp/.Print screen)
    (println)))

(defn -main (& args)
  (render-hiccup (:vbox
                  (:hbox
                   (:text "north-west")
                   (:filler)
                   (:text "north-east"))
                  (:filler)
                  (:hbox
                   (:filler)
                   (:text "center")
                   (:filler))
                  (:filler)
                  (:hbox
                   (:text "south-west")
                   (:filler)
                   (:text "south-east")))))

তালি সম্পর্কে একটি দ্রুত নোট

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

এরপরে কী?

ভাই আমি এই কোয়ার্টারে একটি টন অর্জন করেছি এবং জ্যাঙ্ক এখন যা করতে পারে তা নিয়ে আমি অত্যন্ত সন্তুষ্ট। তবুও, বিরামবিহীন ইন্টারপের কাজটি শেষ হয়নি এবং জ্যাঙ্ক প্রকাশের আগে এতে আরও কাজ করা দরকার। একটি বড় সমস্যা হ’ল আমার কাছে স্ট্যাক বরাদ্দকৃত সি ++ অবজেক্টগুলির জন্য স্বয়ংক্রিয় ডেস্ট্রাক্টর কলগুলি মোকাবেলার সময় ছিল না। আমার একটি মেন্টি আছে, জিয়ানলিংআমরা শীঘ্রই এটি সম্পন্ন করতে পারি তা নিশ্চিত করার জন্য এখানে কাজটিতে সহায়তা করা।

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

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

আপনি সাহায্য করতে চান?

  1. সম্প্রদায়ের সাথে যোগ দিন স্ল্যাক
  2. ডিজাইন আলোচনায় যোগদান করুন বা টিকিট নিন গিরুব
  3. একটি হওয়ার কথা বিবেচনা করে স্পনসর
  4. আরও ভাল, কর্পোরেট স্পনসরশিপ নিয়ে আলোচনা করতে পৌঁছান!

Source link