क्यों अधिक भाषाओं में एक मूल्य को एक से अधिक अन्य मूल्य से तुलना करने की क्षमता नहीं है? [बन्द है]


10

निम्नलिखित को धयान मे रखते हुए:

if(a == b or c)

अधिकांश भाषाओं में, इसे निम्नानुसार लिखना होगा:

if(a == b or a == c)

जो थोड़ा बोझिल है और जानकारी को दोहराता है।

मुझे पता है कि मेरा उपर्युक्त नमूना वाक्य-विन्यास थोड़ा स्पष्ट है, लेकिन मुझे यकीन है कि विचार को व्यक्त करने के बेहतर तरीके हैं।

अधिक भाषाएं इसे क्यों नहीं पेश करतीं? क्या प्रदर्शन या वाक्यविन्यास मुद्दे हैं?


6
SQL प्रदान करता है कि: जहां A IN (B, C)
thursdaysgeek

4
मैं ऐसी भाषाओं के लिए नहीं पूछ रहा था जो इसे पेश करती हैं, या हो सकती हैं, लेकिन अधिक भाषाएं इसे क्यों नहीं पेश करती हैं? क्या प्रदर्शन या वाक्यविन्यास मुद्दे हैं?
ज़ेरोथ

8
सामान्य भाषा में @ thursdaysgeek के उत्तर को सामान्य करने के लिए, आमतौर पर आप ऐसा करते हैं कि सेट कंटेंट के साथ। (या एक सूची या अगर यह आसान है। तो।) यह एक ही काम करता है और कुछ संभावित मुश्किल सिंटैक्स मुद्दों से बचा जाता है। आपके उदाहरण से, "b या c" का अर्थ सेट "{b, c}" है या एक ऑपरेटर जैसा है || ? अजगर में "बी या सी" का अर्थ है "बी का मान यदि सच है, या फिर सी का मूल्य"
रोब

4
मूलतः यह एक वाक्यविन्यास मुद्दा है। हाथ में समस्या "बी या सी" और "बी या सी के साथ बी" के बीच अंतर को स्पष्ट करने के लिए एक सहज तरीका है।
यंगजॉन

2
यह विशेष मामले के लिए काफी आसान है a == b or c, और यह भी अच्छी तरह से IMHO नहीं है।

जवाबों:


24

वाक्यविन्यास मुद्दा है - कि यह वाक्यविन्यास की आवश्यकता है।

आपकी भाषा में जो भी वाक्यविन्यास है, भाषा का उपयोग करने वाले लोगों को इसे सीखना होगा। अन्यथा वे कोड को देखने और यह नहीं जानते कि यह क्या करता है। इस प्रकार यह आम तौर पर एक अच्छी बात मानी जाती है यदि किसी भाषा में एक सरल वाक्यविन्यास होता है जो बहुत सारे मामलों को सफाई से संभालता है।

अपने विशिष्ट उदाहरण में, आप एक infix ऑपरेटर (एक फ़ंक्शन जो दो तर्क लेता है, लेकिन लिखा जाता है Argument1 Operator Argument2) लेने की कोशिश कर रहा है और इसे कई तर्कों तक विस्तारित करने की कोशिश कर रहा है। यह बहुत सफाई से काम नहीं करता है क्योंकि infix ऑपरेटरों के पूरे बिंदु, इस हद तक कि एक है, ऑपरेटर को 2 तर्कों के बीच सही रखना है। (Argument1 Operator Argument2 MagicallyClearSymbol Argument3...)लगता है पर विस्तार करने के लिए स्पष्टता का एक बहुत जोड़ने के लिए नहीं है Equals(Arg1,Arg2,...)। Infix का उपयोग आम तौर पर उन गणितीय सम्मेलनों का अनुकरण करने के लिए किया जाता है जिनसे लोग परिचित होते हैं, जो एक वैकल्पिक वाक्यविन्यास के लिए सही नहीं होगा।

