<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>http://debianws.lexgopc.com/wiki143/index.php?action=history&amp;feed=atom&amp;title=Draft%3AC3_linearization</id>
	<title>Draft:C3 linearization - Revision history</title>
	<link rel="self" type="application/atom+xml" href="http://debianws.lexgopc.com/wiki143/index.php?action=history&amp;feed=atom&amp;title=Draft%3AC3_linearization"/>
	<link rel="alternate" type="text/html" href="http://debianws.lexgopc.com/wiki143/index.php?title=Draft:C3_linearization&amp;action=history"/>
	<updated>2026-05-11T21:01:17Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.1</generator>
	<entry>
		<id>http://debianws.lexgopc.com/wiki143/index.php?title=Draft:C3_linearization&amp;diff=3894734&amp;oldid=prev</id>
		<title>imported&gt;Aydoh8: Declining submission: npov - Submission is not written in a formal, neutral encyclopedic tone (AFCH)</title>
		<link rel="alternate" type="text/html" href="http://debianws.lexgopc.com/wiki143/index.php?title=Draft:C3_linearization&amp;diff=3894734&amp;oldid=prev"/>
		<updated>2025-05-25T23:57:10Z</updated>

		<summary type="html">&lt;p&gt;Declining submission: npov - Submission is not written in a formal, neutral encyclopedic tone (&lt;a href=&quot;/wiki143/index.php?title=WP:AFCH&amp;amp;action=edit&amp;amp;redlink=1&quot; class=&quot;new&quot; title=&quot;WP:AFCH (page does not exist)&quot;&gt;AFCH&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{AFC submission|d|npov|u=2804:7F0:B2C0:A3D6:B6C:7F14:E9A6:20E4|ns=118|decliner=Aydoh8|declinets=20250525235710|ts=20250525235604}} &amp;lt;!-- Do not remove this line! --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Short description|Computer algorithm}}&lt;br /&gt;
{{Draft topics|computing}}&lt;br /&gt;
{{AfC topic|other}}&lt;br /&gt;
&lt;br /&gt;
{{draft article|nomove=yes}}&lt;br /&gt;
 &lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;C3 superclass linearization&amp;#039;&amp;#039;&amp;#039; is an [[algorithm]] used primarily to obtain the order in which [[method (computing)|methods]] should be inherited in the presence of [[multiple inheritance]]. In other words, the &amp;#039;&amp;#039;output&amp;#039;&amp;#039; of C3 superclass linearization is a deterministic &amp;#039;&amp;#039;&amp;#039;Method Resolution Order&amp;#039;&amp;#039;&amp;#039; (&amp;#039;&amp;#039;&amp;#039;MRO&amp;#039;&amp;#039;&amp;#039;).  &lt;br /&gt;
