# Semantics of \`Void\`

**URL:** <https://discourse.openehr.org/t/semantics-of-void/17225>\
**Category:** Specifications\
**Tags:** base\
**Created:** [21 August 2026 20:32 UTC](https://discourse.openehr.org/t/semantics-of-void/17225 "2026-08-21T20:32:04Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Mohammad\_Zawahreh](https://discourse.openehr.org/user_avatar/discourse.openehr.org/mohammad_zawahreh/32/4425_2.png) [@Mohammad\_Zawahreh](https://discourse.openehr.org/u/Mohammad_Zawahreh)\
**Post date:** [21 August 2026 20:32 UTC](https://discourse.openehr.org/t/semantics-of-void/17225/1 "2026-08-21T20:32:05Z")

</div>

Hello everyone,  
I have a quick question regarding Void and unintialised fields in OpenEHR specification. as I am working on custom serializer and deserializer. that first loads data in-memory to validate then serialize again.

- Does the concept of `Void` apply universally to **all** values to indicate a missing state, or is it only used for object references (like a null pointer)?
- for primitive data types(like `Integer`, `Real`, `Double` etc), what is their default state at construction time? Do they default to `0` / `0.0`, or do they default to an unassigned `Void` state?

for languages like Java, C# they set primitives to defaults like `0`, `false`. This would allow me also to know if:

- when `is_nullable: True` for an prop of type Integer does it mean it can have Void state, or is it just null
- Furthermore, this knowledge heavily impacts serialization and database storage. If primitives default to zero by spec definition, a serializer can safely drop fields like `magnitude: 0` entirely to reduce disk space and traffic size, knowing the deserializer will naturally reconstruct the zero.

I am Sorry if this is a basic question, but I am looking for clarity based strictly on the openEHR specification itself, rather than just how current implementations happen to handle it (which are often influenced by host-language defaults like Java).

---

<div class="post-metadata">

**Author:** ![pablo](https://discourse.openehr.org/user_avatar/discourse.openehr.org/pablo/32/3505_2.png) [@pablo](https://discourse.openehr.org/u/pablo)\
**Post date:** [21 August 2026 21:04 UTC](https://discourse.openehr.org/t/semantics-of-void/17225/2 "2026-08-21T21:04:11Z")

</div>

> [@Mohammad\_Zawahreh](#):
>
> - for primitive data types(like `Integer`, `Real`, `Double` etc), what is their default state at construction time? Do they default to `0` / `0.0`, or do they default to an unassigned `Void` state?

Those types should rely on your technology of preference since are not openEHR types, but assumed types that should be provided by the underlying programming language.

---

<div class="post-metadata">

**Author:** ![borut.jures](https://discourse.openehr.org/user_avatar/discourse.openehr.org/borut.jures/32/1391_2.png) [@borut.jures](https://discourse.openehr.org/u/borut.jures)\
**Post date:** [22 August 2026 07:23 UTC](https://discourse.openehr.org/t/semantics-of-void/17225/3 "2026-08-22T07:23:41Z")

</div>

I would avoid using 0 / 0.0 as a default for primitive number types. In Java a wrapper classes can be used `Integer` instead of `int`. These act as primitive types but can be set to `null` (Void).

In databases the `null` (Void) is almost always available for primitive types.

---

<div class="post-metadata">

**Author:** ![thomas.beale](https://discourse.openehr.org/user_avatar/discourse.openehr.org/thomas.beale/32/35_2.png) [@thomas.beale](https://discourse.openehr.org/u/thomas.beale)\
**Post date:** [23 August 2026 10:07 UTC](https://discourse.openehr.org/t/semantics-of-void/17225/4 "2026-08-23T10:07:21Z")

</div>

> [@Mohammad\_Zawahreh](#):
>
> - Does the concept of `Void` apply universally to **all** values to indicate a missing state, or is it only used for object references (like a null pointer)?

Void means the same as null in e.g. Java; it is object-level.

> [@Mohammad\_Zawahreh](#):
>
> - for primitive data types(like `Integer`, `Real`, `Double` etc), what is their default state at construction time? Do they default to `0` / `0.0`, or do they default to an unassigned `Void` state?

The spec is written such that primitive types are non-voidable, i.e. they are the same as the Java ‘unboxed’ types like `int` etc. Each type is assumed to have a default state at creation (unlike in C). Note that String is not a primitive type. An int cannot have a ‘Void’ value.

The spec assumes primitive-valued fields are mandatory. Invariants will tell you if the value matters or not.

This does indeed matter for serialised representation, and you need to create appropriate rules on what it means if a Boolean or Integer field is missing from JSON or XML. Usually you will treat missing Booleans as False and Missing Integers as 0. Then you can avoid storing mainly Booleans that have never been changed from their initial default of False.

---

<div class="post-metadata">

**Author:** ![Mohammad\_Zawahreh](https://discourse.openehr.org/user_avatar/discourse.openehr.org/mohammad_zawahreh/32/4425_2.png) [@Mohammad\_Zawahreh](https://discourse.openehr.org/u/Mohammad_Zawahreh)\
**Post date:** [24 August 2026 16:56 UTC](https://discourse.openehr.org/t/semantics-of-void/17225/5 "2026-08-24T16:56:30Z")

</div>

Thank you for reponse,  
I think the root of my confusion lies in the fact that many current implementations rely on “boxed” primitives (e.g., treating `Integer` as an object reference rather than primtive), allowing primitive types to naturally hold a `null` state. Actually, the [Foundation Types Specification](https://specifications.openehr.org/releases/BASE/development/foundation_types.html#_type_cross_reference) cross-reference table explicitly maps `Integer` to `java.lang.Integer`.

Also @borut.jures also mentioned that default values like `0` or `0.0` should be avoided in favor of wrapper classes (which aligns with the spec mapping). noting that databases natively support `null` for primitive columns. However, lets not forget that database storage formats—or serialization formats like JSONB—are simply transport and storage representations rather than the underlying formalism itself.

That is why I am asking about it,because as standard behaviour as language agnostic, when deserializing from any of of serialized formalisms (JSON, Yaml, XML ) how should is `Void/null` handled from OpenEHR point of view internally when validating. rather than leaveing to host languages, i.e if implementation is based on a language without boxed primitives it defaults missing values to `0` (or `false` for booleans) upon deserialization, it blurs the distinction between a defined zero-value and an absent (`Void`) value.

example:  
for exmple if client side sends

```json
{
    "_type": "Interval<Integer>", 
    "lower": 0,
    "upper": 1
}

```

can be stored in db as below, and when loaded by any implementation it would load lower as 0 since it is standardized?

```json
{
    "_type": "Interval<Integer>", 
    "upper": 1
}

```

**Another note** is that the distinction becomes critical as openEHR moves toward a formal Expression Language (EL). Invariant assertions and expression rules need an explicit, language-agnostic contract defining whether primitive types can evaluate to `Void`. Without a standardized rule, an expression evaluating a boolean condition like `lower > 0` might produce valid logic on a platform using boxed/nullable primitives, but throw a runtime error or yield a false positive on a platform using non-nullable value types. Standardizing this behavior ensures that rules written in EL produce identical semantic results across all execution engines.  
what do you think .

---

<div class="post-metadata">

**Author:** ![thomas.beale](https://discourse.openehr.org/user_avatar/discourse.openehr.org/thomas.beale/32/35_2.png) [@thomas.beale](https://discourse.openehr.org/u/thomas.beale)\
**Post date:** [24 August 2026 17:45 UTC](https://discourse.openehr.org/t/semantics-of-void/17225/6 "2026-08-24T17:45:02Z")

</div>

> [@Mohammad\_Zawahreh](#):
>
> can be stored in db as below, and when loaded by any implementation it would load lower as 0 since it is standardized?

These are tricks any implementation is free to use to save space or improve performance; by the time objects are fully materialised however, there should be no missing mandatory elements, which means all primitive properties are populated, as well as all mandatory non-primitive properties.

You just have to make sure your deserialisation layer implements all the rules without error 😉

You can see how some software uses Jackson heavily to do this sort of thing, also to Stringify more complex fields into single strings, and other such things. Nothing wrong with it, as long as it works.

> [@Mohammad\_Zawahreh](#):
>
> **Another note** is that the distinction becomes critical as openEHR moves toward a formal Expression Language (EL).

The EL I now have in the SPLASH framework is an evolution of the EL spec in openEHR, and treats all primitive types as non-voidable. I(f you want voidable Integers and Booleans, you need wrapper types that provide the extra value, which is usually understood as ‘unknown’. I.e. 3-valued Boolean logic. This is unnecessary to have globally, since nearly every Boolean and most if not all Integers are not Voidable; it is only in specific parts of the model that represent data from the external world that may need this facility. Hence ELEMENT.null\_flavour.

---

<div class="post-metadata">

**Author:** ![Mohammad\_Zawahreh](https://discourse.openehr.org/user_avatar/discourse.openehr.org/mohammad_zawahreh/32/4425_2.png) [@Mohammad\_Zawahreh](https://discourse.openehr.org/u/Mohammad_Zawahreh)\
**Post date:** [24 August 2026 18:15 UTC](https://discourse.openehr.org/t/semantics-of-void/17225/7 "2026-08-24T18:15:38Z")

</div>

> [@thomas.beale](#):
>
> The EL I now have in the SPLASH framework is an evolution of the EL spec in openEHR, and treats all primitive types as non-voidable.

That’s great, I am really looking forward to SPLASH.

But will it be integrated as parted the OpenEHR spec, or as seperate specification. because it would be amazing if OpenEHR have specified mature expression language to use it everywhere (invariants, ADL, pre&posconditions). Many of the current invariants strings are just hints to implementers not valid EL assertions , like using `terminlology` instead of type ref `{TERMINOLOGY_SERVICE}` thus my Interperter can’t run them.

Thank you for your time.

---

<div class="post-metadata">

**Author:** ![thomas.beale](https://discourse.openehr.org/user_avatar/discourse.openehr.org/thomas.beale/32/35_2.png) [@thomas.beale](https://discourse.openehr.org/u/thomas.beale)\
**Post date:** [26 August 2026 12:50 UTC](https://discourse.openehr.org/t/semantics-of-void/17225/8 "2026-08-26T12:50:39Z")

</div>

> [@Mohammad\_Zawahreh](#):
>
> But will it be integrated as parted the OpenEHR spec, or as seperate specification

SPLASH has no current status within openEHR; it is a separate project.

You can see the [EL meta-model within BMM4 here](https://openehr.arssemantica.com/openehr-doc/latest/languages/bmm-gen.html#_el_model_package).

I have not yet opened the relevant source repos, still working on some details.

You can [browse the BMML expression of openEHR](https://openehr.arssemantica.com/openehr-doc/latest/foundation/demographic-gen.html#_class_party_relationship), and you will see invariants and pre- and post-conditions, all in computable EL.

Example [invariants from `VERSION_TREE_ID`](https://openehr.arssemantica.com/openehr-doc/latest/representation/identification-gen.html#_class_version_tree_id).

```auto

invariant
    value_valid: ¬ value.is_empty();
    trunk_version_valid: ∃ trunk_version ∧ trunk_version.is_integer ∧ trunk_version.as_integer >= 1;
    branch_number_valid: ∃ branch_number ⇒ branch_number.is_integer ∧ branch_number.as_integer >= 1;
    branch_version_valid: ∃ branch_version ⇒ branch_version.is_integer ∧ branch_version.as_integer >= 1;
    branch_validity: (¬ ∃ branch_number ∧ ¬ ∃ branch_version) ⊻ (∃ branch_number ∧ ∃ branch_version);
    is_branch_validity: is_branch ⊻ ¬ ∃ branch_number;
    is_first_validity: ¬ is_first ⊻ trunk_version.is_equal("1");

```