आपके विचार से जुड़े कोई विशेष प्रदर्शन के मुद्दे नहीं होंगे, इसके अलावा, पार्सर को एक अन्य उत्पादन नियम या दो के साथ एक व्याकरण से निपटना होगा, जो पार्सिंग की गति पर थोड़ा प्रभाव डाल सकता है। यह एक व्याख्या या JIT संकलित भाषा के लिए कुछ अंतर कर सकता है, लेकिन शायद एक बड़ा अंतर नहीं है।

विचार के साथ बड़ी समस्या यह है कि किसी भाषा में बहुत सारे विशेष मामलों को एक बुरा विचार बना दिया जाता है


1
एक तरफ: स्काला के पास कई प्रकार के तर्कों के साथ इन्फिक्स ऑपरेटर्स हैं, क्योंकि इन्फिक्स ऑपरेटर्स बिना किसी विधि के सिर्फ कॉल करते हैं .। तो वे के रूप में लिखा जाएगा arg1 op (arg2, arg3)। बिल्कुल सुंदर नहीं, लेकिन उस भाषा के संदर्भ में कुछ जगहों की जरूरत है।
आमोन

if my_var in (a, b)फिर क्या हुआ ? क्या यह नौकरी के लिए सही उपकरण का उपयोग करने का सवाल नहीं है?

शानदार अंक। भाषा सिंटैक्स भाषा की अनिवार्यता होनी चाहिए, और फिर आप इसके ऊपर पुस्तकालयों का निर्माण करें। यदि भाषा बहुत "उपयोगी" वाक्य रचना चीनी के साथ लिपटी है, तो इसका उपयोग करना कठिन हो जाता है। हर किसी की जरूरत नहीं है a == b or cजबकि अन्य चाहते हैं a == b or c but not d। IMO वह जगह है जहाँ उपयोगिता कार्य / पुस्तकालय बचाव के लिए आते हैं।
एलन

शायद इसकी आवश्यकता एक साधन है जिसके माध्यम से एक विधि निर्दिष्ट कर सकती है कि एक मनमानी संख्या वाले तर्कों को एक कॉल के रूप में एकाधिक कॉल के रूप में संभाला जाना चाहिए, जिसके परिणाम किसी तरह संयुक्त हो सकते हैं। अगर f().Equals(a,b,c); मूल्यांकन किया जा सकता है (var temp=f(); temp.Equals(a)||temp.Equals(b)||temp.Equals(c))कि वाक्यविन्यास सही होगा, लेकिन अगर इसका मूल्यांकन int[] arr = {a,b,c}; f().Equals(arr);किया जाए तो यह इतना अच्छा नहीं होगा, खासकर यदि प्रत्येक कॉल के लिए एक नया सरणी बनाया जाना था।
सुपरकैट

6

क्योंकि यह एक गैर-समस्या है, और इसे हल करने से मूल रूप से शून्य लाभ होता है, लेकिन इसे लागू करने से गैर-शून्य लागत आती है।

मौजूदा रेंज-आधारित फ़ंक्शंस और ऐसे जो व्यावहारिक रूप से हर भाषा की पेशकश करते हैं, इस स्थिति में पूरी तरह से अच्छी तरह से काम कर सकते हैं यदि यह एक आकार के लिए तराजू है जहां यह इसे खो a == b || a == cदेगा।


2
+1, लेकिन मुझे लगता है कि उत्तर उन "मौजूदा रेंज-आधारित फ़ंक्शंस में से एक या दो को दिखाते हुए बेहतर होगा जो व्यावहारिक रूप से हर भाषा [ऑफ़र]" है, बस इसलिए यह विकल्प स्पष्ट होगा।
अवनेर शाहर-कश्तन

क्या आप यह साबित कर सकते हैं कि यह "मूल रूप से शून्य लाभ लाता है, लेकिन इसे लागू करने से गैर-शून्य लागत आती है"?
डेरेक नादज़ा

