Skip to content

Default values #15

Open
Open
@badeend

Description

@badeend

TLDR, these proposed changes:

  • Allow function parameters, record fields and variant case payloads to have default values, as long as they're constant.
  • When subtyping; allow variant cases to fall back on cases which have non-unit payload.
  • Strip the option type from its special status in various places.

Definition

literal-bool ::= 'false' | 'true'
literal-char ::= '"' <core:stringelem> '"'
constant ::= unit
	| (bool <literal-bool>)
	| (s8 <core:s8>) | (u8 <core:u8>)
	| (s16 <core:s16>) | (u16 <core:u16>)
	| (s32 <core:s32>) | (u32 <core:u32>)
	| (s64 <core:s64>) | (u64 <core:u64>)
	| (float32 <core:f32>) | (float64 <core:f64>)
	| (char <literal-char>) | (string <core:string>)
	| (record (field <name> <constant>)*)
	| (variant (case <name> <constant>))
	| (list <intertype> <constant>*)

Regarding the list constant: every provided <constant> must be a subtype of the list's <intertype>.

Aliases

                 false ↦ (bool false)
                  true ↦ (bool true)
   (tuple <constant>*) ↦ (record (field "𝒊" <constant>)*) for 𝒊=0,1,...
       (flags <name>*) ↦ (record (field <name> (bool true))*)
                  none ↦ (variant (case "none" unit))
     (some <constant>) ↦ (variant (case "some" <constant>))
       (ok <constant>) ↦ (variant (case "ok" <constant>))
    (error <constant>) ↦ (variant (case "error" <constant>))

Types

Every constant expression has a fully deterministic interface type.

  • Primitive constants map 1:1 to an interface type.
  • List constants declare the element intertype in the constant expression itself.
  • Record and Variant constants generate an ad-hoc interface type derived from the constant itself. Example:
Constant:
	(record
		(field "a" (s16 42))
		(field "b" (string "Wasm"))
		(field "c" (variant (case "ok" (bool true))))
		(field "d" (list u8 (u8 3) (u8 5) (u8 8) (u8 13)))
	)

Generated type:
	(record
		(field "a" s16)
		(field "b" string)
		(field "c" (variant (case "ok" bool)))
		(field "d" (list u8))
	)

Updates to existing definitions

- (record (field <name> <intertype>)*)
+ (record (field <name> <intertype> (default <constant>)?)*)
	* <constant> must be a subtype of <intertype>


- (variant (case <name> <intertype> (refines <name>)?)*)
+ (variant (case <name> <intertype> (default <constant>)? (refines <name> <constant>?)?)*)
	* The <constant> of the `default` clause must be a subtype of <intertype> from the same case.
	* The <constant> of the `refines` clause must be a subtype of <intertype> from the case <name> refers to.
	* The <constant> in the `refines` clause is optional when the case `<name>` refers to has a `default` value.


- (func <id>? (param <name>? <intertype>)* (result <intertype>))
+ (func <id>? (param <name>? <intertype> (default <constant>)?)* (result <intertype>))
	* A param's <constant> must be a subtype of <intertype>


- (flags <name>*) ↦ (record (field <name> bool)*)
+ (flags <name>*) ↦ (record (field <name> bool (default (bool false)))*)


- (option <intertype>) ↦ (variant (case "none") (case "some" <intertype>))
+ (option <intertype>) ↦ (variant (case "none" unit (default unit)) (case "some" <intertype>))


- `record`: fields can be reordered; covariant field payload subtyping; superfluous fields can be ignored in the subtype; `option` fields can be ignored in the supertype
+ `record`: fields can be reordered; covariant field payload subtyping; superfluous fields can be ignored in the subtype; missing fields are set to the `default` value declared in the supertype.


- `func`: parameter names must match in order; contravariant parameter subtyping; superfluous parameters can be ignored in the subtype; `option` parameters can be ignored in the supertype; covariant result subtyping
+ `func`: parameter names must match in order; contravariant parameter subtyping; superfluous parameters can be ignored in the subtype; missing parameters are set to the `default` value declared in the supertype; covariant result subtyping

This is already more detailed than I intended it to be. Let me know if there is interest in pursuing this any further.

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