overlay.language 0.2.0.post23.dev0__tar.gz → 0.2.0.post25.dev0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {overlay_language-0.2.0.post23.dev0 → overlay_language-0.2.0.post25.dev0}/.gitignore +1 -1
- {overlay_language-0.2.0.post23.dev0 → overlay_language-0.2.0.post25.dev0}/PKG-INFO +1 -1
- {overlay_language-0.2.0.post23.dev0 → overlay_language-0.2.0.post25.dev0}/README.md +1 -1
- {overlay_language-0.2.0.post23.dev0 → overlay_language-0.2.0.post25.dev0}/docs/conf.py +1 -1
- {overlay_language-0.2.0.post23.dev0 → overlay_language-0.2.0.post25.dev0}/docs/index.rst +12 -12
- {overlay_language-0.2.0.post23.dev0 → overlay_language-0.2.0.post25.dev0}/docs/overlay-language-tutorial.rst +10 -12
- {overlay_language-0.2.0.post23.dev0 → overlay_language-0.2.0.post25.dev0}/docs/specification.md +80 -80
- {overlay_language-0.2.0.post23.dev0 → overlay_language-0.2.0.post25.dev0}/src/overlay/language/__init__.py +2 -2
- {overlay_language-0.2.0.post23.dev0 → overlay_language-0.2.0.post25.dev0}/src/overlay/language/_core.py +13 -9
- {overlay_language-0.2.0.post23.dev0 → overlay_language-0.2.0.post25.dev0}/src/overlay/language/_mixin_directory.py +17 -8
- {overlay_language-0.2.0.post23.dev0 → overlay_language-0.2.0.post25.dev0}/src/overlay/language/_mixin_parser.py +24 -19
- {overlay_language-0.2.0.post23.dev0 → overlay_language-0.2.0.post25.dev0}/docs/Makefile +0 -0
- {overlay_language-0.2.0.post23.dev0 → overlay_language-0.2.0.post25.dev0}/docs/_static/favicon.svg +0 -0
- {overlay_language-0.2.0.post23.dev0 → overlay_language-0.2.0.post25.dev0}/docs/_static/logo.svg +0 -0
- {overlay_language-0.2.0.post23.dev0 → overlay_language-0.2.0.post25.dev0}/docs/installation.rst +0 -0
- {overlay_language-0.2.0.post23.dev0 → overlay_language-0.2.0.post25.dev0}/docs/tutorial.rst +0 -0
- {overlay_language-0.2.0.post23.dev0 → overlay_language-0.2.0.post25.dev0}/pyproject.toml +0 -0
- {overlay_language-0.2.0.post23.dev0 → overlay_language-0.2.0.post25.dev0}/src/overlay/language/_config.py +0 -0
- {overlay_language-0.2.0.post23.dev0 → overlay_language-0.2.0.post25.dev0}/src/overlay/language/_interned_linked_list.py +0 -0
- {overlay_language-0.2.0.post23.dev0 → overlay_language-0.2.0.post25.dev0}/src/overlay/language/_runtime.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: overlay.language
|
|
3
|
-
Version: 0.2.0.
|
|
3
|
+
Version: 0.2.0.post25.dev0
|
|
4
4
|
Summary: A dependency injection framework with pytest-fixture syntax, plus a configuration language for declarative programming
|
|
5
5
|
Project-URL: Repository, https://github.com/Atry/overlay
|
|
6
6
|
Author-email: "Yang, Bo" <yang-bo@yang-bo.com>
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
A dependency injection framework with pytest-fixture syntax, plus a
|
|
4
4
|
configuration language for declarative programming, based on
|
|
5
|
-
[
|
|
5
|
+
[inheritance-calculus](https://arxiv.org/abs/2602.16291).
|
|
6
6
|
|
|
7
7
|
## Documentation
|
|
8
8
|
|
|
@@ -14,7 +14,7 @@ sys.path.insert(0, str(Path(__file__).resolve().parent.parent / "src"))
|
|
|
14
14
|
# -- Project information -----------------------------------------------------
|
|
15
15
|
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
|
|
16
16
|
|
|
17
|
-
project = '
|
|
17
|
+
project = 'MIXINv2'
|
|
18
18
|
copyright = '2025, Bo Yang'
|
|
19
19
|
author = 'Bo Yang'
|
|
20
20
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
MIXINv2
|
|
2
|
+
=======
|
|
3
3
|
|
|
4
4
|
``overlay.language`` is a dependency injection framework with pytest-fixture
|
|
5
5
|
syntax, plus a configuration language for declarative programming. The package
|
|
@@ -12,22 +12,22 @@ cutting behaviour layers on via ``@patch`` without touching the original code.
|
|
|
12
12
|
App-scoped singletons and per-request resources coexist naturally.
|
|
13
13
|
See :doc:`tutorial`.
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
``.ojson`` / ``.otoml``
|
|
17
|
-
the business decisions that clutter Python code — live in
|
|
15
|
+
**MIXINv2** is a configuration language written in ``.mixin.yaml`` /
|
|
16
|
+
``.mixin.json`` / ``.mixin.toml`` files (also ``.oyaml`` / ``.ojson`` / ``.otoml``). SQL queries, format strings, URL patterns — all
|
|
17
|
+
the business decisions that clutter Python code — live in MIXINv2
|
|
18
18
|
instead, where independent modules deep-merge by name without glue code —
|
|
19
19
|
dissolving the
|
|
20
20
|
`Expression Problem <https://en.wikipedia.org/wiki/Expression_problem>`_.
|
|
21
21
|
|
|
22
22
|
If you have ever struggled to mock a service that tangles I/O with business
|
|
23
23
|
logic, or dreaded porting an application from sync to async, or needed to swap
|
|
24
|
-
between providers without rewriting half your Python —
|
|
24
|
+
between providers without rewriting half your Python — MIXINv2 can
|
|
25
25
|
help. Despite looking like a configuration format, it is also a statically typed
|
|
26
26
|
modern programming language based on
|
|
27
|
-
`
|
|
27
|
+
`inheritance-calculus <https://arxiv.org/abs/2602.16291>`_, which is provably more
|
|
28
28
|
expressive than λ-calculus, so it can express your entire business logic — not
|
|
29
|
-
just configuration. Move that logic into
|
|
30
|
-
to thin I/O adapters that are trivial to mock or replace. The same
|
|
29
|
+
just configuration. Move that logic into MIXINv2 and Python reduces
|
|
30
|
+
to thin I/O adapters that are trivial to mock or replace. The same MIXINv2 code runs against any set of adapters and the business logic
|
|
31
31
|
never changes, even when you
|
|
32
32
|
port your synchronous program to async — the problem known as
|
|
33
33
|
`function color <https://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/>`_.
|
|
@@ -41,12 +41,12 @@ See :doc:`overlay-language-tutorial`.
|
|
|
41
41
|
step by step using ``@scope``, ``@extern``, and ``@resource``.
|
|
42
42
|
|
|
43
43
|
:doc:`overlay-language-tutorial`
|
|
44
|
-
Getting started with
|
|
45
|
-
in ``.
|
|
44
|
+
Getting started with MIXINv2 — rewrite the same application
|
|
45
|
+
in ``.mixin.yaml``, separating business logic from I/O, then switch the
|
|
46
46
|
underlying framework to asyncio without changing your code.
|
|
47
47
|
|
|
48
48
|
:doc:`specification`
|
|
49
|
-
Full language specification for
|
|
49
|
+
Full language specification for MIXINv2.
|
|
50
50
|
|
|
51
51
|
`API Reference <api/overlay.language.html>`__
|
|
52
52
|
Python API reference (auto-generated).
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
Getting Started with
|
|
2
|
-
|
|
1
|
+
Getting Started with MIXINv2
|
|
2
|
+
============================
|
|
3
3
|
|
|
4
4
|
The Step 4 Python code works, but it has a structural problem: **business logic
|
|
5
5
|
and I/O are tangled together**. Consider ``user_id`` in ``HttpHandlers``:
|
|
@@ -15,14 +15,13 @@ an integer (another business decision). The path separator, SQL queries, and
|
|
|
15
15
|
format templates are all hardcoded in Python — changing any of them means
|
|
16
16
|
changing Python code.
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
MIXINv2 solves this by separating the application into three layers:
|
|
19
19
|
|
|
20
20
|
- **Python FFI** wraps individual stdlib calls in ``@scope`` adapters — one class
|
|
21
21
|
per operation (``sqlite3.connect``, ``str.split``, ``wfile.write``). Each adapter
|
|
22
22
|
declares its inputs as ``@extern`` and exposes a single ``@public @resource``
|
|
23
23
|
output. The adapter contains **zero business logic**.
|
|
24
|
-
- **``.oyaml`` files** contain all application logic, written in
|
|
25
|
-
language. The Overlay language is not just a configuration format — it is a
|
|
24
|
+
- **``.oyaml`` files** contain all application logic, written in MIXINv2. MIXINv2 is not just a configuration format — it is a
|
|
26
25
|
complete language with lexical scoping, nested scopes, deep-merge composition,
|
|
27
26
|
and lazy evaluation. These features make it more natural than Python for
|
|
28
27
|
expressing business logic, which is inherently declarative ("the user ID is
|
|
@@ -238,8 +237,7 @@ single ``RequestScope``. After merging:
|
|
|
238
237
|
``HttpHandlers.RequestScope``, which uses it in ``_format``
|
|
239
238
|
|
|
240
239
|
Neither scope imports or references the other — deep merge makes their fields
|
|
241
|
-
mutual siblings automatically. This is the most powerful feature of
|
|
242
|
-
language: cross-cutting concerns compose without glue code.
|
|
240
|
+
mutual siblings automatically. This is the most powerful feature of MIXINv2: cross-cutting concerns compose without glue code.
|
|
243
241
|
|
|
244
242
|
**Config value scoping:** App-lifetime values (``database_path``, ``host``, ``port``)
|
|
245
243
|
live directly in ``memory_app``. Request-lifetime values (``user_query_sql``,
|
|
@@ -274,8 +272,8 @@ Syntax quick reference
|
|
|
274
272
|
- **Inheritance** — ``- [Parent]`` items are inherited scopes; the last item (a mapping) defines own fields
|
|
275
273
|
|
|
276
274
|
|
|
277
|
-
Python vs
|
|
278
|
-
|
|
275
|
+
Python vs MIXINv2
|
|
276
|
+
------------------
|
|
279
277
|
|
|
280
278
|
.. list-table::
|
|
281
279
|
:header-rows: 1
|
|
@@ -283,7 +281,7 @@ Python vs Overlay language
|
|
|
283
281
|
|
|
284
282
|
* - Aspect
|
|
285
283
|
- Python ``@scope``
|
|
286
|
-
-
|
|
284
|
+
- MIXINv2 (``.oyaml``)
|
|
287
285
|
* - Composition
|
|
288
286
|
- Manual ``@extend`` + ``RelativeReference``
|
|
289
287
|
- Inheritance list: ``- [Parent]``
|
|
@@ -341,6 +339,6 @@ using the fixture package at
|
|
|
341
339
|
|
|
342
340
|
The full language specification is in :doc:`specification`.
|
|
343
341
|
|
|
344
|
-
The semantics of
|
|
345
|
-
`
|
|
342
|
+
The semantics of MIXINv2 are grounded in the
|
|
343
|
+
`inheritance-calculus <https://arxiv.org/abs/2602.16291>`_, a formal calculus of
|
|
346
344
|
overlays.
|
{overlay_language-0.2.0.post23.dev0 → overlay_language-0.2.0.post25.dev0}/docs/specification.md
RENAMED
|
@@ -1,94 +1,94 @@
|
|
|
1
|
-
#
|
|
1
|
+
# MIXINv2 Specification
|
|
2
2
|
|
|
3
3
|
## 1. Introduction
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
MIXINv2 is a programming language designed to facilitate the flexible composition and configuration of logic and data structures through the use of _overlays_. Unlike traditional programming languages that use classes or functions as the primary building blocks, MIXINv2 employs a unified concept where everything is represented as an overlay. This approach allows for greater modularity, reusability, and flexibility.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
MIXINv2 is a lazily-evaluated, immutable language, meaning that values are only computed when necessary, and once created, they cannot be changed. This design makes MIXINv2 particularly well-suited for applications that require functional purity, such as configuration management, domain-specific language (DSL) creation, and code generation.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
MIXINv2 is not limited to a specific platform or target language. It can generate code for multiple languages by representing abstract syntax trees (ASTs) that correspond to various programming languages. This makes MIXINv2 an ideal choice for scenarios involving cross-language interoperability, complex configuration files, and even software synthesis.
|
|
10
10
|
|
|
11
11
|
### 1.1 Comparison with Other Languages
|
|
12
12
|
|
|
13
13
|
#### 1.1.1 Object-Oriented Languages
|
|
14
14
|
|
|
15
|
-
In traditional object-oriented languages like Java or C++, classes and objects are used to encapsulate state and behavior. However, this approach has several limitations that
|
|
15
|
+
In traditional object-oriented languages like Java or C++, classes and objects are used to encapsulate state and behavior. However, this approach has several limitations that MIXINv2 addresses through its unique design:
|
|
16
16
|
|
|
17
17
|
- **Complex Inheritance Hierarchies**: Object-oriented languages often require complex class hierarchies to represent different behaviors, leading to rigidity and difficulty in maintenance. Multiple inheritance, in particular, can introduce the "diamond problem," where the same method or property is inherited from multiple sources, causing ambiguity and conflicts.
|
|
18
18
|
|
|
19
|
-
- **the
|
|
19
|
+
- **the MIXINv2 Solution**: MIXINv2 uses a flexible composition model where overlays can be combined and inherited without conflict. Properties are automatically merged, and there is no need for complex inheritance trees. This eliminates the diamond problem and allows for clean, modular inheritance structures.
|
|
20
20
|
|
|
21
21
|
- **Static and Inflexible Object Models**: Once a class is defined in an object-oriented language, its structure and behavior are fixed. Modifying or extending the behavior often requires creating subclasses or using design patterns like decorators, which can add complexity and reduce clarity.
|
|
22
22
|
|
|
23
|
-
- **the
|
|
23
|
+
- **the MIXINv2 Solution**: Overlays in MIXINv2 can be dynamically composed and configured, allowing for flexible adjustments without altering existing definitions. This dynamic composition model enables developers to easily modify and extend behavior by combining overlays, without the need for static class hierarchies or complex design patterns.
|
|
24
24
|
|
|
25
25
|
- **Method Overriding and the Risk of Ad Hoc Behavior**: Traditional object-oriented languages rely on method overriding to modify inherited behavior. This can lead to unpredictable behavior, especially in deep inheritance hierarchies, where methods in subclasses may inadvertently override those in parent classes, introducing subtle bugs.
|
|
26
26
|
|
|
27
|
-
- **the
|
|
27
|
+
- **the MIXINv2 Solution**: MIXINv2 does not support method overriding. Instead, it merges properties from multiple parent overlays, ensuring that all inherited properties coexist without conflict. This approach avoids the risks associated with method overriding, such as accidental method shadowing or breaking polymorphic behavior, providing a more predictable and safer inheritance model.
|
|
28
28
|
|
|
29
29
|
- **Overreliance on Design Patterns**: To address limitations in object-oriented design, developers often resort to complex design patterns like Singleton, Factory, and Strategy. While these patterns solve specific problems, they can introduce additional complexity and boilerplate code.
|
|
30
30
|
|
|
31
|
-
- **the
|
|
31
|
+
- **the MIXINv2 Solution**: MIXINv2 can be seen as a metaprogramming language designed to generate code for other languages. Instead of using design patterns to address language limitations, developers can use MIXINv2 to generate consistent and reusable code across multiple languages. By representing abstract syntax trees (ASTs) and configurations as overlays, MIXINv2 allows for the creation of domain-specific languages (DSLs) and the automated generation of language constructs, reducing the need for complex design patterns and enabling more expressive and maintainable code.
|
|
32
32
|
|
|
33
|
-
Overall,
|
|
33
|
+
Overall, MIXINv2 provides a more modular and flexible alternative to traditional object-oriented languages by using overlay composition instead of class inheritance. Its support for property merging and dynamic composition allows developers to build complex systems more easily and safely. As a metaprogramming language, MIXINv2 excels in generating code for multiple languages, making it a powerful tool for scenarios requiring cross-language interoperability and code generation.
|
|
34
34
|
|
|
35
35
|
#### 1.1.2 Functional Languages
|
|
36
36
|
|
|
37
|
-
Functional programming languages like Haskell and Scala emphasize immutability and functional purity, offering benefits such as easier reasoning about code and avoidance of side effects. However, they also come with certain limitations that
|
|
37
|
+
Functional programming languages like Haskell and Scala emphasize immutability and functional purity, offering benefits such as easier reasoning about code and avoidance of side effects. However, they also come with certain limitations that MIXINv2 addresses through its design:
|
|
38
38
|
|
|
39
39
|
- **Complexity of Function Composition Syntax**: Functional languages often use advanced and abstract syntax for function composition, such as higher-order functions, monads, and combinators. While powerful, these constructs can be difficult to read and understand, especially for those new to functional programming.
|
|
40
40
|
|
|
41
|
-
- **the
|
|
41
|
+
- **the MIXINv2 Solution**: MIXINv2 employs a more intuitive and declarative approach by representing logic and data structures through overlay composition and configuration. Using familiar data serialization formats like YAML or JSON, MIXINv2 allows developers to define complex behaviors in a hierarchical and readable manner. This reduces the syntactic complexity associated with function composition in traditional functional languages.
|
|
42
42
|
|
|
43
43
|
- **Complexity of Context Management**: In functional programming, managing context, such as state or environment, often requires explicit passing of context through function parameters or using monads, which can make code verbose and harder to maintain.
|
|
44
44
|
|
|
45
|
-
- **the
|
|
45
|
+
- **the MIXINv2 Solution**: MIXINv2 simplifies context management by allowing overlays to automatically inherit and access properties from their lexical scope. This means that shared context or state can be accessed without the need for explicit parameter passing or complex monadic structures. The unified scoping and inheritance rules in MIXINv2 reduce boilerplate code and make the logic more straightforward.
|
|
46
46
|
|
|
47
47
|
- **The Expression Problem**: The Expression Problem refers to the difficulty of extending both the set of data types and the set of operations over them in a type-safe and modular way. In functional languages, adding new data types is straightforward, but adding new operations can be challenging without modifying existing code.
|
|
48
48
|
|
|
49
|
-
- **the
|
|
49
|
+
- **the MIXINv2 Solution**: MIXINv2 addresses the Expression Problem by allowing both overlays (representing data types) and properties or methods (representing operations) to be extended and composed modularly. Since overlays can inherit and combine properties from multiple sources without conflicts, developers can add new data types and operations independently. This flexibility enables MIXINv2 to support extensibility in both dimensions, overcoming the limitations faced in traditional functional programming languages.
|
|
50
50
|
|
|
51
|
-
Overall,
|
|
51
|
+
Overall, MIXINv2 provides a more accessible and flexible alternative to functional programming languages by reducing syntactic complexity, simplifying context management, and addressing the Expression Problem. Its overlay-based composition model allows for the modular and conflict-free extension of both data structures and operations, facilitating the development of complex systems in a more intuitive and maintainable way.
|
|
52
52
|
|
|
53
53
|
#### 1.1.3 Declarative Configuration Languages
|
|
54
54
|
|
|
55
|
-
Declarative configuration languages like JSON, YAML, and Nix are widely used to represent static data and configurations. They offer simplicity and readability but often lack the ability to express dynamic logic and complex relationships.
|
|
55
|
+
Declarative configuration languages like JSON, YAML, and Nix are widely used to represent static data and configurations. They offer simplicity and readability but often lack the ability to express dynamic logic and complex relationships. MIXINv2 extends these ideas, providing a more powerful and flexible alternative.
|
|
56
56
|
|
|
57
57
|
- **Static Configuration Limitations**: Traditional configuration languages like JSON and YAML are limited to representing static data structures. They cannot express dynamic relationships or logic, such as conditional values, calculations, or dependencies between configurations.
|
|
58
58
|
|
|
59
|
-
- **the
|
|
59
|
+
- **the MIXINv2 Solution**: MIXINv2 allows for dynamic logic and configuration through overlay composition and inheritance. Properties can be inherited, combined, or overridden based on context, enabling dynamic configurations that adapt to changing conditions. This makes MIXINv2 suitable for scenarios where complex dependencies and conditional configurations are required.
|
|
60
60
|
|
|
61
61
|
- **Lack of Modularity and Reusability**: In static configuration formats, it is difficult to create modular and reusable components. While YAML supports features like anchors and aliases, these are limited and can lead to complex and error-prone configurations.
|
|
62
62
|
|
|
63
|
-
- **the
|
|
63
|
+
- **the MIXINv2 Solution**: MIXINv2 enables modular and reusable configuration components through its overlay system. Each overlay can encapsulate a piece of configuration or logic, which can then be combined and reused in different contexts. This modular approach not only improves maintainability but also allows for the creation of complex configurations by composing simpler, reusable overlays.
|
|
64
64
|
|
|
65
65
|
- **Difficulty in Representing Relationships**: Declarative configuration languages often lack the ability to represent complex relationships between different parts of a configuration. Dependencies and relationships must be managed manually, which can lead to errors and inconsistencies.
|
|
66
66
|
|
|
67
|
-
- **the
|
|
67
|
+
- **the MIXINv2 Solution**: MIXINv2 uses inheritance to represent relationships between overlays, enabling clear and maintainable configurations. By using a unified inheritance model, MIXINv2 allows for the automatic resolution of dependencies and relationships, reducing the risk of errors and inconsistencies.
|
|
68
68
|
|
|
69
69
|
- **Limited Expressiveness for Code Generation**: While declarative languages like Nix provide some level of code generation through lazy evaluation and functional constructs, they are primarily designed for configuration management and package management. Extending them for general-purpose code generation or complex logical expressions can be cumbersome.
|
|
70
70
|
|
|
71
|
-
- **the
|
|
71
|
+
- **the MIXINv2 Solution**: MIXINv2, as a metaprogramming language, is designed to generate code and configurations for multiple target languages. By representing abstract syntax trees (ASTs) and logical structures as overlays, MIXINv2 can be used to generate code in different languages consistently. This capability makes MIXINv2 ideal for building DSLs, automating code generation, and ensuring consistency across different language environments.
|
|
72
72
|
|
|
73
|
-
Overall,
|
|
73
|
+
Overall, MIXINv2 extends the capabilities of traditional declarative configuration languages by supporting dynamic logic, modularity, and complex relationships. Its overlay-based approach enables more expressive and maintainable configurations, and its metaprogramming capabilities make it a powerful tool for code generation and cross-language interoperability.
|
|
74
74
|
|
|
75
75
|
### 1.2 Key Use Cases
|
|
76
76
|
|
|
77
77
|
#### 1.2.1 Multi-language Code Generation
|
|
78
78
|
|
|
79
|
-
|
|
79
|
+
MIXINv2 can generate code in multiple target languages, making it a versatile tool for building DSLs or serving as the core module of a compiler. By representing the ASTs of various languages as overlays, MIXINv2 can translate a single logical structure into multiple programming languages, ensuring consistency and reducing duplication across projects.
|
|
80
80
|
|
|
81
81
|
#### 1.2.2 Cross-language Interoperability
|
|
82
82
|
|
|
83
|
-
|
|
83
|
+
MIXINv2 provides a unified way to define data structures and logic that can be shared across different programming environments. For instance, a complex business logic model defined in MIXINv2 can be translated into both a backend service in Scala and a frontend component in JavaScript, ensuring consistent behavior and data flow.
|
|
84
84
|
|
|
85
85
|
#### 1.2.3 Complex System Configuration
|
|
86
86
|
|
|
87
|
-
As a configuration language,
|
|
87
|
+
As a configuration language, MIXINv2 excels in defining complex systems with interdependent components. Through the use of overlay composition and inheritance, configuration files can be modular, reusable, and adaptable, enabling powerful and flexible system configurations that go beyond the capabilities of traditional static formats like JSON or YAML.
|
|
88
88
|
|
|
89
89
|
### 1.3 A Simple Example
|
|
90
90
|
|
|
91
|
-
The following example demonstrates how to use
|
|
91
|
+
The following example demonstrates how to use MIXINv2 to define a basic arithmetic operation represented as an AST:
|
|
92
92
|
|
|
93
93
|
```yaml
|
|
94
94
|
# math_operations.oyaml
|
|
@@ -121,24 +121,24 @@ example_calculation:
|
|
|
121
121
|
|
|
122
122
|
**Explanation**:
|
|
123
123
|
|
|
124
|
-
1. The `Number` overlay represents a basic number type with no initial value, aligning with
|
|
124
|
+
1. The `Number` overlay represents a basic number type with no initial value, aligning with MIXINv2's immutable and lazy-evaluated nature.
|
|
125
125
|
2. The `add` overlay inherits from `Number` and defines two properties, `addend1` and `addend2`, both of which are also `Number`.
|
|
126
126
|
3. The `multiply` overlay defines a multiplication operation with two properties: `multiplicand` and `multiplier`.
|
|
127
127
|
4. In `test.oyaml`, the `example_calculation` overlay uses the `add` operation to add two numbers:
|
|
128
128
|
- `addend1` is a multiplication of `2` and `3`, represented using the `multiply` overlay.
|
|
129
129
|
- `addend2` is the constant `4`.
|
|
130
130
|
|
|
131
|
-
This example illustrates how
|
|
131
|
+
This example illustrates how MIXINv2 can be used to represent complex logic in a modular and declarative manner. The `example_calculation` overlay serves as the root of an AST, with each operation (e.g., `add` and `multiply`) acting as nodes, and their properties (`addend1`, `addend2`, `multiplicand`, `multiplier`) as sub-nodes. This structure can be evaluated directly within MIXINv2 or used to generate equivalent code in another language.
|
|
132
132
|
|
|
133
133
|
## 2. Overlay Definitions and Data Types
|
|
134
134
|
|
|
135
135
|
### 2.1 Basic Structure and Data Types
|
|
136
136
|
|
|
137
|
-
|
|
137
|
+
MIXINv2 supports a range of data types, all of which map directly to JSON data types. These types form the foundational elements of the language and define how data is represented and manipulated within MIXINv2.
|
|
138
138
|
|
|
139
139
|
#### 2.1.1 Primitive Data Types
|
|
140
140
|
|
|
141
|
-
The primitive data types in
|
|
141
|
+
The primitive data types in MIXINv2 correspond directly to JSON's scalar types:
|
|
142
142
|
|
|
143
143
|
- **Strings**: Represented as sequences of characters, corresponding to JSON strings.
|
|
144
144
|
|
|
@@ -157,7 +157,7 @@ The primitive data types in the Overlay language correspond directly to JSON's s
|
|
|
157
157
|
|
|
158
158
|
#### 2.1.2 Overlays as Data Types
|
|
159
159
|
|
|
160
|
-
In
|
|
160
|
+
In MIXINv2, the primary data type is the overlay itself, which corresponds to JSON objects. Each overlay represents a collection of properties and can inherit from other overlays, enabling complex compositions and configurations.
|
|
161
161
|
|
|
162
162
|
- **Overlay**: Corresponds to a JSON object, with each key representing a property name and each value representing an overlay, primitive type, or an inheritance to another overlay.
|
|
163
163
|
|
|
@@ -180,14 +180,14 @@ In the Overlay language, the primary data type is the overlay itself, which corr
|
|
|
180
180
|
|
|
181
181
|
#### 2.1.3 Relationship to JSON
|
|
182
182
|
|
|
183
|
-
|
|
183
|
+
MIXINv2's data types map directly to JSON types:
|
|
184
184
|
|
|
185
185
|
- **JSON Object → Overlay**: An overlay is defined by a JSON object where keys are property names, and values can be overlays or primitive data types.
|
|
186
|
-
- **JSON Scalar Types → Primitive Data Types**: JSON strings, numbers, booleans, and null values map directly to
|
|
186
|
+
- **JSON Scalar Types → Primitive Data Types**: JSON strings, numbers, booleans, and null values map directly to MIXINv2's corresponding primitive data types.
|
|
187
187
|
|
|
188
188
|
#### 2.1.4 No First-class List Support
|
|
189
189
|
|
|
190
|
-
Unlike JSON,
|
|
190
|
+
Unlike JSON, MIXINv2 does not support lists as a first-class type within the language itself. This means that you cannot directly define or manipulate lists in the core MIXINv2 as you would in JSON. Instead, lists are defined and manipulated through MIXINv2 standard library. This design choice maintains the simplicity and consistency of the language by focusing on overlay composition and inheritance. For scenarios requiring list-like structures or operations, MIXINv2 encourages using custom overlays to represent collections or sequences of data.
|
|
191
191
|
|
|
192
192
|
### 2.2 Properties
|
|
193
193
|
|
|
@@ -198,7 +198,7 @@ Properties are the fundamental components of an overlay, defining its internal s
|
|
|
198
198
|
|
|
199
199
|
#### Property Definition Syntax
|
|
200
200
|
|
|
201
|
-
The definition of a property resembles key-value pairs in JSON or YAML. Unlike most programming languages, property names in
|
|
201
|
+
The definition of a property resembles key-value pairs in JSON or YAML. Unlike most programming languages, property names in MIXINv2 do not need to be unique. If the same property name is defined multiple times, all definitions will always be automatically merged through multiple inheritance. This allows for the creation of complex and modular structures without conflict.
|
|
202
202
|
|
|
203
203
|
Example:
|
|
204
204
|
|
|
@@ -230,7 +230,7 @@ In this example, the `person_with_address` overlay inherits from `Person` and in
|
|
|
230
230
|
|
|
231
231
|
### 2.3 Inheritance
|
|
232
232
|
|
|
233
|
-
In
|
|
233
|
+
In MIXINv2, inheritance is the mechanism by which the current overlay inherits all properties and scalar values from another overlay. An inheritance is represented as an array of strings that indicate the path to the target overlay.
|
|
234
234
|
|
|
235
235
|
#### Grouping Property Definitions in Lists
|
|
236
236
|
|
|
@@ -264,11 +264,11 @@ In this valid example, each element within the `my_car` node begins with the `-`
|
|
|
264
264
|
|
|
265
265
|
#### Multiple Inheritance and Scalar Values
|
|
266
266
|
|
|
267
|
-
|
|
267
|
+
MIXINv2 supports conflict-free multiple inheritance and allows scalar values to be inherited from multiple sources. This means an overlay can combine properties and scalar values from multiple parent overlays without any conflict. All inherited properties and values are integrated seamlessly, resulting in a unified set of properties for the child overlay.
|
|
268
268
|
|
|
269
269
|
**Example of Multiple Inheritance with Scalar Values**
|
|
270
270
|
|
|
271
|
-
|
|
271
|
+
MIXINv2 allows scalar values to coexist and be inherited along with other properties, as shown below:
|
|
272
272
|
|
|
273
273
|
```yaml
|
|
274
274
|
Number:
|
|
@@ -283,7 +283,7 @@ In this example, `my_number` has both a scalar value `42` and inherits the `Numb
|
|
|
283
283
|
|
|
284
284
|
**Conflict-Free Inheritance**
|
|
285
285
|
|
|
286
|
-
In
|
|
286
|
+
In MIXINv2, properties with the same name defined in multiple parent overlays are always automatically merged:
|
|
287
287
|
|
|
288
288
|
```yaml
|
|
289
289
|
# basic_features.oyaml
|
|
@@ -311,21 +311,21 @@ In this example, `hybrid_car` inherits the `engine` property from both `Vehicle`
|
|
|
311
311
|
|
|
312
312
|
### 3.1 Lexical Structure
|
|
313
313
|
|
|
314
|
-
|
|
314
|
+
MIXINv2 is a language that leverages the lexical structures of JSON, YAML, and TOML, focusing on their ability to represent structured data in a clear and readable manner. This section outlines the core syntax and grammar of MIXINv2, emphasizing its usage of these formats and how they correspond to MIXINv2's data and logic constructs.
|
|
315
315
|
|
|
316
|
-
|
|
316
|
+
MIXINv2 does not have its own unique lexical structure; instead, it directly adopts the lexical structures of JSON, YAML, and TOML. This means that any syntax that can be converted into JSON is valid in MIXINv2. Specifically:
|
|
317
317
|
|
|
318
318
|
- **JSON**: Fully supported, including all standard JSON types and structures.
|
|
319
319
|
|
|
320
320
|
- **YAML**: Supported as long as it can be losslessly converted into JSON. This means that only a subset of YAML is used, excluding features such as:
|
|
321
321
|
|
|
322
322
|
- **Anchors and Aliases**: YAML constructs like `&` (anchor) and `*` (alias) are not supported as they cannot be directly represented in JSON.
|
|
323
|
-
- **Tags**: YAML's type tags (e.g., `!!str`, `!!int`) are not supported, as
|
|
323
|
+
- **Tags**: YAML's type tags (e.g., `!!str`, `!!int`) are not supported, as MIXINv2 uses its own data type system.
|
|
324
324
|
- **Complex Data Types**: Data types like sets, timestamps, and ordered mappings are not supported.
|
|
325
325
|
|
|
326
326
|
- **TOML**: Supported in its JSON-compatible subset, which includes basic data types like strings, finite numbers, booleans, and dates, but excludes date/time datatypes.
|
|
327
327
|
|
|
328
|
-
By utilizing these existing formats,
|
|
328
|
+
By utilizing these existing formats, MIXINv2 ensures a seamless integration with widely-used data serialization standards, making it easy to define complex data structures and configurations.
|
|
329
329
|
|
|
330
330
|
#### 3.1.1 Examples of Supported and Unsupported Syntax
|
|
331
331
|
|
|
@@ -378,17 +378,17 @@ data = 23:22:21.0123
|
|
|
378
378
|
|
|
379
379
|
### 4.1 Supported File Formats
|
|
380
380
|
|
|
381
|
-
|
|
381
|
+
MIXINv2 supports the following file formats for representing source code:
|
|
382
382
|
|
|
383
|
-
- **YAML**: File extension `.oyaml`.
|
|
384
|
-
- **JSON**: File extension `.ojson`.
|
|
385
|
-
- **TOML**: File extension `.otoml`.
|
|
383
|
+
- **YAML**: File extension `.mixin.yaml` (or `.mixin.yml`). Legacy: `.oyaml`, `.oyml`.
|
|
384
|
+
- **JSON**: File extension `.mixin.json`. Legacy: `.ojson`.
|
|
385
|
+
- **TOML**: File extension `.mixin.toml`. Legacy: `.otoml`.
|
|
386
386
|
|
|
387
|
-
|
|
387
|
+
MIXINv2 uses these formats to define overlays in a structured and human-readable manner. The formats share the following characteristics:
|
|
388
388
|
|
|
389
389
|
1. **JSON Compatibility**: All supported formats must be serializable to JSON. This means that only the subset of YAML and TOML that can be converted to JSON without loss of information is supported.
|
|
390
390
|
|
|
391
|
-
2. **File Extensions**: The file extension must indicate the format and its use as
|
|
391
|
+
2. **File Extensions**: The file extension must indicate the format and its use as a MIXINv2 file: `.mixin.yaml`, `.mixin.json`, or `.mixin.toml` (legacy: `.oyaml`, `.ojson`, `.otoml`).
|
|
392
392
|
|
|
393
393
|
3. **Lossless Conversion**: The language only uses features that can be converted between the supported formats without loss of information.
|
|
394
394
|
|
|
@@ -396,15 +396,15 @@ The Overlay language uses these formats to define overlays in a structured and h
|
|
|
396
396
|
|
|
397
397
|
#### 4.2.1 File Naming Conventions
|
|
398
398
|
|
|
399
|
-
- **Format**: Use lowercase letters with underscores to separate words. File names must use the `.
|
|
399
|
+
- **Format**: Use lowercase letters with underscores to separate words. File names must use the `.mixin` prefix before the format extension (e.g., `.mixin.yaml`, `.mixin.json`, `.mixin.toml`) to indicate they are MIXINv2 files. Legacy extensions `.oyaml`, `.ojson`, `.otoml` are also supported.
|
|
400
400
|
|
|
401
|
-
- **Type Definition**: Use singular nouns if defining a primary concept (e.g., `vehicle.
|
|
401
|
+
- **Type Definition**: Use singular nouns if defining a primary concept (e.g., `vehicle.mixin.yaml`). Use plural nouns if the file contains multiple instances or variations (e.g., `vehicles.mixin.yaml`).
|
|
402
402
|
|
|
403
403
|
**Examples**:
|
|
404
404
|
|
|
405
|
-
- `vehicle.
|
|
406
|
-
- `vehicles.
|
|
407
|
-
- `test_cases.
|
|
405
|
+
- `vehicle.mixin.yaml`
|
|
406
|
+
- `vehicles.mixin.yaml`
|
|
407
|
+
- `test_cases.mixin.json`
|
|
408
408
|
|
|
409
409
|
#### 4.2.2 Overlay Naming Conventions
|
|
410
410
|
|
|
@@ -425,7 +425,7 @@ Overlay names within files must follow these conventions based on their intended
|
|
|
425
425
|
|
|
426
426
|
### 4.3 Cross-File Inheritance
|
|
427
427
|
|
|
428
|
-
|
|
428
|
+
MIXINv2 allows inheriting overlays defined in different files. The rules for cross-file inheritance are as follows:
|
|
429
429
|
|
|
430
430
|
1. **Inheritance Format**:
|
|
431
431
|
|
|
@@ -439,7 +439,7 @@ the Overlay language allows inheriting overlays defined in different files. The
|
|
|
439
439
|
|
|
440
440
|
3. **Lexical Scope Resolution**:
|
|
441
441
|
|
|
442
|
-
-
|
|
442
|
+
- MIXINv2 automatically searches for inheritances starting in the current directory. If not found, it searches in the parent directory, and then the parent's parent directory, continuing upwards until the root is reached.
|
|
443
443
|
- The first segment of the inheritance looks for the overlay name in the current lexical scope, which includes:
|
|
444
444
|
|
|
445
445
|
- **Current File**: Overlays defined in the same file.
|
|
@@ -454,7 +454,7 @@ the Overlay language allows inheriting overlays defined in different files. The
|
|
|
454
454
|
|
|
455
455
|
5. **No `..` Syntax for Parent Directory**:
|
|
456
456
|
|
|
457
|
-
-
|
|
457
|
+
- MIXINv2 does not support the `..` syntax to navigate to parent directories. Instead, the language automatically searches upward through the directory structure, starting from the current directory.
|
|
458
458
|
|
|
459
459
|
#### 4.3.1 Example of Cross-File Inheritance
|
|
460
460
|
|
|
@@ -521,9 +521,9 @@ In this example:
|
|
|
521
521
|
|
|
522
522
|
### 5.1 Scope Definition
|
|
523
523
|
|
|
524
|
-
In
|
|
524
|
+
In MIXINv2, scope determines the visibility and inheritance relationships of overlays and properties within the current context. The scope structure includes sibling overlays, parent overlays, directory scope, and cross-file inheritance.
|
|
525
525
|
|
|
526
|
-
**Scope in
|
|
526
|
+
**Scope in MIXINv2 consists of the following levels**:
|
|
527
527
|
|
|
528
528
|
- **Sibling Overlays**: The names of other overlays in the same file are visible in the current scope and can be inherited using the format `[overlay_name]`. Inheritance from sibling overlays takes precedence over parent overlay inheritance.
|
|
529
529
|
|
|
@@ -533,11 +533,11 @@ In the Overlay language, scope determines the visibility and inheritance relatio
|
|
|
533
533
|
|
|
534
534
|
- **Cross-File Inheritance**: When inheriting overlays across different directories, the path must include the relative path from the current file to the target overlay.
|
|
535
535
|
|
|
536
|
-
|
|
536
|
+
MIXINv2 does not distinguish between types and values. Any overlay can represent either a data value or a type. However, in practice, type-like overlays are usually named using the UpperCamelCase convention and represent structures or behaviors to be inherited. Value-like overlays are named using lowercase letters with underscores and typically represent individual values or instances.
|
|
537
537
|
|
|
538
538
|
### 5.2 Inheritance Resolution
|
|
539
539
|
|
|
540
|
-
Inheritances in
|
|
540
|
+
Inheritances in MIXINv2 are resolved **dynamically at the time of overlay evaluation or inheritance**. The first segment of the inheritance determines how the target is identified based on the current context.
|
|
541
541
|
|
|
542
542
|
#### 5.2.1 First Segment Resolution
|
|
543
543
|
|
|
@@ -643,7 +643,7 @@ In this example:
|
|
|
643
643
|
|
|
644
644
|
#### 5.2.4 Qualified This Syntax
|
|
645
645
|
|
|
646
|
-
When a reference needs to access the dynamic `self` of an enclosing overlay (analogous to `Outer.this` in Java),
|
|
646
|
+
When a reference needs to access the dynamic `self` of an enclosing overlay (analogous to `Outer.this` in Java), MIXINv2 provides an explicit **qualified this** syntax:
|
|
647
647
|
|
|
648
648
|
```yaml
|
|
649
649
|
- [OuterOverlay, ~, property, path]
|
|
@@ -691,11 +691,11 @@ When inheriting overlays across different directories, the path must include rel
|
|
|
691
691
|
|
|
692
692
|
- **First Segment**: `path` is interpreted relative to the directory structure of the current file.
|
|
693
693
|
|
|
694
|
-
- **Resolution**:
|
|
694
|
+
- **Resolution**: MIXINv2 will automatically search for the inherited overlay by traversing the directory hierarchy.
|
|
695
695
|
|
|
696
696
|
### 5.3 Multiple Inheritance and Scalar Value Handling
|
|
697
697
|
|
|
698
|
-
|
|
698
|
+
MIXINv2 supports **conflict-free multiple inheritance**, allowing overlays to inherit properties and scalar values from multiple parent overlays without conflicts. This feature enables the flexible composition of complex structures by combining the functionalities of various overlays.
|
|
699
699
|
|
|
700
700
|
#### 5.3.1 Inheritance and Property Merging
|
|
701
701
|
|
|
@@ -729,13 +729,13 @@ In this example:
|
|
|
729
729
|
- `hybrid_car` inherits from both `Vehicle` and `Motor`.
|
|
730
730
|
- **Property Merging**:
|
|
731
731
|
- The `engine` property is defined in both parent overlays.
|
|
732
|
-
-
|
|
732
|
+
- MIXINv2 automatically merges the `engine` property without conflict.
|
|
733
733
|
- **Resulting Properties**:
|
|
734
734
|
- `hybrid_car` has access to all properties from both parents: `wheels`, `engine`, and `battery_capacity`.
|
|
735
735
|
|
|
736
736
|
#### 5.3.2 Scalar Value Merging
|
|
737
737
|
|
|
738
|
-
Scalar values (e.g., strings, numbers, booleans) can coexist with properties within an overlay and can be inherited from multiple parent overlays.
|
|
738
|
+
Scalar values (e.g., strings, numbers, booleans) can coexist with properties within an overlay and can be inherited from multiple parent overlays. MIXINv2 does not define specific rules for merging scalar values from different parents; instead, scalar values from all parents are included in the child overlay without causing errors. The **specific merging behavior** of scalar values is defined by the libraries used in conjunction with MIXINv2, allowing for different strategies depending on the application's needs.
|
|
739
739
|
|
|
740
740
|
**Example:**
|
|
741
741
|
|
|
@@ -765,7 +765,7 @@ In this example:
|
|
|
765
765
|
|
|
766
766
|
#### 5.3.3 Merging Scalar Values with Properties
|
|
767
767
|
|
|
768
|
-
An overlay can have both scalar values and properties, and these can be inherited from multiple parents.
|
|
768
|
+
An overlay can have both scalar values and properties, and these can be inherited from multiple parents. MIXINv2 allows this combination without conflicts, enabling more expressive and flexible overlay definitions.
|
|
769
769
|
|
|
770
770
|
**Example:**
|
|
771
771
|
|
|
@@ -797,7 +797,7 @@ In this example:
|
|
|
797
797
|
|
|
798
798
|
#### 5.3.4 Conflict-Free Inheritance
|
|
799
799
|
|
|
800
|
-
|
|
800
|
+
MIXINv2's approach to inheritance ensures that properties and scalar values from multiple parents are merged seamlessly. This conflict-free inheritance model eliminates issues commonly associated with multiple inheritance in other languages, such as the diamond problem.
|
|
801
801
|
|
|
802
802
|
- **Automatic Merging**: Properties with the same name are automatically merged.
|
|
803
803
|
- **No Overwriting**: Scalar values and properties from different parents do not overwrite each other unless explicitly redefined in the child overlay.
|
|
@@ -836,11 +836,11 @@ In this example:
|
|
|
836
836
|
|
|
837
837
|
## 6. Binding Rules and Examples
|
|
838
838
|
|
|
839
|
-
Inheritances in
|
|
839
|
+
Inheritances in MIXINv2 can be resolved using either **early binding** or **late binding** mechanisms. Understanding these binding rules is crucial for determining how overlays and properties are inherited and resolved during evaluation. The following example illustrates the differences between early and late binding within a single overlay structure.
|
|
840
840
|
|
|
841
841
|
### 6.1 Example
|
|
842
842
|
|
|
843
|
-
Consider the following
|
|
843
|
+
Consider the following MIXINv2 definition:
|
|
844
844
|
|
|
845
845
|
```yaml
|
|
846
846
|
test_binding:
|
|
@@ -907,7 +907,7 @@ test_binding:
|
|
|
907
907
|
|
|
908
908
|
### 6.3 Practical Guidelines
|
|
909
909
|
|
|
910
|
-
To effectively use early and late binding in
|
|
910
|
+
To effectively use early and late binding in MIXINv2:
|
|
911
911
|
|
|
912
912
|
- **Use Early Binding When**:
|
|
913
913
|
|
|
@@ -920,7 +920,7 @@ To effectively use early and late binding in the Overlay language:
|
|
|
920
920
|
|
|
921
921
|
### 6.4 Summary
|
|
922
922
|
|
|
923
|
-
In
|
|
923
|
+
In MIXINv2, choosing between early and late binding allows you to control how inheritances are resolved during inheritance and evaluation:
|
|
924
924
|
|
|
925
925
|
- **Early Binding**: Ensures a fixed inheritance that remains constant across all contexts.
|
|
926
926
|
- **Late Binding**: Provides flexibility by adapting to the current context, making it suitable for dynamic and extensible overlay definitions.
|
|
@@ -929,7 +929,7 @@ By understanding these binding rules and how the first segment of an inheritance
|
|
|
929
929
|
|
|
930
930
|
## 7. Appendices
|
|
931
931
|
|
|
932
|
-
This section provides additional resources and references to aid in the understanding of
|
|
932
|
+
This section provides additional resources and references to aid in the understanding of MIXINv2. It includes a JSON Schema reference, which defines the structure of Overlay files, and a glossary of terms used throughout the language specification.
|
|
933
933
|
|
|
934
934
|
### 7.1 JSON Schema Reference
|
|
935
935
|
|
|
@@ -968,15 +968,15 @@ The JSON Schema that defines the structure of Overlay files is maintained in [`m
|
|
|
968
968
|
|
|
969
969
|
- Represents an overlay definition. An overlay can be an inheritance to another overlay, a set of properties, or a combination of inheritance and properties.
|
|
970
970
|
|
|
971
|
-
This schema provides a structured way to define and validate overlays in
|
|
971
|
+
This schema provides a structured way to define and validate overlays in MIXINv2, ensuring consistency and correct syntax across different files and formats.
|
|
972
972
|
|
|
973
973
|
### 7.2 Glossary
|
|
974
974
|
|
|
975
|
-
This section provides definitions of key terms used in
|
|
975
|
+
This section provides definitions of key terms used in MIXINv2 specification.
|
|
976
976
|
|
|
977
|
-
- **Overlay**: The fundamental building block in
|
|
977
|
+
- **Overlay**: The fundamental building block in MIXINv2. It represents a reusable unit that can contain properties, inheritances, or scalar values. Overlays can be inherited, composed, and combined to form complex data structures and logic.
|
|
978
978
|
|
|
979
|
-
- **Inheritance**: A mechanism for pointing to another overlay or module. An inheritance is represented as an array of strings, indicating the path to the target overlay. Inheritance in
|
|
979
|
+
- **Inheritance**: A mechanism for pointing to another overlay or module. An inheritance is represented as an array of strings, indicating the path to the target overlay. Inheritance in MIXINv2 is conflict-free, allowing multiple parent overlays to be combined without error.
|
|
980
980
|
|
|
981
981
|
- **Property**: A named value within an overlay. Properties are named overlays, containing scalar values (e.g., strings, numbers), inheritances to other overlays, or nested properties. Properties define the internal structure or behavior of an overlay.
|
|
982
982
|
|
|
@@ -992,15 +992,15 @@ This section provides definitions of key terms used in the Overlay language spec
|
|
|
992
992
|
|
|
993
993
|
- **Directory Scope**: The scope defined by a directory. All overlays within a directory are part of the directory scope, and files within the directory can inherit overlays using the directory scope.
|
|
994
994
|
|
|
995
|
-
- **Cross-File Inheritance**: An inheritance that points to an overlay defined in a different file. The inheritance format includes the file name and overlay name, and
|
|
995
|
+
- **Cross-File Inheritance**: An inheritance that points to an overlay defined in a different file. The inheritance format includes the file name and overlay name, and MIXINv2 will automatically search for the target overlay within the directory hierarchy.
|
|
996
996
|
|
|
997
997
|
- **Schema**: A JSON Schema definition that describes the structure of an Overlay file. The schema defines the types, constraints, and relationships between overlays, properties, and inheritances.
|
|
998
998
|
|
|
999
|
-
- **File Format**: The supported formats for defining
|
|
999
|
+
- **File Format**: The supported formats for defining MIXINv2 source code. MIXINv2 supports YAML, JSON, and TOML, with restrictions to ensure compatibility with JSON serialization.
|
|
1000
1000
|
|
|
1001
|
-
- **Naming Convention**: The rules for naming overlays and files in
|
|
1001
|
+
- **Naming Convention**: The rules for naming overlays and files in MIXINv2. These conventions help distinguish between type-like overlays, value-like overlays, and instances, and ensure clarity and consistency in code organization.
|
|
1002
1002
|
|
|
1003
|
-
- **Conflict-Free Inheritance**:
|
|
1003
|
+
- **Conflict-Free Inheritance**: MIXINv2's approach to inheritance ensures that properties and scalar values from multiple parents are merged seamlessly without conflicts. This model eliminates issues commonly associated with multiple inheritance in other languages, such as the diamond problem.
|
|
1004
1004
|
|
|
1005
1005
|
- **Property Merging**: The process by which properties with the same name from multiple parent overlays are automatically combined into the child overlay without causing conflicts.
|
|
1006
1006
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"""
|
|
2
|
-
|
|
2
|
+
MIXINv2: A dependency injection framework with pytest-fixture-like semantics.
|
|
3
3
|
|
|
4
4
|
Public API
|
|
5
5
|
==========
|
|
@@ -67,7 +67,7 @@ if TYPE_CHECKING:
|
|
|
67
67
|
|
|
68
68
|
@final
|
|
69
69
|
class LexicalReference(Protocol):
|
|
70
|
-
"""A lexical reference following the
|
|
70
|
+
"""A lexical reference following the MIXINv2 spec resolution algorithm."""
|
|
71
71
|
|
|
72
72
|
path: tuple[Hashable, ...]
|
|
73
73
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"""
|
|
2
|
-
|
|
2
|
+
MIXINv2: A dependency injection framework with pytest-fixture-like semantics.
|
|
3
3
|
|
|
4
4
|
Design Philosophy
|
|
5
5
|
=================
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
MIXINv2 implements a dependency injection framework that combines pytest fixture-like semantics
|
|
8
8
|
with hierarchical resource structures and mixin composition patterns, inspired by
|
|
9
9
|
https://github.com/atry/mixin and https://github.com/mxmlnkn/ratarmount/pull/163.
|
|
10
10
|
|
|
@@ -378,7 +378,7 @@ Merging and Composition
|
|
|
378
378
|
Module and Package Merging
|
|
379
379
|
---------------------------
|
|
380
380
|
|
|
381
|
-
When merging modules and packages,
|
|
381
|
+
When merging modules and packages, MIXINv2 uses an algorithm similar to
|
|
382
382
|
https://github.com/atry/mixin and https://github.com/mxmlnkn/ratarmount/pull/163.
|
|
383
383
|
|
|
384
384
|
Same-Named Callable Merging Rules
|
|
@@ -1184,7 +1184,7 @@ class MixinSymbol(HasDict, Mapping[Hashable, "MixinSymbol"], Symbol):
|
|
|
1184
1184
|
symbol is expanded through its ``unions`` and their
|
|
1185
1185
|
``normalized_references``.
|
|
1186
1186
|
|
|
1187
|
-
Corresponds to the ``this`` function in the
|
|
1187
|
+
Corresponds to the ``this`` function in the inheritance-calculus paper::
|
|
1188
1188
|
|
|
1189
1189
|
this(p, p_def) = { p_site | (p_site, p_overlay) in supers(p),
|
|
1190
1190
|
s.t. p_overlay = p_def }
|
|
@@ -1681,13 +1681,17 @@ class PackageScopeDefinition(ObjectScopeDefinition):
|
|
|
1681
1681
|
|
|
1682
1682
|
@cached_property
|
|
1683
1683
|
def _mixin_files(self) -> Mapping[str, Path]:
|
|
1684
|
-
"""Discover
|
|
1684
|
+
"""Discover MIXINv2 files in the package directory."""
|
|
1685
1685
|
result: dict[str, Path] = {}
|
|
1686
1686
|
package_paths = getattr(self.underlying, "__path__", None)
|
|
1687
1687
|
if package_paths is None:
|
|
1688
1688
|
return result
|
|
1689
1689
|
|
|
1690
|
-
|
|
1690
|
+
mixin_extensions = (
|
|
1691
|
+
".mixin.yaml",
|
|
1692
|
+
".mixin.yml",
|
|
1693
|
+
".mixin.json",
|
|
1694
|
+
".mixin.toml",
|
|
1691
1695
|
".oyaml",
|
|
1692
1696
|
".oyml",
|
|
1693
1697
|
".ojson",
|
|
@@ -1701,9 +1705,9 @@ class PackageScopeDefinition(ObjectScopeDefinition):
|
|
|
1701
1705
|
if not file_path.is_file():
|
|
1702
1706
|
continue
|
|
1703
1707
|
name_lower = file_path.name.lower()
|
|
1704
|
-
for extension in
|
|
1708
|
+
for extension in mixin_extensions:
|
|
1705
1709
|
if name_lower.endswith(extension):
|
|
1706
|
-
# Extract stem: Foo.oyaml -> Foo
|
|
1710
|
+
# Extract stem: Foo.mixin.yaml -> Foo, Foo.oyaml -> Foo
|
|
1707
1711
|
stem = file_path.name[: -len(extension)]
|
|
1708
1712
|
if stem not in result:
|
|
1709
1713
|
result[stem] = file_path
|
|
@@ -2612,7 +2616,7 @@ class ResolvedReference:
|
|
|
2612
2616
|
@dataclass(frozen=True, kw_only=True, slots=True, weakref_slot=True)
|
|
2613
2617
|
class LexicalReference:
|
|
2614
2618
|
"""
|
|
2615
|
-
A lexical reference following the
|
|
2619
|
+
A lexical reference following the MIXINv2 spec resolution algorithm.
|
|
2616
2620
|
|
|
2617
2621
|
This reference type implements **lexical scoping with late-binding** and
|
|
2618
2622
|
**same-name skip semantics** (pytest fixture style).
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""
|
|
2
|
-
Directory-based
|
|
2
|
+
Directory-based MIXINv2 file discovery and evaluation.
|
|
3
3
|
|
|
4
|
-
This module provides support for evaluating
|
|
4
|
+
This module provides support for evaluating MIXINv2 files from filesystem
|
|
5
5
|
directories (not Python packages).
|
|
6
6
|
"""
|
|
7
7
|
|
|
@@ -31,9 +31,9 @@ if TYPE_CHECKING:
|
|
|
31
31
|
@dataclass(frozen=True, kw_only=True, slots=True, weakref_slot=True)
|
|
32
32
|
class DirectoryMixinDefinition(ScopeDefinition):
|
|
33
33
|
"""
|
|
34
|
-
Scope definition for a directory of
|
|
34
|
+
Scope definition for a directory of MIXINv2 files.
|
|
35
35
|
|
|
36
|
-
Recursively discovers
|
|
36
|
+
Recursively discovers MIXINv2 files (.mixin.yaml/.oyaml/etc.) and subdirectories.
|
|
37
37
|
"""
|
|
38
38
|
|
|
39
39
|
underlying: Path
|
|
@@ -41,19 +41,28 @@ class DirectoryMixinDefinition(ScopeDefinition):
|
|
|
41
41
|
|
|
42
42
|
@cached_property
|
|
43
43
|
def _mixin_files(self) -> Mapping[str, Path]:
|
|
44
|
-
"""Discover
|
|
44
|
+
"""Discover MIXINv2 files in the directory."""
|
|
45
45
|
result: dict[str, Path] = {}
|
|
46
46
|
if not self.underlying.is_dir():
|
|
47
47
|
return result
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
mixin_extensions = (
|
|
50
|
+
".mixin.yaml",
|
|
51
|
+
".mixin.yml",
|
|
52
|
+
".mixin.json",
|
|
53
|
+
".mixin.toml",
|
|
54
|
+
".oyaml",
|
|
55
|
+
".oyml",
|
|
56
|
+
".ojson",
|
|
57
|
+
".otoml",
|
|
58
|
+
)
|
|
50
59
|
for file_path in self.underlying.iterdir():
|
|
51
60
|
if not file_path.is_file():
|
|
52
61
|
continue
|
|
53
62
|
name_lower = file_path.name.lower()
|
|
54
|
-
for extension in
|
|
63
|
+
for extension in mixin_extensions:
|
|
55
64
|
if name_lower.endswith(extension):
|
|
56
|
-
# Extract stem: Foo.oyaml -> Foo
|
|
65
|
+
# Extract stem: Foo.mixin.yaml -> Foo, Foo.oyaml -> Foo
|
|
57
66
|
stem = file_path.name[: -len(extension)]
|
|
58
67
|
if stem not in result:
|
|
59
68
|
result[stem] = file_path
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""
|
|
2
|
-
Parser for
|
|
2
|
+
Parser for MIXINv2 specification files (YAML/JSON/TOML).
|
|
3
3
|
|
|
4
|
-
This module provides parsing of
|
|
4
|
+
This module provides parsing of MIXINv2 files into Definition objects that can be
|
|
5
5
|
evaluated by the overlay runtime.
|
|
6
6
|
|
|
7
7
|
.. todo::
|
|
@@ -30,7 +30,7 @@ evaluated by the overlay runtime.
|
|
|
30
30
|
- **Structural recursion**: Tree structure + naming convention enforce that
|
|
31
31
|
recursive calls are made only on structurally smaller values.
|
|
32
32
|
|
|
33
|
-
This combination enables
|
|
33
|
+
This combination enables MIXINv2 to support both finite structures (via
|
|
34
34
|
recursion/termination) and infinite structures (via corecursion/productivity),
|
|
35
35
|
similar to Haskell's lazy evaluation or Coq's coinductive types.
|
|
36
36
|
"""
|
|
@@ -66,7 +66,7 @@ JsonValue: TypeAlias = JsonScalar | list["JsonValue"] | dict[str, "JsonValue"]
|
|
|
66
66
|
@dataclass(frozen=True, kw_only=True, slots=True, weakref_slot=True)
|
|
67
67
|
class FileMixinDefinition(ScopeDefinition):
|
|
68
68
|
"""
|
|
69
|
-
Definition for a mixin parsed from
|
|
69
|
+
Definition for a mixin parsed from a MIXINv2 file.
|
|
70
70
|
|
|
71
71
|
This holds the parsed properties from the file. The `underlying` field
|
|
72
72
|
stores the raw parsed data, and properties are resolved lazily via
|
|
@@ -119,13 +119,13 @@ class ParsedMixinValue:
|
|
|
119
119
|
|
|
120
120
|
def parse_reference(array: list[JsonValue]) -> ResourceReference:
|
|
121
121
|
"""
|
|
122
|
-
Parse
|
|
122
|
+
Parse a MIXINv2 array reference into a ResourceReference.
|
|
123
123
|
|
|
124
124
|
Distinguishes between:
|
|
125
125
|
- Regular inheritance: [str, str, ...] → LexicalReference
|
|
126
126
|
- Qualified this: [str, null, str, ...] → QualifiedThisReference
|
|
127
127
|
|
|
128
|
-
:param array: The array from the
|
|
128
|
+
:param array: The array from the MIXINv2 file.
|
|
129
129
|
:return: A ResourceReference.
|
|
130
130
|
:raises ValueError: If the array is empty or has invalid format.
|
|
131
131
|
"""
|
|
@@ -163,11 +163,11 @@ def _is_reference_array(value: JsonValue) -> bool:
|
|
|
163
163
|
"""
|
|
164
164
|
Check if a value is a reference array (inheritance or qualified this).
|
|
165
165
|
|
|
166
|
-
In
|
|
166
|
+
In MIXINv2, arrays are ONLY used for references:
|
|
167
167
|
- Inheritance: [str, str, ...] - all strings
|
|
168
168
|
- Qualified this: [str, null, str, ...] - string, null, then strings
|
|
169
169
|
|
|
170
|
-
|
|
170
|
+
MIXINv2 does not have first-class list/array type.
|
|
171
171
|
"""
|
|
172
172
|
if not isinstance(value, list) or len(value) == 0:
|
|
173
173
|
return False
|
|
@@ -280,10 +280,10 @@ def parse_mixin_value(
|
|
|
280
280
|
source_file: Path, # noqa: ARG001 - reserved for future error messages
|
|
281
281
|
) -> ParsedMixinValue:
|
|
282
282
|
"""
|
|
283
|
-
Parse
|
|
283
|
+
Parse a MIXINv2 value into inheritances, properties, and scalar values.
|
|
284
284
|
|
|
285
|
-
In
|
|
286
|
-
There is no first-class list type in
|
|
285
|
+
In MIXINv2, arrays are ONLY used for references (inheritance or qualified this).
|
|
286
|
+
There is no first-class list type in MIXINv2.
|
|
287
287
|
|
|
288
288
|
A mixin value can be:
|
|
289
289
|
- A reference array: [str, str, ...] or [str, null, str, ...] → inheritance
|
|
@@ -347,31 +347,36 @@ def _parse_top_level_mixin(
|
|
|
347
347
|
|
|
348
348
|
def load_overlay_file(file_path: Path) -> JsonValue:
|
|
349
349
|
"""
|
|
350
|
-
Load and parse
|
|
350
|
+
Load and parse a MIXINv2 file (YAML/JSON/TOML) into raw JSON data.
|
|
351
351
|
|
|
352
|
-
:param file_path: Path to the
|
|
352
|
+
:param file_path: Path to the MIXINv2 file.
|
|
353
353
|
:return: The parsed JSON-compatible data (dict, list, or scalar).
|
|
354
354
|
:raises ValueError: If the file format is not recognized.
|
|
355
355
|
"""
|
|
356
356
|
content = file_path.read_text(encoding="utf-8")
|
|
357
357
|
|
|
358
358
|
name = file_path.name.lower()
|
|
359
|
-
if
|
|
359
|
+
if (
|
|
360
|
+
name.endswith(".oyaml")
|
|
361
|
+
or name.endswith(".oyml")
|
|
362
|
+
or name.endswith(".mixin.yaml")
|
|
363
|
+
or name.endswith(".mixin.yml")
|
|
364
|
+
):
|
|
360
365
|
return yaml.load(content, Loader=yaml.CSafeLoader) # noqa: S506
|
|
361
|
-
elif name.endswith(".ojson"):
|
|
366
|
+
elif name.endswith(".ojson") or name.endswith(".mixin.json"):
|
|
362
367
|
return json.loads(content)
|
|
363
|
-
elif name.endswith(".otoml"):
|
|
368
|
+
elif name.endswith(".otoml") or name.endswith(".mixin.toml"):
|
|
364
369
|
return tomllib.loads(content)
|
|
365
370
|
else:
|
|
366
371
|
raise ValueError(
|
|
367
|
-
f"Unrecognized
|
|
368
|
-
f"Expected .oyaml, .ojson, or .otoml"
|
|
372
|
+
f"Unrecognized MIXINv2 file format: {file_path.name}. "
|
|
373
|
+
f"Expected .mixin.yaml, .mixin.json, .mixin.toml, .oyaml, .ojson, or .otoml"
|
|
369
374
|
)
|
|
370
375
|
|
|
371
376
|
|
|
372
377
|
def parse_mixin_file(file_path: Path) -> Mapping[str, Sequence[Definition]]:
|
|
373
378
|
"""
|
|
374
|
-
Parse
|
|
379
|
+
Parse a MIXINv2 file (YAML/JSON/TOML) containing named top-level mixins.
|
|
375
380
|
|
|
376
381
|
The file must contain a mapping at the top level, where each key is a mixin
|
|
377
382
|
name. For files where the top level is a mixin definition itself (list or
|
|
File without changes
|
{overlay_language-0.2.0.post23.dev0 → overlay_language-0.2.0.post25.dev0}/docs/_static/favicon.svg
RENAMED
|
File without changes
|
{overlay_language-0.2.0.post23.dev0 → overlay_language-0.2.0.post25.dev0}/docs/_static/logo.svg
RENAMED
|
File without changes
|
{overlay_language-0.2.0.post23.dev0 → overlay_language-0.2.0.post25.dev0}/docs/installation.rst
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|