পাইথন সাজসজ্জা এবং লিস্প ম্যাক্রো


18

পাইথন সাজসজ্জার সন্ধানকারীরা যখন কেউ বিবৃতি দিয়েছিলেন যে তারা লিস্প ম্যাক্রো (বিশেষত ক্লোজার) এর মতো শক্তিশালী।

পিইপি 318 এ প্রদত্ত উদাহরণগুলির দিকে তাকালে আমার কাছে মনে হয় যেন তারা লিস্পে প্লেইন পুরাতন উচ্চতর অর্ডার ফাংশনগুলি ব্যবহার করার এক অভিনব উপায়:

def attrs(**kwds):
    def decorate(f):
        for k in kwds:
            setattr(f, k, kwds[k])
        return f
    return decorate

@attrs(versionadded="2.2",
       author="Guido van Rossum")
def mymethod(f):
    ...

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

সুতরাং, এই দু'জন কীভাবে তুলনা করে এবং আপনি কী বলতে পারেন যে তারা যা করতে পারে তার মধ্যে প্রায় সমান? প্রমাণগুলি এর বিরুদ্ধে প্রমাণিত বলে মনে হচ্ছে।

সম্পাদনা: একটি মন্তব্যের উপর ভিত্তি করে, আমি দুটি জিনিস খুঁজছি: "যত শক্তিশালী" এবং "সাথে দুর্দান্ত কাজ করা সহজ" এর সাথে তুলনা করছি।


12
অবশ্যই সাজসজ্জা বাস্তব ম্যাক্রো নয়। তারা একটি স্বেচ্ছাসেবী ভাষা (সম্পূর্ণ ভিন্ন সিনট্যাক্স সহ) পাইথনে অনুবাদ করতে পারে না। যারা উল্টো দাবি করে তারা ম্যাক্রোগুলি বুঝতে পারে না।
এসকে-যুক্তি

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

সম্ভবত আমার তখন প্রশ্নটি "এর সাথে দুর্দান্ত কাজগুলি করা সহজ" হিসাবে পরিবর্তন করা উচিত। ;)
প্রোফ্যাপাটস

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

@ ফোশি রান-টাইমে সংকলিত এএসটি পরিবর্তন করে: স্ব-সংশোধনকারী কোড হিসাবে পরিচিত ।
কাজ 1

উত্তর:


16

একটি সাজসজ্জা মূলত কেবল একটি ফাংশন

কমন লিস্পে উদাহরণ:

(defun attributes (keywords function)
  (loop for (key value) in keywords
        do (setf (get function key) value))
  function)

উপরে ফাংশনটি একটি প্রতীক (যা দ্বারা প্রত্যাবর্তিত হবে DEFUN) হয় এবং আমরা চিহ্নগুলির সম্পত্তি তালিকায় বৈশিষ্ট্যগুলি রেখেছি ।

এখন আমরা এটি একটি ফাংশন সংজ্ঞা চারপাশে লিখতে পারি:

(attributes
  '((version-added "2.2")
    (author "Rainer Joswig"))

  (defun foo (a b)
    (+ a b))

)  

যদি আমরা পাইথনের মতো অভিনব বাক্য গঠন যুক্ত করতে চাই তবে আমরা একটি পাঠক ম্যাক্রো লিখি । একটি পাঠক ম্যাক্রো আমাদের এস-এক্সপ্রেশন সিনট্যাক্সের স্তরে প্রোগ্রাম করার অনুমতি দেয়:

