ModuleMixins.jl.jl
Fuente:
Zenodo
Guardado en:
| Autor principal: | |
|---|---|
| Formato: | Recurso digital |
| Publicado: |
Zenodo
2026
|
| Acceso en línea: | |
| Etiquetas: |
Agregar Etiqueta
Sin Etiquetas, Sea el primero en etiquetar este registro!
|
| _version_ | 1866901274153189376 |
|---|---|
| author | Johan Hidding |
| author_facet | Johan Hidding |
| contents | <h2>ModuleMixins v0.3.0</h2> <p><a href="https://github.com/jhidding/ModuleMixins.jl/compare/v0.2.0...v0.3.0">Diff since v0.2.0</a></p> <h2>Changelog</h2> <ul> <li>No breaking changes.</li> <li>Refactors code and tests into modules.</li> <li>Adds major new feature: <strong>constructors</strong>.</li> </ul> <h2>Constructors</h2> <p>When you can use inheritance to compose larger objects, it would also be nice if we can construct the larger object without additional code. Suppose we have some <code>Input</code> and a <code>State</code> struct. It is good to put common definitions in a <code>Common</code> module.</p> <pre><code>using ModuleMixins module Common using Unitful export @u_str, Seconds, Kilograms, Meters, Radians, RadiansPerSecond const Seconds = typeof(1.0u"s") const Kilograms = typeof(1.0u"kg") const Meters = typeof(1.0u"m") const Radians = typeof(1.0u"rad") const RadiansPerSecond = typeof(1.0u"rad/s") end </code></pre> <p>Our very first component stores the <code>Input</code> inside the <code>State</code> for later reference:</p> <pre><code>@compose module ModelBase @kwdef struct Input end struct State{I} input::I end @constructor initial_state(input)::State[input] = (input = input,) end </code></pre> <p>Notice that we must give the return type of the constructor, and the fields that the constructor initializes using a hand-crafted syntax <code>State[input]</code> here. A constructor must always return a <code>NamedTuple</code> with those same fields. All later additions to the constructor must have the same parameter names, in this case just <code>input</code>.</p> <p>Our first real component introduces time:</p> <pre><code>@compose module Time @mixin ModelBase using ..Common @kwdef struct Input delta_t::Seconds = 0.1u"s" steps::Int = 1000 end struct State step::Int end @constructor initial_state(input)::State[step] = (step = 0,) time(state) = state.step * state.input.delta_t end </code></pre> <p>We may model a pendulum:</p> <pre><code>@compose module Pendulum using ..Common @mixin Time @kwdef struct Input length::Meters = 1.0u"m" mass::Kilograms = 1.0u"kg" initial_angle::Radians = 30.0u"deg" end struct State angle::Radians angular_velocity::RadiansPerSecond end @constructor function initial_state(input)::State[angle, angular_velocity] (angle = input.initial_angle, angular_velocity = 0.0u"rad/s") end end </code></pre> <p>See here that both long and short-form function notation is supported. We can now create an initial state using the default values for input.</p> <pre><code>Pendulum.initial_state(Pendulum.Input()) </code></pre> <p><strong>Merged pull requests:</strong></p> <ul> <li>Bump codecov/codecov-action from 4 to 5 (#6) (@dependabot[bot])</li> <li>Bump actions/checkout from 4 to 6 (#7) (@dependabot[bot])</li> <li>Bump julia-actions/cache from 2 to 3 (#8) (@dependabot[bot])</li> <li>Bump codecov/codecov-action from 5 to 6 (#9) (@dependabot[bot])</li> <li>change syntax to make constructor return fields explicit; complete introduction; change example (#10) (@jhidding)</li> </ul> |
| format | Recurso digital |
| id | zenodo_https___doi_org_10_5281_zenodo_19352556 |
| institution | Zenodo |
| language | |
| publishDate | 2026 |
| publisher | Zenodo |
| record_format | zenodo |
| spellingShingle | ModuleMixins.jl.jl Johan Hidding <h2>ModuleMixins v0.3.0</h2> <p><a href="https://github.com/jhidding/ModuleMixins.jl/compare/v0.2.0...v0.3.0">Diff since v0.2.0</a></p> <h2>Changelog</h2> <ul> <li>No breaking changes.</li> <li>Refactors code and tests into modules.</li> <li>Adds major new feature: <strong>constructors</strong>.</li> </ul> <h2>Constructors</h2> <p>When you can use inheritance to compose larger objects, it would also be nice if we can construct the larger object without additional code. Suppose we have some <code>Input</code> and a <code>State</code> struct. It is good to put common definitions in a <code>Common</code> module.</p> <pre><code>using ModuleMixins module Common using Unitful export @u_str, Seconds, Kilograms, Meters, Radians, RadiansPerSecond const Seconds = typeof(1.0u"s") const Kilograms = typeof(1.0u"kg") const Meters = typeof(1.0u"m") const Radians = typeof(1.0u"rad") const RadiansPerSecond = typeof(1.0u"rad/s") end </code></pre> <p>Our very first component stores the <code>Input</code> inside the <code>State</code> for later reference:</p> <pre><code>@compose module ModelBase @kwdef struct Input end struct State{I} input::I end @constructor initial_state(input)::State[input] = (input = input,) end </code></pre> <p>Notice that we must give the return type of the constructor, and the fields that the constructor initializes using a hand-crafted syntax <code>State[input]</code> here. A constructor must always return a <code>NamedTuple</code> with those same fields. All later additions to the constructor must have the same parameter names, in this case just <code>input</code>.</p> <p>Our first real component introduces time:</p> <pre><code>@compose module Time @mixin ModelBase using ..Common @kwdef struct Input delta_t::Seconds = 0.1u"s" steps::Int = 1000 end struct State step::Int end @constructor initial_state(input)::State[step] = (step = 0,) time(state) = state.step * state.input.delta_t end </code></pre> <p>We may model a pendulum:</p> <pre><code>@compose module Pendulum using ..Common @mixin Time @kwdef struct Input length::Meters = 1.0u"m" mass::Kilograms = 1.0u"kg" initial_angle::Radians = 30.0u"deg" end struct State angle::Radians angular_velocity::RadiansPerSecond end @constructor function initial_state(input)::State[angle, angular_velocity] (angle = input.initial_angle, angular_velocity = 0.0u"rad/s") end end </code></pre> <p>See here that both long and short-form function notation is supported. We can now create an initial state using the default values for input.</p> <pre><code>Pendulum.initial_state(Pendulum.Input()) </code></pre> <p><strong>Merged pull requests:</strong></p> <ul> <li>Bump codecov/codecov-action from 4 to 5 (#6) (@dependabot[bot])</li> <li>Bump actions/checkout from 4 to 6 (#7) (@dependabot[bot])</li> <li>Bump julia-actions/cache from 2 to 3 (#8) (@dependabot[bot])</li> <li>Bump codecov/codecov-action from 5 to 6 (#9) (@dependabot[bot])</li> <li>change syntax to make constructor return fields explicit; complete introduction; change example (#10) (@jhidding)</li> </ul> |
| title | ModuleMixins.jl.jl |
| url | https://doi.org/10.5281/zenodo.19352556 |