{"id":"ocp-bidirectional-extensibility","text":"OCP achieves bidirectional extensibility: the standard composition-based direction (add new types without modifying existing code, validated by OCP's evolution from inheritance to abstraction) combined with Visitor's principled inversion (add new operations via double-dispatch without modifying element classes), ensuring no extension axis is permanently closed.","truth_value":"IN","source":"","source_url":"","source_hash":"","justifications":[{"type":"SL","antecedents":["ocp-composition-with-principled-escape","composite-visitor-dual-ocp-coverage"],"outlist":[],"label":"Standard OCP extends types; Visitor inverts to extend operations — together they cover both axes"}],"dependents":["bidirectional-ocp-encapsulation-bounded","ocp-bidirectional-grounded-in-solid","ocp-governs-variation-strategy"],"metadata":{"source_type":"derived","review_result":"unnecessary"},"created_at":"2026-06-17T18:53:05+00:00","updated_at":"2026-06-18T06:15:08+00:00","reviewed_at":"2026-06-18T06:15:08+00:00","verified_at":"","retracted_at":"","explanation":{"steps":[{"node":"ocp-bidirectional-extensibility","truth_value":"IN","reason":"SL justification valid","antecedents":["ocp-composition-with-principled-escape","composite-visitor-dual-ocp-coverage"],"label":"Standard OCP extends types; Visitor inverts to extend operations — together they cover both axes"},{"node":"ocp-composition-with-principled-escape","truth_value":"IN","reason":"SL justification valid","antecedents":["ocp-evolution-validates-composition-shift","visitor-dispatch-implements-ocp-inversion"],"label":"Both depth-2 conclusions address OCP's relationship to composition from opposite directions (evolution toward it, deliberate inversion of it); together they reveal composition as a default-with-escape-hatch rather than a dogma"},{"node":"ocp-evolution-validates-composition-shift","truth_value":"IN","reason":"SL justification valid","antecedents":["ocp-evolved-from-inheritance-to-abstraction","composition-superiority-for-reuse"],"label":"OCP's own history recapitulates the broader paradigm shift — convergent validation from principle and practice"},{"node":"ocp-evolved-from-inheritance-to-abstraction","truth_value":"IN","reason":"SL justification valid","antecedents":["ocp-coined-by-meyer-1988","ocp-meyer-vs-polymorphic-interpretation","ocp-polymorphic-version-is-dominant-modern-interpretation"],"label":"OCP's evolution from concrete inheritance to abstract polymorphism parallels and foreshadows the GoF's composition-over-inheritance principle"},{"node":"ocp-coined-by-meyer-1988","truth_value":"IN","reason":"premise"},{"node":"ocp-meyer-vs-polymorphic-interpretation","truth_value":"IN","reason":"premise"},{"node":"ocp-polymorphic-version-is-dominant-modern-interpretation","truth_value":"IN","reason":"premise"},{"node":"composition-superiority-for-reuse","truth_value":"IN","reason":"SL justification valid","antecedents":["favor-composition-over-inheritance","inheritance-breaks-encapsulation","inheritance-compile-time-composition-run-time","delegation-composition-as-powerful-as-inheritance"],"label":"Four independent arguments converge on composition's superiority over inheritance"},{"node":"favor-composition-over-inheritance","truth_value":"IN","reason":"premise"},{"node":"inheritance-breaks-encapsulation","truth_value":"IN","reason":"premise"},{"node":"inheritance-compile-time-composition-run-time","truth_value":"IN","reason":"premise"},{"node":"delegation-composition-as-powerful-as-inheritance","truth_value":"IN","reason":"premise"},{"node":"visitor-dispatch-implements-ocp-inversion","truth_value":"IN","reason":"SL justification valid","antecedents":["visitor-double-dispatch-mechanism","visitor-inverts-ocp-axis"],"label":"The dispatch mechanism IS the axis inversion — not two independent properties but implementation and consequence"},{"node":"visitor-double-dispatch-mechanism","truth_value":"IN","reason":"SL justification valid","antecedents":["gof-visitor-double-dispatch-via-accept","visitor-passed-as-argument-to-accept","gof-visitor-two-class-hierarchies"],"label":"Accept-as-argument + callback-encodes-type + two-hierarchy-structure together constitute the double-dispatch mechanism"},{"node":"gof-visitor-double-dispatch-via-accept","truth_value":"IN","reason":"premise"},{"node":"visitor-passed-as-argument-to-accept","truth_value":"IN","reason":"premise"},{"node":"gof-visitor-two-class-hierarchies","truth_value":"IN","reason":"premise"},{"node":"visitor-inverts-ocp-axis","truth_value":"IN","reason":"SL justification valid","antecedents":["visitor-enables-open-ended-operations","visitor-tradeoff-stable-structure-required","ocp-open-for-extension-closed-for-modification"],"label":"Visitor's open-ops/closed-structure stance is the precise mirror of OCP's open-structure/closed-ops stance"},{"node":"visitor-enables-open-ended-operations","truth_value":"IN","reason":"premise"},{"node":"visitor-tradeoff-stable-structure-required","truth_value":"IN","reason":"premise"},{"node":"ocp-open-for-extension-closed-for-modification","truth_value":"IN","reason":"premise"},{"node":"composite-visitor-dual-ocp-coverage","truth_value":"IN","reason":"SL justification valid","antecedents":["composite-as-universal-recursive-structure","visitor-inverts-ocp-axis"],"label":"Composite covers standard OCP axis (new types) while Visitor covers inverted axis (new operations) for the same structures"},{"node":"composite-as-universal-recursive-structure","truth_value":"IN","reason":"SL justification valid","antecedents":["composite-uniform-leaf-composite-treatment","interpreter-abstract-syntax-tree-is-composite","macrocommand-is-composite-of-commands"],"label":"Three distinct patterns reuse Composite's recursive composition structure"},{"node":"composite-uniform-leaf-composite-treatment","truth_value":"IN","reason":"premise"},{"node":"interpreter-abstract-syntax-tree-is-composite","truth_value":"IN","reason":"premise"},{"node":"macrocommand-is-composite-of-commands","truth_value":"IN","reason":"premise"}]}}