3
@ DarekN Ddza दूसरी छमाही को विवादास्पद नहीं होना चाहिए: प्रत्येक सुविधा के माध्यम से सोचा जाना चाहिए, कार्यान्वित, परीक्षण, प्रलेखित और समर्थित होना चाहिए। उन कदमों में से कोई भी किसी भी उचित मीट्रिक (लोगों के समय, अवसर लागत, जटिलता, मौद्रिक लागत के तहत मुक्त नहीं है, अगर किसी को उस पर काम करने के लिए भुगतान किया जाता है, और इसी तरह)।

@ AvnerShahar-Kashtan सहमत - मेरे लिए, यह स्पष्ट नहीं है कि यह कैसे कहेंगे, जावा, या श, या zsh? ठीक है, उसने 'आधुनिक' भाषा का अर्थ लगाया हो सकता है। ग्रूवी?
वोल्कर सेगल

PHP में, यह कैसा दिखेगा in_array($a, [$b, $c, $d, $e, $f])। : P
cHao

6

कुछ भाषाओं में ऐसी विशेषताएं होती हैं। Perl6 में उदाहरण के लिए हम उपयोग कर सकते हैं जंक्शनों है, जो दो मूल्यों की "superpositions" कर रहे हैं:

if $a == any($b, $c) {
    say "yes";
}

# syntactic sugar for the above
if $a == $b | $c {
    say "yes";
}

कुछ भाषाओं में कलेक्शन को वितरित करने के तरीके के समान रूप से जूनक्शन हमें डेटा के एक सेट पर काफी स्पष्ट रूप से संचालन व्यक्त करने की अनुमति देता है। उदाहरण के लिए पाइथन का प्रयोग सुन्न के साथ, तुलना सभी मूल्यों पर वितरित की जा सकती है:

import numpy as np
2 == np.array([1, 2, 3])
#=> np.array([False, True, False], dtype=np.bool)
(2 == np.array([1, 2, 3])).any()
#=> True

हालांकि, यह केवल चयनित आदिम प्रकारों के लिए काम करता है।

जंक्शन क्यों समस्याग्रस्त हैं? क्योंकि एक जंक्शन पर संचालन निहित मूल्यों पर वितरित होता है, जंक्शन ऑब्जेक्ट खुद को विधि कॉल के लिए प्रॉक्सी की तरह व्यवहार करता है - बतख टाइपिंग से अलग कुछ प्रकार के सिस्टम को संभाल सकता है।

यदि इस तरह के जंक्शनों को केवल तुलनात्मक संचालकों के आसपास विशेष वाक्यविन्यास के रूप में अनुमति दी जाती है, तो टाइप सिस्टम समस्याओं से बचा जा सकता है । लेकिन इस मामले में, वे इतने सीमित हैं कि वे किसी भी भाषा में जोड़े जाने के लिए पर्याप्त मूल्य नहीं जोड़ते हैं। सेट संचालन या मैन्युअल रूप से सभी तुलनाओं का उपयोग करके एक ही व्यवहार व्यक्त किया जा सकता है, और अगर कोई पहले से ही पूरी तरह से ठीक समाधान है, तो अधिकांश भाषाएं अनावश्यक वाक्यविन्यास को जोड़ने में विश्वास नहीं करती हैं।


यह विशेष रूप से उदाहरण के रूप में स्पष्ट रूप से फिर से लिखा जा सकता है 2 in [1, 2, 3]। दूसरी ओर, यदि सुन्न एक .all()या कुछ है, समतुल्य सादा अजगर लगभग संक्षिप्त नहीं है।
इजाकाता

@ इज़कट I ने विशेष रूप से सेट ऑपरेशन का उपयोग नहीं किया। जबकि मेरे उदाहरण ने ==ऑपरेटर का उपयोग किया था , हम <इसके बजाय भी उपयोग कर सकते हैं - inअब आपका कहां है ? जंक्शनों, सेट सदस्यता परीक्षण की तुलना में अधिक सामान्य होते हैं क्योंकि जंक्शन पर कार्रवाई सभी सदस्यों से अधिक वितरित - (x|y).fooहै x.foo|y.foo, जब तक जंक्शन अंत में एक एकल मान को ध्वस्त हो गई है। प्रदान किया गया NumPy कोड, आदिम प्रकारों को मानते हुए, पर्ल 6 जंक्शनों के बिल्कुल समतुल्य लेकिन अधिक क्रियात्मक अनुवाद को दर्शाता है।
आमोन

