# Values that may be missing

There is no `null` or `undefined`. A type followed by `?` may hold `none`,
and reading it means handling both cases, usually with
[`match`](logic.md).

Writing another language's form is an error with an edit that writes the
Jadpo form: `null`, `nil`, `undefined` and `None` are each
`type.foreign_value`, and `??` and `?.` are `syntax.null_coalescing` and
`syntax.optional_chaining`, whose edits write the `match`.

```jadpo
type Listing = Object {
    name: ProductName
    subtitle: ProductName?
}

function headline(listing: Listing) -> ProductName {
    return match listing.subtitle {
        some(subtitle) -> subtitle
        none -> listing.name
    }
}
```

A field that may be `none` must still be given: a `Listing` must say
`subtitle: none` explicitly. Being allowed to leave a field out is a separate
idea, and only an `Input` has it:

```jadpo
type ListProducts = Input {
    name: ProductName {
        optional: true
    }
    page_size: PageSize {
        default: 25
    }
}

type RenameProduct = Input {
    name: ProductName
    subtitle: ProductName? {
        default: none
    }
}
```

- `optional: true` lets the request leave the field out. Reading it gives
  `T?`, and a field left out reads as `none`. Only an update's `patch:` tells
  "left out" apart from "sent as `none`"
  ([Reads and writes](reads-and-writes.md)).
- `default: 25` fills in a value when the request leaves the field out,
  checked against the field's rules while compiling.
- `default: none` fills in `none` for a field that may be `none`.

A value that may be `none` widens as the value itself does: a
`Customer.email?` can be used where an `Email?` is expected.
