নির্ধারিত মানের চেয়ে ইউনিটকে মূল্যায়ন করার জন্য স্কালা অ্যাসাইনমেন্টের অনুপ্রেরণা কী?


84

নির্ধারিত মানের চেয়ে ইউনিটকে মূল্যায়ন করার জন্য স্কালা অ্যাসাইনমেন্টের অনুপ্রেরণা কী?

আই / ও প্রোগ্রামিংয়ের একটি সাধারণ প্যাটার্ন হ'ল এই জাতীয় জিনিসগুলি করা:

while ((bytesRead = in.read(buffer)) != -1) { ...

তবে স্কেলে এটি সম্ভব নয় কারণ ...

bytesRead = in.read(buffer)

.. ইউনিট প্রদান করে, বাইটআরডের নতুন মান নয়।

কার্যকরী ভাষা থেকে বেরিয়ে আসা একটি আকর্ষণীয় জিনিস বলে মনে হচ্ছে। আমি ভাবছি কেন এমন হয়েছে?


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

উত্তর:


89

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


7
কোনও কারণ রয়েছে যে কেন স্কালার সংকলক কার্যনির্বাহের মানটি আসলে ব্যবহৃত হয় কিনা এবং সে অনুযায়ী দক্ষ বাইটকোড তৈরি করে কিনা তা তাকাতে পারেনি?
ম্যাট আর

43
সেটটারগুলির উপস্থিতিতে এটি এত সহজ নয়: প্রতিটি সেটারকে একটি ফলাফল ফিরে আসতে হয়, যা লিখতে কষ্ট হয়। তারপরে সংকলকটিকে এটিকে অপ্টিমাইজ করতে হবে, যা কলগুলির বাইরে করা শক্ত।
মার্টিন ওডারস্কি

4
আপনার যুক্তিটি কোনও অর্থবোধ করে না, তবুও জাভা এবং সি # এর বিপরীতে। আমি অনুমান করি আপনি জেনারেটেড বাইট কোডটি দিয়ে কিছু অদ্ভুত কিছু করছেন, তাহলে স্কালায় কোনও অ্যাসাইনমেন্ট ক্লাস ফাইলে সংকলিত হয়ে জাভাতে ফিরে পচে যাওয়া কেমন হবে?
Phng Nguyễn

4
@ PhươngNguyễn পার্থক্যটি ইউনিফর্ম অ্যাক্সেসের মূল নীতি। সি # / জাভা সেটারগুলিতে (সাধারণত) ফিরুন void। যদি অ্যাসাইনমেন্ট করে তবে স্কালায় foo_=(v: Foo)ফিরে আসা উচিত Foo
আলেক্সি রোমানভ

4
@ মার্টিন ওডারস্কি: নিম্নলিখিতগুলি সম্পর্কে কীভাবে: সেটারগুলি রয়ে গেছে void( Unit), অ্যাসাইনমেন্টগুলি এর x = valueসমতুল্যে অনুবাদ হয় x.set(value);x.get(value); getমানটি অব্যবহৃত থাকলে সংকলকটি কলগুলির পর্যায়ক্রমে অনুকূলকরণের ক্ষেত্রে সরিয়ে দেয়। এটি একটি নতুন মেজাজে (পশ্চাদগম্য অসঙ্গতিজনিত কারণে) স্কেল রিলিজ এবং ব্যবহারকারীদের জন্য কম বিরক্তিতে স্বাগত পরিবর্তন হতে পারে। আপনি কি মনে করেন?
ইউজেন লাবুন

20

আমি প্রকৃত কারণগুলিতে তথ্য ভিতরে গোপন রাখি না, তবে আমার সন্দেহ খুব সহজ is স্কালা পার্শ্ব-কার্যকারী লুপগুলি ব্যবহারের জন্য বিশ্রী করে তোলে যাতে প্রোগ্রামাররা প্রাকৃতিকভাবে বোঝার জন্য পছন্দ করে।

এটি বিভিন্ন উপায়ে এটি করে। উদাহরণস্বরূপ, আপনার এমন কোনও forলুপ নেই যেখানে আপনি ভেরিয়েবলটি ঘোষণা এবং পরিবর্তন করতে পারেন । আপনি whileশর্তটি পরীক্ষা করতে একই সাথে আপনি কোনও লুপে পরিবর্তন করতে পারবেন না ( যার অর্থ) আপনাকে প্রায়শই পরিবর্তনের ঠিক আগে এবং তার শেষেও পুনরাবৃত্তি করতে হয়। কোনও whileব্লকের ভিতরে ঘোষিত চলকগুলি whileপরীক্ষার শর্ত থেকে দৃশ্যমান নয় , যা do { ... } while (...)অনেক কম দরকারী করে তোলে । ইত্যাদি।

কার্যকারিতা:

while ({bytesRead = in.read(buffer); bytesRead != -1}) { ... 

যার জন্য এটি মূল্যবান।

বিকল্প ব্যাখ্যা হিসাবে, সম্ভবত মার্টিন ওডারস্কিকে এই ধরনের ব্যবহার থেকে প্রাপ্ত কয়েকটি খুব কুৎসিত বাগের মুখোমুখি হতে হয়েছিল এবং তার ভাষা থেকে এটিকে নিষিদ্ধ করার সিদ্ধান্ত নিয়েছে।

সম্পাদনা

ডেভিড পোল্যাক কিছু বাস্তব তথ্য দিয়ে উত্তর দিয়েছেন , যেগুলি স্পষ্টতই সমর্থন করেছে যে মার্টিন ওডারস্কি নিজেই তার উত্তর মন্তব্য করেছিলেন, পোলাকের দেওয়া পারফরম্যান্স-সম্পর্কিত ইস্যু তর্ককে বিশ্বাসযোগ্যতা দিয়েছিলেন।


4
সুতরাং সম্ভবত forলুপ সংস্করণটি হবে: for (bytesRead <- in.read(buffer) if (bytesRead) != -1এটি দুর্দান্ত যা ব্যতীত এটি কার্যকর হবে না কারণ সেখানে নেই foreachএবং withFilterউপলব্ধ!
অক্সবো_লেকস

12

স্কালার আরও একটি "আনুষ্ঠানিকভাবে সঠিক" টাইপ সিস্টেম থাকার অংশ হিসাবে এটি ঘটেছে। সাধারণভাবে বলতে গেলে, অ্যাসাইনমেন্টটি একটি সম্পূর্ণ পার্শ্ব-প্রতিক্রিয়াশীল বিবৃতি এবং তাই ফিরে আসা উচিত Unit। এর কিছু সুন্দর পরিণতি হয়; উদাহরণ স্বরূপ:

class MyBean {
  private var internalState: String = _

  def state = internalState

  def state_=(state: String) = internalState = state
}

state_=পদ্ধতি আয় Unit(হিসাবে একটি সেটার জন্য প্রত্যাশিত হবে) অবিকল কারণ নিয়োগ আয় Unit

আমি একমত যে সি স্টাইলের নিদর্শনগুলির মতো কোনও স্ট্রিম অনুলিপি করার অনুরূপ, এই নির্দিষ্ট নকশার সিদ্ধান্তটি কিছুটা ঝামেলা হতে পারে। তবে এটি সাধারণভাবে তুলনামূলকভাবে অপ্রতিরোধ্য এবং টাইপ সিস্টেমের সামগ্রিক ধারাবাহিকতায় সত্যই অবদান রাখে।


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

4
@ গ্রাহাম: তবে, আপনাকে অবশ্যই ধারাবাহিকতাটি অনুসরণ করতে হবে এবং আপনার সমস্ত সেটারগুলিতে তারা যত জটিল হতে পারে তা নিশ্চিত করতে হবে, যাতে তারা নির্ধারিত মানটি ফেরত দেয়। এটি কিছু ক্ষেত্রে জটিল হবে এবং অন্য ক্ষেত্রে কেবল ভুল, আমার ধারণা। (ত্রুটির ক্ষেত্রে আপনি কী ফিরিয়ে দেবেন? নাল? - না, কিছুই নয়? - তবে আপনার ধরণটি অপশন [টি] হবে)) আমি মনে করি এটির সাথে সামঞ্জস্য করা খুব কঠিন।
দেবিলেস্কি

7

সম্ভবত এটি কমান্ড-ক্যোয়ারী বিচ্ছেদ নীতিটির কারণে হয়েছে ?

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

কেন CQS দরকারী সংক্ষিপ্ত চিত্রণ: একটি সঙ্গে একটি প্রকল্পিত সংকর এফ / OO যেমন পণ্য ভাষা বিবেচনা Listবর্গ আছে পদ্ধতি Sort, Append, First, এবং Length। অপরিহার্য ওও স্টাইলে, কেউ এই জাতীয় কোনও ফাংশন লিখতে চাইতে পারেন:

func foo(x):
    var list = new List(4, -2, 3, 1)
    list.Append(x)
    list.Sort()
    # list now holds a sorted, five-element list
    var smallest = list.First()
    return smallest + list.Length()

যদিও আরও কার্যকরী শৈলীতে, কেউ সম্ভবত আরও কিছু লিখবেন:

func bar(x):
    var list = new List(4, -2, 3, 1)
    var smallest = list.Append(x).Sort().First()
    # list still holds an unsorted, four-element list
    return smallest + list.Length()

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

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


4

আমি অনুমান করব প্রোগ্রামটি / ভাষাটিকে পার্শ্ব প্রতিক্রিয়া মুক্ত রাখার জন্য এটি।

আপনি যা বর্ণনা করছেন তা হ'ল পার্শ্ব প্রতিক্রিয়ার ইচ্ছাকৃত ব্যবহার যা সাধারণ ক্ষেত্রে খারাপ জিনিস হিসাবে বিবেচিত হয়।


হি। পার্শ্ব প্রতিক্রিয়া মুক্ত স্কেল? :) এছাড়াও, বনাম এর মতো একটি মামলার val a = b = 1কল্পনা করুন ( valসামনে "যাদুকর" কল্পনা করুন b) val a = 1; val b = 1;

পার্শ্ব প্রতিক্রিয়াগুলির সাথে এটির কোনও সম্পর্ক নেই, কমপক্ষে এখানে বর্ণিত অর্থে নয়: পার্শ্ব প্রতিক্রিয়া (কম্পিউটার বিজ্ঞান)
Feuermurmel

4

বুলিয়ান এক্সপ্রেশন হিসাবে কোনও অ্যাসাইনমেন্ট ব্যবহার করা এটি সেরা শৈলী নয়। আপনি একই সাথে দুটি জিনিস সম্পাদন করেন যা প্রায়শই ত্রুটির দিকে পরিচালিত করে। এবং "==" এর পরিবর্তে "=" এর যথাযথ ব্যবহার স্কেলাস সীমাবদ্ধতার সাথে এড়ানো যায়।


4
আমি মনে করি এটি একটি আবর্জনা কারণ! ওপি পোস্ট করার সাথে সাথে কোডটি এখনও সংকলন করে চলে এবং চলতে পারে: আপনি যা যুক্তিসঙ্গতভাবে আশা করতে পারেন এটি তা করে না। এটি আরও একটি গোচা, একটিও কম নয়!
অক্সবো_লেকস

4
যদি আপনি কিছু লিখেন তবে (a = b) এটি সংকলন করবে না। সুতরাং অন্তত এই ত্রুটিটি এড়ানো যায়।
ডিমন ২

4
ওপি '==' এর পরিবর্তে '=' ব্যবহার করেনি, তিনি উভয়ই ব্যবহার করেছিলেন। তিনি আশা করেন যে অ্যাসাইনমেন্টটি এমন কোনও মান প্রত্যাবর্তন করবে যা তারপরে ব্যবহার করা যেতে পারে, উদাহরণস্বরূপ, অন্য কোনও মানের সাথে তুলনা করতে (উদাহরণের মধ্যে -1)
ইত্তেডে

@ ডিমন: ক এবং কম বুলিয়ান হলে এটি কমপক্ষে (জাভাতে) সংকলন করবে। আমি (a = সত্য) ব্যবহার করে newbies এই ফাঁদে পড়তে দেখেছি। আরও সহজ কারণ (ক) (এবং আরও উল্লেখযোগ্য নাম ব্যবহার করা হলে আরও পরিষ্কার!) পছন্দ করার আরও একটি কারণ।
ফিলিহো

2

যাইহোক: আমি প্রাথমিক বুদ্ধিমান বোকা এমনকি জাভাতেও খুঁজে পাই। কেন এভাবে কিছু করেন না?

for(int bytesRead = in.read(buffer); bytesRead != -1; bytesRead = in.read(buffer)) {
   //do something 
}

মঞ্জুর, অ্যাসাইনমেন্টটি দু'বার প্রদর্শিত হবে, তবে কমপক্ষে বাইটরেড এটির ক্ষেত্রের মধ্যে রয়েছে এবং আমি মজাদার অ্যাসাইনমেন্ট ট্রিক্সের সাথে খেলছি না ...


4
কৌতুকটি একটি দুর্দান্ত সাধারণ, এটি সাধারণত প্রতিটি অ্যাপে প্রদর্শিত হয় যা একটি বাফারের মাধ্যমে পড়ে। এবং এটি সর্বদা ওপি-র সংস্করণ হিসাবে দেখায়।
TWiStErRob

0

আপনার কাছে ইন্ডিরিশেশনের জন্য একটি রেফারেন্স টাইপ থাকলে আপনি এটির জন্য একত্বর কাজ করতে পারেন। নির্লজ্জ প্রয়োগে, আপনি স্বেচ্ছাচারী ধরণের জন্য নিম্নলিখিত ব্যবহার করতে পারেন।

case class Ref[T](var value: T) {
  def := (newval: => T)(pred: T => Boolean): Boolean = {
    this.value = newval
    pred(this.value)
  }
}

তারপরে, আপনাকে এই সীমাবদ্ধতার অধীনে ref.valueরেফারেন্সটি পরে ব্যবহার করতে হবে, আপনি নিজের লিখতে পারেনwhile প্রিকিকেট হিসাবে

val bytesRead = Ref(0) // maybe there is a way to get rid of this line

while ((bytesRead := in.read(buffer)) (_ != -1)) { // ...
  println(bytesRead.value)
}

এবং আপনি এটি পরীক্ষা না করে bytesReadআরও নিখুঁত পদ্ধতিতে পরীক্ষা করতে পারেন ।

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