2

मैक्रोज़ वाली भाषाओं में, कुछ ऐसा जोड़ना आसान है, अगर यह पहले से ही नहीं है। रैकेट पर विचार करें

(define-syntax-rule (equal-any? a b ...)
  (or (equal? a b) ...))
(equal-any? "a" "b" "a")
> #t

मेटाप्रोग्रामिंग के बिना अन्य भाषाओं में, शायद आप इसे सुधार सकते हैं कि सेट / सूची सदस्यता के रूप में शायद जाँच करें:

if a ∈ {b, c}

2
पहले दो जांचें कि क्या सभी तर्क समान हैं; ओपी यह जांचना चाहता है कि पहला तर्क निम्नलिखित में से किसी के बराबर है या नहीं। उत्सुकतावश, आपके द्वारा दिखाया गया तीसरा स्निपेट सम्मान करता है।

@delnan क्षमा करें मुझे सामान की गलतफहमी हुई। मैंने इसे संपादित किया है।
फिल

2

कुछ (लोकप्रिय) भाषाओं में ==ऑपरेटर संक्रामक नहीं होता है। उदाहरण के लिए जावास्क्रिप्ट 0में दोनों समान हैं ''और '0', लेकिन फिर ''और '0'प्रत्येक अभिकार के बराबर नहीं हैं। PHP में इस तरह के और अधिक quirks।

इसका मतलब यह है कि यह a == b == cएक और अस्पष्टता को जोड़ देगा, क्योंकि यह एक अलग परिणाम दे सकता है जो इस बात पर निर्भर करता है कि यह (a == b) & (a == c)या के रूप में व्याख्या की गई है (a == b) & (a == c) & (b == c)


2

अधिकांश भाषाओं में, यह एक Inफ़ंक्शन लिखकर तुच्छ रूप से प्राप्त किया जाना चाहिए , इसलिए इसे वास्तविक भाषा का हिस्सा क्यों बनाया जाए?

उदाहरण के लिए, Linq है Contains()

ठीक है, आप सभी बच्चों के लिए, यहाँ C # में मेरा कार्यान्वयन है:

public static bool In<T>(this T obj, params T[] values)
{
    for(int i=0; i < values.Length; i++)
    {
        if (object.Equals(obj, values[i]))
            return true;
    }
    return false;
}

यह मूल्यों की एक रन-टाइम रेंज पर संचालित होता है, न कि एक टपल जैसा कि ओपी कोड के रूप में व्यक्त किया जा सकता है।
डेडएमजी

ऐसा लगता है, सिर्फ इसलिए कि यह आसान है, इसका मतलब यह नहीं है कि यह नहीं किया जाना चाहिए। इसके ... निर्माण पर विचार करें। क्यों हम हमेशा कार्यक्षमता और एल्गोरिदम के इन बुनियादी टुकड़ों को बार-बार लिखने के लिए, बार-बार लिख रहे हैं?
ज़ेरोथ

5
@Zeroth शायद आप बार-बार एक ही बात लिख रहे हैं, लेकिन अन्य लोग अपनी भाषा के बजाय उनके द्वारा दिए गए अमूर्त तंत्र का उपयोग करते हैं। आप अपने आप को देखते हैं, तो लिख a == b || a == cकई बार, हो सकता है इसके लिए समय आ गया हैequals_any(a, {b, c})
आमोन

एक "समाहित" कार्यान्वयन आसानी से जैसी चीजों को कवर करने के लिए विस्तार नहीं करता है if (a > (b or c))और if (a mod (b or c) == 2)
tobyink

