13

कोड के इस टुकड़े के साथ की वजह से finitary नहीं किया जा रहा त्रुटि:संकलक के बारे में वर्ग ग्राफ एक विस्तृत पुनरावर्ती प्रकार पैरामीटर

trait B[T] 
trait C[T] 
class A[T] extends B[A[C[T]]] 

मैं निम्नलिखित त्रुटि मिलती है:

error: class graph is not finitary because type parameter T is expansively recursive 
     class A[T] extends B[A[C[T]]] 
      ^

कोई क्या त्रुटि व्याख्या कर सकते हैं संदेश के बारे में है, क्यों T असीमित पुनरावर्ती है और निम्न कोड क्यों काम करता है?

class A[T] extends B[A[T]] 

उत्तर

18
Scala 2.9 specification से

(ध्यान दें कि इस में एक परिवर्तन है कि 2.4 में पेश किया गया था के रूप में परिवर्तन लॉग है, इसलिए यह एक "नए प्रतिबंध" 2.9 में नहीं है):

The implementation of subtyping has been changed to prevent infinite recursions. Termination of subtyping is now ensured by a new restriction of class graphs to be finitary.

Kennedy and Pierce इसका कारण बताएं

Even disregarding subtyping, infinite closure presents a problem for language implementers, as they must take care not to create type representations for supertypes in an eager fashion, else non- termination is the result. For example, the .NET Common Language Runtime supports generic instantiation and generic inheritance in its intermediate language targeted by C. The class loader maintains a hash table of types currently loaded, and when loading a new type it will attempt to load its supertypes, add these to the table, and in turn load the type arguments involved in the supertype.

सौभाग्य से, कैनेडी और पियर्स का कहना है के रूप में, वहाँ है कि क्या एक वर्ग ग्राफ infinitary है की जाँच करने के लिए एक सुविधाजनक तरीका बताया गया है: infinitary वर्ग रेखांकन एक समस्या है। मैं इस जवाब में अपनी परिभाषाओं का उपयोग कर रहा हूं।

सबसे पहले मैं अपने प्रकार चर स्पष्टता के लिए अलग बनाती हूँ:

trait B[X] 
trait C[Y] 
class A[Z] extends B[A[C[Z]]] 

अगला हम कैनेडी और पियर्स की परिभाषा का उपयोग कर प्रकार पैरामीटर निर्भरता ग्राफ का निर्माण। ग्राफ में किनारों को जोड़ने वाला एकमात्र घोषणा A के लिए अंतिम है। वे ग्राफ के निर्माण के लिए निम्नलिखित नियम दे:

For each declaration C <X̄> <:: T and each subterm D<T̄> of T , if T_j = X_i add a non-expansive edge C#i → D#j ; if X_i is a proper subterm of T_j add an expansive edge C#i → D#j

तो सबसे पहले हम Z और C[Z] पर है, जो हमें एक गैर प्रशस्त बढ़त Z से Y के लिए देता है देखो।

Graph for the bad version

मैं धराशायी तीर और विशाल के साथ गैर प्रशस्त किनारों इंगित किया है: अगली Z और A[C[Z]] हमें एक विशाल बढ़त Z से Z करने देता है, और Z और B[A[C[Z]]] हमें Z से एक विशाल बढ़त X के लिए देता है ठोस वाले किनारों।

Infinitary class tables are characterized precisely by those graphs that contain a cycle with at least one expansive edge.

यह class A[Z] extends B[A[Z]] के लिए नहीं होता है, जो निम्नलिखित ग्राफ है:

Graph for the good version

एक सबूत के लिए कागज देखें हम एक विशाल बढ़त है, जो एक समस्या है के साथ एक चक्र है कि एक वर्ग तालिका infinitary iff यह विशाल है।


+3

मैं मैं सिर्फ ग्राफिक्स के लिए एक अतिरिक्त +1 दे सकता है चाहता हूँ। बहुत अच्छा जवाब। –