&lt;br /&gt;
{{quote|In [[object-oriented]] systems with multiple inheritance, some mechanism must be used for resolving conflicts when inheriting different definitions of the same property from multiple superclasses.&amp;lt;ref name=C3_96/&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
C3 superclass linearization is called C3 because it &amp;quot;is consistent with three properties&amp;quot;:&amp;lt;ref name=C3_96/&amp;gt; &lt;br /&gt;
* a consistent extended [[precedence graph]], &lt;br /&gt;
* preservation of local precedence order, and &lt;br /&gt;
* fitting a monotonicity criterion.&lt;br /&gt;
&lt;br /&gt;
It was first published at the 1996 [[OOPSLA]] conference, in a paper entitled &amp;quot;A Monotonic Superclass Linearization for [[Dylan (programming language)|Dylan]]&amp;quot;.&amp;lt;ref name=C3_96&amp;gt;{{cite conference&lt;br /&gt;
| date = 1996-06-28&lt;br /&gt;
| title = A Monotonic Superclass Linearization for Dylan&lt;br /&gt;
| book-title = OOPSLA &amp;#039;96 Conference Proceedings&lt;br /&gt;
| author = Kim Barrett, Bob Cassels, Paul Haahr, David A. Moon, Keith Playford, P. Tucker Withington&lt;br /&gt;
| pages = 69–82&lt;br /&gt;
| publisher = [[ACM Press]]&lt;br /&gt;
| doi = 10.1145/236337.236343&lt;br /&gt;
| isbn = 0-89791-788-X&lt;br /&gt;
| citeseerx = 10.1.1.19.3910&lt;br /&gt;
}}&amp;lt;/ref&amp;gt;  It was adapted to the Open Dylan implementation in January 2012&amp;lt;ref&amp;gt;[http://opendylan.org/news/2012/01/25/c3.html News item on opendylan.org]&amp;lt;/ref&amp;gt; following an enhancement proposal.&amp;lt;ref&amp;gt;{{Cite web |url=http://opendylan.org/proposals/dep-0003.html |title=Dylan Enhancement Proposal 3: C3 superclass linearization |access-date=2013-02-17 |archive-date=2017-07-03 |archive-url=https://web.archive.org/web/20170703005630/https://opendylan.org/proposals/dep-0003.html |url-status=dead }}&amp;lt;/ref&amp;gt; It has been chosen as the default algorithm for method resolution in [[Python (programming language)|Python]] 2.3 (and newer),&amp;lt;ref&amp;gt;[https://www.python.org/download/releases/2.3/mro/ Python 2.3&amp;#039;s use of C3 MRO]&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;[http://rhettinger.wordpress.com/2011/05/26/super-considered-super/ Tutorial for practical applications of C3 linearization using Python]&amp;lt;/ref&amp;gt; [[Raku (programming language)|Raku]],&amp;lt;ref&amp;gt;[http://doc.perl6.org/type/Metamodel::C3MRO Perl 6&amp;#039;s use of the C3 MRO]&amp;lt;/ref&amp;gt; [[Parrot virtual machine|Parrot]],&amp;lt;ref&amp;gt;{{Cite web |url=http://aspn.activestate.com/ASPN/Mail/Message/perl6-internals/2746631 |title=Parrot uses C3 MRO |access-date=2006-12-06 |archive-url=https://web.archive.org/web/20070208165958/http://aspn.activestate.com/ASPN/Mail/Message/perl6-internals/2746631 |archive-date=2007-02-08 |url-status=dead }}&amp;lt;/ref&amp;gt; [[Solidity]], and [[PGF/TikZ]]&amp;#039;s Object-Oriented Programming module.&amp;lt;ref&amp;gt;{{cite book|last1=Tantau|first1=Till|title=The TikZ &amp;amp; PGF Manual|date=August 29, 2015|page=1062|edition=3.1.9a|url=http://ftp.ntua.gr/mirror/ctan/graphics/pgf/base/doc/pgfmanual.pdf|access-date=2021-05-15}}&amp;lt;/ref&amp;gt; It is also available as an alternative, non-default MRO in the core of [[Perl|Perl 5]] starting with version 5.10.0.&amp;lt;ref&amp;gt;[https://metacpan.org/module/mro C3 MRO available in Perl 5.10 and newer]&amp;lt;/ref&amp;gt; An extension implementation for earlier versions of Perl 5 named &amp;lt;code&amp;gt;Class::C3&amp;lt;/code&amp;gt; exists on [[CPAN]].&amp;lt;ref&amp;gt;[https://metacpan.org/module/Class::C3 Perl 5 extension for C3 MRO on CPAN]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Python&amp;#039;s [[Guido van Rossum]] summarizes C3 superclass linearization thus:&amp;lt;ref&amp;gt;{{cite web|last1=van Rossum|first1=Guido|title=Method Resolution Order|url=http://python-history.blogspot.co.uk/2010/06/method-resolution-order.html|website=The History of Python|access-date=18 January 2018|date=23 June 2010}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{quote|Basically, the idea behind C3 is that if you write down all of the ordering rules imposed by inheritance relationships in a complex class hierarchy, the algorithm will determine a monotonic ordering of the classes that satisfies all of them. If such an ordering can not be determined, the algorithm will fail.}}&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
{{Confusing|date=April 2018}}&lt;br /&gt;
&lt;br /&gt;
The C3 superclass linearization of a class is the sum of the class plus a unique merge of the linearizations of its parents and a list of the parents itself. The list of parents as the last argument to the merge process preserves the local precedence order of direct parent classes.&lt;br /&gt;
&lt;br /&gt;
The merge of parents&amp;#039; linearizations and parents list is done by selecting the first head of the lists which does not appear in the tail (all elements of a list except the first) of any of the lists. Note, that a good head may appear as the first element in multiple lists at the same time, but it is forbidden to appear anywhere else. The selected element is removed from all the lists where it appears as a head and appended to the output list. The process of selecting and removing a good head to extend the output list is repeated until all remaining lists are exhausted. If at some point no good head can be selected, because the heads of all remaining lists appear in any one tail of the lists, then the merge is impossible to compute due to inconsistent orderings of dependencies in the inheritance hierarchy and no linearization of the original class exists.&lt;br /&gt;
&lt;br /&gt;
A naive [[divide-and-conquer algorithm|divide-and-conquer]] approach to computing the linearization of a class may invoke the algorithm recursively to find the linearizations of parent classes for the merge-subroutine. However, this will result in an infinitely looping recursion in the presence of a cyclic class hierarchy. To detect such a cycle and to break the infinite recursion (and to reuse the results of previous computations as an optimization), the recursive invocation should be shielded against [[reentrancy (computing)|re-entrance]] of a previous argument by means of a cache or [[memoization]].&lt;br /&gt;
&lt;br /&gt;
This algorithm is similar to finding a [[topological sorting|topological ordering]].&lt;br /&gt;
&lt;br /&gt;
=== Example ===&lt;br /&gt;
Given&lt;br /&gt;
[[File:C3_linearization_example.svg|right|300px|thumb|A dependency graph for the C3 linearization example.]]&lt;br /&gt;
{{sxhl|2=java|1=&amp;lt;nowiki/&amp;gt;&lt;br /&gt;
 class O&lt;br /&gt;
 class A extends O&lt;br /&gt;
 class B extends O&lt;br /&gt;
 class C extends O&lt;br /&gt;
 class D extends O&lt;br /&gt;
 class E extends O&lt;br /&gt;
 class K1 extends C, A, B&lt;br /&gt;
 class K3 extends A, D&lt;br /&gt;
 class K2 extends B, D, E&lt;br /&gt;
 class Z extends K1, K3, K2&lt;br /&gt;
}}&lt;br /&gt;
the linearization of Z is computed as&lt;br /&gt;
{{sxhl|2=pascal|1=&amp;lt;nowiki/&amp;gt;&lt;br /&gt;
 L(O)  := [O]                                                // the linearization of O is trivially the singleton list [O], because O has no parents&lt;br /&gt;
 &lt;br /&gt;
 L(A)  := [A] + merge(L(O), [O])                             // the linearization of A is A plus the merge of its parents&amp;#039; linearizations with the list of parents...&lt;br /&gt;
        = [A] + merge([O], [O])&lt;br /&gt;
        = [A, O]                                             // ...which simply prepends A to its single parent&amp;#039;s linearization&lt;br /&gt;
 &lt;br /&gt;
 L(B)  := [B, O]                                             // linearizations of B, C, D and E are computed similar to that of A&lt;br /&gt;
 L(C)  := [C, O]&lt;br /&gt;
 L(D)  := [D, O]&lt;br /&gt;
 L(E)  := [E, O]&lt;br /&gt;
 &lt;br /&gt;
 L(K1) := [K1] + merge(L(C), L(B), L(A), [C, A, B])          // first, find the linearization of K1&amp;#039;s parents, L(C), L(B), and L(A), and merge them with the parent list [C, A, B]&lt;br /&gt;
        = [K1] + merge([C, O], [B, O], [A, O], [C, A, B])    // class C is a good candidate for the first merge step, because it only appears as the head of the first and last lists&lt;br /&gt;
        = [K1, C] + merge([O], [B, O], [A, O], [A, B])       // class O is not a good candidate for the next merge step, because it also appears in the tails of list 2 and 3, class B is also not good; but class A is a good candidate&lt;br /&gt;
        = [K1, C, A] + merge([O], [B, O], [O], [B])          // class B is a good candidate; class O still appears in the tail of list 2&lt;br /&gt;
        = [K1, C, A, B] + merge([O], [O], [O])               // finally, class O is a valid candidate, which also exhausts all remaining lists&lt;br /&gt;
        = [K1, C, A, B, O]&lt;br /&gt;
 &lt;br /&gt;
 L(K3) := [K3] + merge(L(A), L(D), [A, D])&lt;br /&gt;
        = [K3] + merge([A, O], [D, O], [A, D])               // select A&lt;br /&gt;
        = [K3, A] + merge([O], [D, O], [D])                  // fail O, select D&lt;br /&gt;
        = [K3, A, D] + merge([O], [O])                       // select O&lt;br /&gt;
        = [K3, A, D, O]&lt;br /&gt;
 &lt;br /&gt;
 L(K2) := [K2] + merge(L(B), L(D), L(E), [B, D, E])&lt;br /&gt;
        = [K2] + merge([B, O], [D, O], [E, O], [B, D, E])    // select B&lt;br /&gt;
        = [K2, B] + merge([O], [D, O], [E, O], [D, E])       // fail O, select D&lt;br /&gt;
        = [K2, B, D] + merge([O], [O], [E, O], [E])          // fail O, select E&lt;br /&gt;
        = [K2, B, D, E] + merge([O], [O], [O])               // select O&lt;br /&gt;
        = [K2, B, D, E, O]&lt;br /&gt;
 &lt;br /&gt;
 L(Z)  := [Z] + merge(L(K1), L(K3), L(K2), [K1, K3, K2])&lt;br /&gt;
        = [Z] + merge([K1, C, A, B, O], [K3, A, D, O], [K2, B, D, E, O], [K1, K3, K2])    // select K1&lt;br /&gt;
        = [Z, K1] + merge([C, A, B, O], [K3, A, D, O], [K2, B, D, E, O], [K3, K2])        // select C&lt;br /&gt;
        = [Z, K1, C] + merge([A, B, O], [K3, A, D, O], [K2, B, D, E, O], [K3, K2])        // fail A, select K3&lt;br /&gt;
        = [Z, K1, C, K3] + merge([A, B, O], [A, D, O], [K2, B, D, E, O], [K2])            // select A&lt;br /&gt;
        = [Z, K1, C, K3, A] + merge([B, O], [D, O], [K2, B, D, E, O], [K2])               // fail B, fail D, select K2&lt;br /&gt;
        = [Z, K1, C, K3, A, K2] + merge([B, O], [D, O], [B, D, E, O])                     // select B&lt;br /&gt;
        = [Z, K1, C, K3, A, K2, B] + merge([O], [D, O], [D, E, O])                        // fail O, select D&lt;br /&gt;
        = [Z, K1, C, K3, A, K2, B, D] + merge([O], [O], [E, O])                           // fail O, select E&lt;br /&gt;
        = [Z, K1, C, K3, A, K2, B, D, E] + merge([O], [O], [O])                           // select O&lt;br /&gt;
        = [Z, K1, C, K3, A, K2, B, D, E, O]                                               // done.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Example demonstrated in Python 3 ===&lt;br /&gt;
First, a metaclass to enable a short representation of the objects by name instead of the default class REPR value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python3&amp;quot;&amp;gt;&lt;br /&gt;
class Type(type):&lt;br /&gt;
    def __repr__(cls):&lt;br /&gt;
        # Will make it so that repr(O) is &amp;quot;O&amp;quot; instead of &amp;quot;&amp;lt;__main__.O&amp;gt;&amp;quot;,&lt;br /&gt;
        # and the same for any subclasses of O.&lt;br /&gt;
        return cls.__name__&lt;br /&gt;
&lt;br /&gt;
class O(object, metaclass=Type): pass &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next, we define our base classes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
class A(O): pass&lt;br /&gt;
&lt;br /&gt;
class B(O): pass&lt;br /&gt;
&lt;br /&gt;
class C(O): pass&lt;br /&gt;
&lt;br /&gt;
class D(O): pass&lt;br /&gt;
&lt;br /&gt;
class E(O): pass&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then we construct the inheritance tree:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
class K1(C, A, B): pass&lt;br /&gt;
&lt;br /&gt;
class K3(A, D): pass&lt;br /&gt;
&lt;br /&gt;
class K2(B, D, E): pass&lt;br /&gt;
&lt;br /&gt;
class Z(K1, K3, K2): pass&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And now:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;pycon&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; Z.mro()&lt;br /&gt;
[Z, K1, C, K3, A, K2, B, D, E, O, &amp;lt;class &amp;#039;object&amp;#039;&amp;gt;]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example demonstrated in Raku ===&lt;br /&gt;
&lt;br /&gt;
[[Raku (programming language)|Raku]] uses C3 linearization for classes by default:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl6&amp;quot;&amp;gt;&lt;br /&gt;
class A {}&lt;br /&gt;
class B {}&lt;br /&gt;
class C {}&lt;br /&gt;
class D {}&lt;br /&gt;
class E {}&lt;br /&gt;
class K1 is C is A is B {}&lt;br /&gt;
class K3 is A is D {}&lt;br /&gt;
class K2 is B is D is E {}&lt;br /&gt;
class Z is K1 is K3 is K2 {}&lt;br /&gt;
say Z.^mro; # OUTPUT: ((Z) (K1) (C) (K3) (A) (K2) (B) (D) (E) (Any) (Mu))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(the &amp;lt;code&amp;gt;Any&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Mu&amp;lt;/code&amp;gt; are the types all Raku objects inherit from, so &amp;lt;code&amp;gt;Any&amp;lt;/code&amp;gt; stands in place of O)&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{reflist}}&lt;br /&gt;
&lt;br /&gt;
{{draft categories|&lt;br /&gt;
[[:Category:Object-oriented programming]]&lt;br /&gt;
[[:Category:Programming language implementation]]&lt;br /&gt;
[[:Category:Articles with example Python (programming language) code]]&lt;br /&gt;
}}&lt;br /&gt;
{{Drafts moved from mainspace|date=May 2025}}&lt;/div&gt;</summary>
		<author><name>imported&gt;Aydoh8</name></author>
	</entry>
</feed>