1
क्या किसी ने पेडेंट कहा? :) यह एक फॉरेस्ट लूप है, इसलिए कोई iचर नहीं है। और कुल मिलाकर ऐसा लगता है कि आपके द्वारा एक लंबा दिन बीतने के बाद लिखा जा रहा है :) क्योंकि दोनों return trueऔर return falseलूप के अंदर रखने का मतलब है कि ऐसा कोई तरीका नहीं है जो इसे पहले पुनरावृत्ति से आगे कभी नहीं बनाएगा। आप केवल पहले के मुकाबले तुलना कर रहे हैं value। वैसे, Any@ याकूब ने सुझाव के रूप में इसका उपयोग क्यों नहीं किया और इसे सरल बना दियाreturn values.Any(value => Object.Equals(obj, value));
कोनराड मोरावस्की

1

"if (a == b या c)" अधिकांश भाषाओं में काम करता है: यदि a == b या यदि c ऋणात्मक, शून्य या शून्य नहीं है।

यह शिकायत करना कि यह क्रिया है, इस बिंदु को याद करती है: आपको एक दर्जन चीजों को सशर्त नहीं करना चाहिए। यदि आपको एक मान की तुलना अन्य मानों की एक मनमानी संख्या से करने की आवश्यकता है, तो एक सबरूटीन बनाएँ।


3
कौन सी भाषाएं "सबसे अधिक" बनाती हैं?
FrustratedWithFormsDesigner

1
@FrustratedWithFormsDesigner, ठीक है, अगर cएक बूलियन का मूल्यांकन करता है, तो बहुत ज्यादा किसी भी भाषा को संभाल सकता है a == b || c:)
ब्रायन एस

@ ब्रायन: मैंने माना कि ओपी का मतलब शाब्दिक वाक्य रचना है if(a == b or c)। मुझे एक ब्रेक लेने की जरूरत है, मुझे लगता है ...: P
FrustratedWithFormsDesigner

@FrustratedWithFormsDesigner लिस्प! ... हुह? ... :)
वोल्कर सेगल

3
यह वास्तव में प्रश्न के बिंदु को याद करता है। if (a == b or c)यह देखने के लिए कि aक्या बराबर है bया नहीं के बराबर है , जांचना कोड aहै c। यह जाँचने के लिए नहीं है कि cगैर-शून्य है।
hvd

1

आमतौर पर, आप अपने वाक्यविन्यास को कम से कम रखना चाहते हैं और इसके बजाय ऐसे निर्माणों को भाषा में ही परिभाषित करने की अनुमति देते हैं।

उदाहरण के लिए, हास्केल में आप बैकस्टिक्स का उपयोग करके किसी भी फ़ंक्शन को दो या अधिक तर्कों के साथ इनफ़िक्स ऑपरेटर में परिवर्तित कर सकते हैं। यह आपको लिखने की अनुमति देता है:

if a `elem` [b, c] then ... else ...

जहां elemदो तर्कों को लेते हुए एक सामान्य कार्य है - एक मूल्य और मूल्यों की एक सूची - और यह जांचता है कि क्या पहले दूसरे का एक तत्व है।

यदि आप andइसके बजाय उपयोग करना चाहते हैं तो क्या होगा or? हास्केल में, आप कंपाइलर विक्रेता की नई सुविधा को लागू करने के लिए इंतजार करने के बजाय बस निम्नलिखित का उपयोग कर सकते हैं:

 if all (== a) [b, c] then ... else ...

1
कोई वाक्य रचना को न्यूनतम क्यों रखना चाहेगा? क्या वास्तव में व्यापार बंद हो रहा है? तर्कों के समर्थन के बिना इस तरह की घोषणा न करें। ;)
ज़ेरोथ

1

कुछ भाषाएं इसे प्रदान करती हैं - एक हद तक।

शायद आपके विशिष्ट उदाहरण के रूप में नहीं , लेकिन उदाहरण के लिए एक पायथन लाइन लें:

def minmax(min, max):
    def answer(value):
        return max > value > min
    return answer

inbounds = minmax(5, 15)
inbounds(7) ##returns True
inbounds(3) ##returns False
inbounds(18) ##returns False