(set-macro-character
 #\@
 (lambda (stream char)
   (let ((decorator (read stream))
         (arg       (read stream))
         (form      (read stream)))
     `(,decorator ,arg ,form))))

আমরা তখন লিখতে পারি:

@attributes'((version-added "2.2")
             (author "Rainer Joswig"))
(defun foo (a b)
  (+ a b))

লিস্প পাঠক উপরে পড়েন:

(ATTRIBUTES (QUOTE ((VERSION-ADDED "2.2")
                    (AUTHOR "Rainer Joswig")))
            (DEFUN FOO (A B) (+ A B)))

এখন আমাদের কমন লিস্পে সাজসজ্জার একটি ফর্ম রয়েছে ।

ম্যাক্রো এবং রিডার ম্যাক্রোগুলির সংমিশ্রণ।

প্রকৃতপক্ষে আমি কোনও ফাংশন নয়, ম্যাক্রো ব্যবহার করে বাস্তব কোডে উপরের অনুবাদটি করব।

(defmacro defdecorator (decorator arg form)
  `(progn
     ,form
     (,decorator ,arg ',(second form))))

(set-macro-character
 #\@
 (lambda (stream char)
   (declare (ignore char))
   (let* ((decorator (read stream))
          (arg       (read stream))
          (form      (read stream)))
     `(defdecorator ,decorator ,arg ,form))))

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

লিস্প পাঠক উপরের উদাহরণটি এতে পড়েন:

(DEFDECORATOR ATTRIBUTES
  (QUOTE ((VERSION-ADDED "2.2")
           (AUTHOR "Rainer Joswig")))
  (DEFUN FOO (A B) (+ A B)))

যা এর পরে ম্যাক্রোতে প্রসারিত হয়:

(PROGN (DEFUN FOO (A B) (+ A B))
       (ATTRIBUTES (QUOTE ((VERSION-ADDED "2.2")
                           (AUTHOR "Rainer Joswig")))
                   (QUOTE FOO)))

ম্যাক্রোস রিডার ম্যাক্রোর থেকে খুব আলাদা ।

ম্যাক্রোগুলি উত্স কোডটি পাস হয়, তারা যা চায় তা করতে পারে এবং তারপরে উত্স কোডটি ফিরিয়ে দেয়। ইনপুট উত্সটি বৈধ লিস্প কোড হওয়ার দরকার নেই। এটি যে কোনও কিছু হতে পারে এবং এটি সম্পূর্ণ আলাদা লেখা যেতে পারে। ফলাফলটি তখন বৈধ লিস্প কোড হতে হবে। তবে উত্পন্ন কোডটি যদি ম্যাক্রোও ব্যবহার করে তবে ম্যাক্রো কলটিতে এমবেড করা কোডটির বাক্য গঠনটি আবার আলাদা সিনট্যাক্স হতে পারে। একটি সাধারণ উদাহরণ: কেউ একটি গণিত ম্যাক্রো লিখতে পারতেন যা কোনও ধরণের গাণিতিক বাক্য গঠন গ্রহণ করবে:

(math y = 3 x ^ 2 - 4 x + 3)

অভিব্যক্তিটি y = 3 x ^ 2 - 4 x + 3বৈধ লিস্প কোড নয়, তবে ম্যাক্রো উদাহরণস্বরূপ এটি বিশ্লেষণ করতে এবং বৈধ লিস্প কোডটি এর মতো ফিরে আসতে পারে:

(setq y (+ (* 3 (expt x 2))
           (- (* 4 x))
           3))

লিস্পে ম্যাক্রোর আরও অনেকগুলি ব্যবহারের ঘটনা রয়েছে।


8

পাইথনে (ভাষা) সজ্জাকারীরা ফাংশনটি সংশোধন করতে পারে না, কেবল এটি মোড়ানো করতে পারে, সুতরাং তারা লিস্প ম্যাক্রোগুলির চেয়ে অবশ্যই কম কম শক্তিশালী।

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

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


1
আপনাকে ফাংশনটি সংশোধন করার দরকার নেই। আপনাকে কেবল কোনও ফর্মের ফাংশনের কোডটি পড়তে হবে (বাস্তবে, এর অর্থ বাইকোড)। এটি এটিকে আরও ব্যবহারিক করে তোলে না।

2
@ ডেলান: প্রযুক্তিগতভাবে, লিস্প এটির কোনও পরিবর্তনও করছে না; এটি এটিকে উত্স হিসাবে একটি নতুন উত্পন্ন করার জন্য ব্যবহার করছে এবং তাই অজগর, হ্যাঁ। সমস্যাটি টোকেন তালিকা বা এএসটির অনুপস্থিতিতে এবং কম্পাইলার ইতিমধ্যে এমন কিছু জিনিস সম্পর্কে অভিযোগ করেছে যা আপনি অন্যথায় ম্যাক্রোতে অনুমতি দিতে পারেন allow
জানু হুডেক

4

নতুন নিয়ন্ত্রণ প্রবাহ প্রক্রিয়া প্রবর্তনের জন্য পাইথন সাজসজ্জার ব্যবহার করা বেশ শক্ত।

নতুন নিয়ন্ত্রণ প্রবাহ প্রক্রিয়া প্রবর্তনের জন্য কমন লিস্প ম্যাক্রোগুলি ব্যবহার করা সীমিত-তুচ্ছ।

এ থেকে সম্ভবত এটি অনুসরণ করা হয়েছে যে তারা সমানভাবে ভাববাদী নন (আমি "শক্তিশালী" কে "ভাববাদী" হিসাবে ব্যাখ্যা করতে পছন্দ করি, যেহেতু আমি মনে করি যে তারা আসলে কী বোঝায়)।


আমি সাহস করে বলিs/quite hard/impossible/

@delnan আচ্ছা, আমি যেতে হবে না বেশ যতদূর বলতে "অসম্ভব", কিন্তু আপনি স্পষ্টভাবে এটি এ কাজ করতে হবে।
ভ্যাটাইন

0

এটি অবশ্যই কার্যকরীতার সাথে সম্পর্কিত, তবে পাইথন ডেকরেটারের কাছ থেকে বলা হচ্ছে পদ্ধতিটি পরিবর্তন করা তুচ্ছ নয় (এটি fআপনার উদাহরণের প্যারামিটার হবে) be এটি সংশোধন করতে আপনি অ্যাস্টের সাথে পাগল হতে পারেন মডিউলটি ) তবে আপনি কিছু জটিল জটিল প্রোগ্রামিংয়ের জন্য যেতে চাইবেন।

এই লাইন বরাবর জিনিসগুলি সম্পন্ন হয়েছে: কিছু সত্যিকারের মন-বাঁকানো উদাহরণগুলির জন্য ম্যাক্রপি প্যাকেজটি দেখুন।


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

1
জিনিসটি হ'ল ম্যাক্রপিটি সাজসজ্জার ব্যবহার করে প্রয়োগ করা হয় না । এটি ডেকোরেটর সিনট্যাক্স ব্যবহার করে (কারণ এটি অবশ্যই একটি বৈধ পাইথন সিনট্যাক্স ব্যবহার করতে পারে) তবে এটি আমদানির হুক থেকে বাইট সংকলন প্রক্রিয়া হাইজ্যাক করে প্রয়োগ করা হয়।
জানু হুডেক

@ এসকে-যুক্তি: লিস্পে উত্স ভাষাটিও লিস্প হতে হবে। জাস্ট লিস্প সিনট্যাক্স খুব সহজ তবে নমনীয়, অন্যদিকে পাইথন সিনট্যাক্স অনেক জটিল এবং এতো নমনীয় নয়।
জানু হুডেক

1
@JanHudec, পাতার মর্মর উৎস ভাষা যে কোন থাকতে পারে (আমি সত্যিই গড়, কোন ) সিনট্যাক্স - পাঠক ম্যাক্রো দেখুন।
এসকে-যুক্তি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.