কমন লিস্পে `সেট`,` সেতকি এবং `সেটফের মধ্যে পার্থক্য?


166

কমন লিস্পে "সেট", "সেটকি" এবং "সেটফ" এর মধ্যে পার্থক্য কী?


9
এর আচরণগুলির উত্তরে উত্তম উত্তর দেওয়া হয় তবে স্বীকৃত উত্তরের "সেট" এর "এফ" এর জন্য সম্ভবত ভুলভাবে ব্যুৎপত্তি রয়েছে। সেফ এফ এর উত্তর কী? এটি "ফাংশন" এর জন্য বলে এবং এটি ব্যাক আপ করার জন্য রেফারেন্স সরবরাহ করে।
জোশুয়া টেলর

উত্তর:


169

মূলত, লিস্পে, কোনও লেজিকাল ভেরিয়েবল ছিল না - কেবল গতিশীল। এবং সেখানে কোনও এসইটিকিউ বা এসইটিএফ ছিল না, কেবল এসইটি ফাংশন ছিল।

এখন যা লেখা আছে:

(setf (symbol-value '*foo*) 42)

লিখেছিলেন:

(set (quote *foo*) 42)

যা অবশেষে SETQ (SET উদ্ধৃত) এর সংক্ষিপ্তসার হয়েছিল:

(setq *foo* 42)

তারপরে লেক্সিকাল ভেরিয়েবলগুলি ঘটেছিল এবং সেটকিউ তাদের কাছেও নিয়োগের জন্য ব্যবহৃত হয়েছিল - সুতরাং এটি আর সেটের চারপাশে কোনও সাধারণ মোড়কের মতো ছিল না।

পরে, অন্য কোনও ভাষার এল-মানগুলি আয়নাতে ডেটা স্ট্রাকচারগুলিকে মান নির্ধারণের জেনেরিক উপায় হিসাবে কেউ এসইটিএফ (এসইটি ফিল্ড) আবিষ্কার করেছিলেন:

x.car := 42;

হিসাবে লেখা হবে

(setf (car x) 42)

প্রতিসাম্যতা এবং সাধারণতার জন্য, এসইটিএফও এসইটিকিউর কার্যকারিতা সরবরাহ করে। এই মুহুর্তে এটি বলা ঠিক হবে যে SETQ একটি নিম্ন-স্তরের আদিম, এবং SETF একটি উচ্চ-স্তরের অপারেশন ছিল।

তারপরে প্রতীক ম্যাক্রোস ঘটেছে। যাতে প্রতীক ম্যাক্রোগুলি স্বচ্ছতার সাথে কাজ করতে পারে, এটি উপলব্ধি করা হয়েছিল যে "ভেরিয়েবল" নির্ধারিত সত্যই যদি একটি প্রতীক ম্যাক্রো হয়ে থাকে তবে SETQ কে SETF এর মতো কাজ করতে হবে:

(defvar *hidden* (cons 42 42))
(define-symbol-macro foo (car *hidden*))

foo => 42

(setq foo 13)

foo => 13

*hidden* => (13 . 42)

সুতরাং আমরা বর্তমান সময়ে পৌঁছেছি: এসইটি এবং এসইটিকিউ পুরানো উপভাষাগুলির অবশেষ রয়েছে, এবং সম্ভবত কমন লিস্পের পরবর্তী উত্তরসূরিদের কাছ থেকে শুরু করা হবে।


45
কমন লিস্পে সর্বদা লেক্সিক ভেরিয়েবল থাকে। কমন লিস্পের আগে আপনি অবশ্যই কিছু লিস্প সম্পর্কে কথা বলছেন।
রেনার জোসভিগ

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

13
এমন কোনও কিছুর কারণ রয়েছে যে আপনি কোনও গাড়ীকে ক্ষেত্র হিসাবে বেছে নিয়েছিলেন যা গাড়ী ফাংশন হিসাবে বিভ্রান্ত হতে পারে?
ড্রড্রু

9
এই উত্তরটি করার কি জন্য setf স্ট্যান্ড মধ্যে চ করে? যে দাবি fআসলে ঘোরা ফাংশন , না ক্ষেত্র (অথবা ফর্ম , যে বিষয়টি জন্য), এবং রেফারেন্স প্রদান করে, তাই যখন ক্ষেত্রের জন্য setf কিছু জ্ঞান করে তোলে, এটা দেখে মনে হচ্ছে এটি সঠিক নাও হতে পারে।
জোশুয়া টেলর

1
সংক্ষিপ্তসার: setএকটি ফাংশন। এভাবে এটি পরিবেশ জানে না। setলেক্সিকাল ভেরিয়েবল দেখতে পাচ্ছে না। এটি তার যুক্তিটির প্রতীক-মানটি সেট করতে পারে। setqআর "সেট কোটড" নেই। setqম্যাক্রো নয় এটি একটি বিশেষ রূপ যা সত্য তা দেখায়।
কিম তাইগুন

142
(set ls '(1 2 3 4)) => Error - ls has no value

(set 'ls '(1 2 3 4)) => OK

(setq ls '(1 2 3 4)) => OK - make ls to (quote ls) and then have the usual set

(setf ls '(1 2 3 4)) => OK - same as setq so far BUT

(setf (car ls) 10) => Makes ls '(10 2 3 4) - not duplicated by setq/set

12
আমি আপনার উত্তরটি শীর্ষ ভোটদানের চেয়ে বেশি পরিষ্কার বলে মনে করি। অনেক ধন্যবাদ.
সিডিআর

2
@ সৌরভ, অনুগ্রহ করে উদাহরণস্বরূপ কোডের পরিবর্তক বা চিহ্ন হিসাবে "l" (ell) অক্ষরটি কখনও ব্যবহার করবেন না।
অংকটি

না, আমি এখনও বুঝতে পারি না (কার এলএস) কীভাবে এল-মান হতে পারে বা নাও হতে পারে। আপনি কী বুঝতে পারেন কীভাবে সিপ্লিপ সিতে অনুবাদ করবেন? এবং কিভাবে একটি ক্লিপ ইন্টারপ্রেটার লিখতে?
reuns

@ user1952009 ক্লিপ্প একটি সাধারণ লিস্প বাস্তবায়ন implementation আপনি যদি ভাষাটি নিজেই উল্লেখ করতে চান তবে সর্বাধিক ব্যবহৃত সংক্ষিপ্তসার সিএল করুন।
ssice

2
@ ব্যবহারকারী1952009 এর পরে (setq ls '(((1)))), অপরিবর্তিত (setf (car (car (car ls))) 5)আচরণ, কারণ এর মান lsধ্রুবক ( সিটিতে একটি স্ট্রিং আক্ষরিক সংশোধন করার মতো)। এরপরে (setq ls (list (list (list 1)))), সি এর (setf (car (car (car ls))) 5)মতোই কাজ করেls->val->val->val = 5
কাইল

21

setqশুধু ভালো হয় setএকটি উদ্ধৃত প্রথম ARG সাথে - (set 'foo '(bar baz))ঠিক মত হল (setq foo '(bar baz))setfঅন্যদিকে, সত্যই এটি সূক্ষ্ম - এটি একটি "দিকনির্দেশনা" এর মতো। আমি এখানে প্রস্তাব দেওয়া যে কোনও উত্তর দিতে পারে তার চেয়ে বেশি ভালো উপায় হিসাবে http://www.nano.com/lisp/cmucl-tutorials/LISP-tutorial-16.html পরামর্শ দেওয়ার পরামর্শ দিচ্ছি ... সংক্ষেপে, যদিও setfগ্রহণ করে "রেফারেন্স" হিসাবে প্রথম যুক্তি, যাতে উদাহরণস্বরূপ অ্যারের ভিতরে একটি আইটেম সেট (aref myarray 3)করতে (প্রথম আর্গ হিসাবে setf) কাজ করবে ।


1
সেটেক নামের জন্য সর্বাধিক জ্ঞান অর্জন করে। মনে রাখা সহজ। ধন্যবাদ।
সিডিআর

17

আপনি setfএর পরিবর্তে setবা এর পরিবর্তে ব্যবহার করতে পারেন setqযেহেতু setfভেরিয়েবলের পৃথক উপাদান থাকে তবে একটি ভেরিয়েবলের পৃথক উপাদানগুলির মানও সেট করতে পারে। নীচের এক্সপেলগুলি দেখুন:

চারটি উদাহরণই foo নামের ভেরিয়েবলের তালিকা (1, 2, 3) বরাদ্দ করবে।

(set (quote foo) (list 1 2 3))    ;foo => (1 2 3)
(1 2 3)

(set 'foo '(1 2 3))   ;foo => (1 2 3) same function, simpler expression
(1 2 3)

(setq foo '(1 2 3))   ;foo => (1 2 3) similar function, different syntax
(1 2 3)

(setf foo '(1 2 3))   ;foo => (1 2 3) more capable function
(1 2 3)

setfতালিকার একজন সদস্যকে fooএকটি নতুন মান নির্ধারণের যুক্ত করার ক্ষমতা রয়েছে ।

foo                   ;foo => (1 2 3) as defined above
(1 2 3)

(car foo)             ;the first item in foo is 1
1

(setf (car foo) 4)    ;set or setq will fail since (car foo) is not a symbol
4

foo                   ;the fist item in foo was set to 4 by setf
(4 2 3)

তবে, আপনি এমন একটি প্রতীক ম্যাক্রো সংজ্ঞায়িত করতে পারেন যা এর মধ্যে একটি আইটেমকে সম্মান জানায় foo

(define-symbol-macro foo-car (car foo))    ; assumes FOO => (1 2 3)
FOO-CAR

foo-car               ;foo-car is now a symbol for the 1st item in foo
1

(setq foo-car 4)      ;set or setq can set the symbol foo-car 
4

foo                   ;Lisp macros are so cool
(4 2 3)

আপনি defvarযদি ইতিমধ্যে ভেরিয়েবলটি সংজ্ঞায়িত না করে থাকেন এবং আপনার কোডটিতে পরে কোনও মান দিতে না চান তবে আপনি ব্যবহার করতে পারেন ।

(defvar foo2)
(define-symbol-macro foo-car (car foo2))

13

কেউ নিম্ন-স্তরের কনস্ট্রাকশন সম্পর্কে ভাবতে SETএবং SETQহতে পারে।

  • SET চিহ্নগুলির মান নির্ধারণ করতে পারে।

  • SETQ ভেরিয়েবলের মান সেট করতে পারে।

তারপরে SETFএকটি ম্যাক্রো যা বিভিন্ন ধরণের সেটিং জিনিস সরবরাহ করে: প্রতীক, ভেরিয়েবল, অ্যারের উপাদান, উদাহরণ স্লটস ...

প্রতীক এবং ভেরিয়েবলের জন্য কেউ ভাবতে পারে যেন SETFপ্রসারিত হয় SETএবং SETQ

* (macroexpand '(setf (symbol-value 'a) 10))

(SET 'A 10)


* (macroexpand '(setf a 10))         

(SETQ A 10)

সুতরাং SETএবং SETQএর কয়েকটি কার্যকারিতা বাস্তবায়নের জন্য ব্যবহার করা SETFহয় যা আরও সাধারণ নির্মাণ। যখন আমরা প্রতীক ম্যাক্রোগুলিকে বিবেচনা করি তখন অন্য কয়েকটি উত্তর আপনাকে আরও জটিল জটিল গল্প বলে।


4

আমি পূর্ববর্তী উত্তরগুলিতে যুক্ত করতে চাই যে সেটফ ম্যাক্রো যা তার প্রথম যুক্তি হিসাবে পাস হয়েছে তার উপর নির্ভর করে নির্দিষ্ট ফাংশনটি কল করে। বিভিন্ন ধরণের আর্গুমেন্টের সাথে সেটফের ম্যাক্রো বিস্তারের ফলাফলের তুলনা করুন:

(macroexpand '(setf a 1))

(macroexpand '(setf (car (list 3 2 1)) 1))

(macroexpand '(setf (aref #(3 2 1) 0) 1))

কিছু ধরণের আর্গুমেন্টের জন্য "সেটফ ফাংশন" ডাকা হবে:

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