इसलिए, कुछ भाषाएं कई तुलनाओं के साथ ठीक हैं, जब तक आप इसे सही ढंग से व्यक्त कर रहे हैं।

दुर्भाग्य से, यह काफी काम नहीं करता है जैसे आप तुलना के लिए इसकी अपेक्षा करेंगे।

>>> def foo(a, b):
...     def answer(value):
...         return value == a or b
...     return answer
... 
>>> tester = foo(2, 4)
>>> tester(3)
4
>>> tester(2)
True
>>> tester(4)
4
>>> 

"आपका क्या मतलब है कि यह या तो सच है या 4?" - आप के बाद किराया

इस मामले में एक समाधान, कम से कम पायथन के साथ, इसे थोड़ा अलग तरीके से उपयोग करना है:

>>> def bar(a, b):
...     def ans(val):
...             return val == a or val == b
...     return ans
... 
>>> this = bar(4, 10)
>>> this(5)
False
>>> this(4)
True
>>> this(10)
True
>>> this(9)
False
>>> 

संपादित करें: निम्नलिखित भी कुछ ऐसा ही करेगा, फिर से पायथन में ...

>>> def bar(a, b):
...     def answer(val):
...             return val in (a, b)
...     return answer
... 
>>> this = bar(3, 5)
>>> this(3)
True
>>> this(4)
False
>>> this(5)
True
>>> 

इसलिए, आप जिस भी भाषा का उपयोग कर रहे हैं, यह नहीं हो सकता है कि आप ऐसा नहीं कर सकते , बस यह कि आपको पहले इस बात पर ध्यान देना चाहिए कि तर्क वास्तव में कैसे काम करता है। आमतौर पर यह जानने की बात होती है कि आप वास्तव में आपको बताने के लिए भाषा से क्या पूछ रहे हैं।


1

IndexOf मेथड, जिसका उपयोग एक Array पर किया जाता है, जो कि सभी भाषाओं में है, एक मान को कई अन्य लोगों से तुलना करने की अनुमति देता है, इसलिए मुझे लगता है कि एक विशेष ऑपरेटर बहुत अर्थ नहीं रखता है।

जावास्क्रिप्ट में जो लिखेंगे:

if ( [b, c].indexOf(a) != -1 ) { ....  }

0

आप पूछते हैं कि हम ऐसा क्यों नहीं कर सकते: if(a == b or c)

अजगर यह बहुत कुशलता से करता है, वास्तव में, सबसे कुशलता से set:

if a in set([b, c]):
    then_do_this()

सदस्यता परीक्षण के लिए, 'सेट' यह जांचता है कि तत्व की हैश समान है और केवल समानता के लिए तुलना करता है, इसलिए तत्वों, बी और सी, धोने योग्य होना चाहिए, अन्यथा एक सूची सीधे समानता के लिए तुलना करती है:

if a in [b, c]:
    then_do_this()

0

एपीएल-शैली की भाषाएं आपको एकल ऑपरेशन में वेक्टर में प्रत्येक तत्व के साथ एक स्केलर की तुलना करने की अनुमति देती हैं। यह बूलियन वेक्टर पैदा करता है। एक उदाहरण के लिए, मैं बेशर्मी से अपने न्यूनतम रुप से प्रदर्शित apl कैलकुलेटर, inca ( ऑनलाइन दुभाषिया ) को बढ़ावा देना चाहूंगा ।

   a<5
5 
   b<4
4 
   c<5
5 
   a=b c
0 1 

इसे एक मूल्य पर कम करने के लिए, हम एक समावेशी या नॉनवेज के लिए योग और जाँच कर सकते हैं।

   0!+/a=b c
1 
   c<6
6 
   0!+/a=b c
0

इसलिए, जैसा कि अन्य उत्तर कहते हैं, मुद्दा वाक्यविन्यास है। कुछ हद तक, वाक्य रचना समाधान है सरणी प्रतिमान सीखने का शायद भारी कीमत पर, पाया गया।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.