Skip to content

Keypath resolution and Optional: rethink null-safety vs Optional unwrapping #18

Description

@hugithordarson

Problem

KVC keypath resolution is currently null-safe: in a binding like <wo:str value="$user.address.city" />, if user or address is null, the entire keypath resolves to null. For templating this is usually exactly what you want — it lets you write concise bindings without peppering them with null checks, and rendering "nothing" for a missing intermediate value is generally the right call in a view layer.

The friction shows up once getters start returning Optional<T>. The literal workaround — $user.get.address.get.city — is ugly, and it still blows up if any segment is Optional.empty() (since Optional.get() throws on empty). So the convenient null-safe behavior we like for plain references doesn't extend naturally to Optional-returning keypaths.

Possible directions

No firm solution yet — listing options to think through:

  • Auto-unwrap Optional in keypath resolution. Treat Optional<T> as T at each segment, with Optional.empty() resolving like a null intermediate (i.e. the keypath yields null), so it composes with the existing null-safe behavior rather than fighting it.
  • Strict resolution + explicit unwrap syntax. Stop being null-safe, require explicit handling. Ergonomically rough and a departure from current semantics.
  • Opt-in via flag or syntax. E.g. tie unwrapping behavior to the ~ OGNL prefix, or gate it behind a Parsley.setOptionalUnwrapping(...) toggle, so existing apps don't silently change semantics.
  • Push the change down into the KVC layer (ng-objects) so non-template callers benefit too — vs. keeping it Parsley-local.

Things to decide

  • Where does unwrapping happen — every keypath segment, or only at terminals? Mid-keypath is the interesting case (user.address.city where address returns Optional<Address>).
  • Empty-Optional semantics: yield null (consistent with current null-safe traversal), throw, or configurable?
  • Default-on or opt-in? Changing keypath semantics for existing apps is a behavior change.
  • Scope: Parsley only, or ng-objects KVC layer?

Filing this as a design question — the existing null-safe behavior is desirable for templating; the open question is how to extend that ergonomics story to Optional-returning getters.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions