Skip to content

Commit

Permalink
rename structural records: tuple -> struct (digital-asset#3660)
Browse files Browse the repository at this point in the history
* rename structural records: tuple -> struct

* add missing renames (tuple -> struct) in comments, var-names and error messages

* exposition: structural vs nominal; change history note

* remove accidentilly checked-in file
  • Loading branch information
nickchapman-da authored and mergify[bot] committed Nov 28, 2019
1 parent 7c3542f commit 885bbef
Show file tree
Hide file tree
Showing 7 changed files with 35 additions and 33 deletions.
2 changes: 1 addition & 1 deletion compiler/daml-lf-tools/src/DA/Daml/LF/TypeChecker/Error.hs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ data Error
| EExpectedEnumType !(Qualified TypeConName)
| EUnknownDataCon !VariantConName
| EUnknownField !FieldName
| EExpectedStructType !Type
| EExpectedStructType !Type
| EKindMismatch {foundKind :: !Kind, expectedKind :: !Kind}
| ETypeMismatch {foundType :: !Type, expectedType :: !Type, expr :: !(Maybe Expr)}
| EExpectedHigherKind !Kind
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,13 @@ class EncodeV1Spec extends WordSpec with Matchers with TableDrivenPropertyChecks
val aTimestamp: Timestamp = 1970-01-01T00:00:00.000001Z;
val aParty: Party = 'party';
val aString: Text = "a string";
val aTuple: forall (a:*) (b:*). a -> b -> < x1: a, x2: b > = /\ (a:*) (b:*). \ (x1: a) (x2: b) ->
val aStruct: forall (a:*) (b:*). a -> b -> < x1: a, x2: b > = /\ (a:*) (b:*). \ (x1: a) (x2: b) ->
<x1 = x1, x2 = x2>;
val aTupleProj: forall (a:*) (b:*). < x1: a, x2: b > -> a = /\ (a:*) (b:*). \ (tuple: < x1: a, x2: b >) ->
(tuple).x1;
val aTupleUpd: forall (a:*) (b:*). < x1: a, x2: b > -> a -> < x1: a, x2: b > =
/\ (a:*) (b:*). \ (tuple: < x1: a, x2: b >) (x: a) ->
< tuple with x1 = x >;
val aStructProj: forall (a:*) (b:*). < x1: a, x2: b > -> a = /\ (a:*) (b:*). \ (struct: < x1: a, x2: b >) ->
(struct).x1;
val aStructUpd: forall (a:*) (b:*). < x1: a, x2: b > -> a -> < x1: a, x2: b > =
/\ (a:*) (b:*). \ (struct: < x1: a, x2: b >) (x: a) ->
< struct with x1 = x >;
val aApp: forall (a: *) (b: *) (c:*). (a -> b -> c) -> a -> b -> c =
/\ (a:*) (b:*) (c: *). \ (f: a -> b -> c) (x: a) (y: b) -> f x y;
val anEmptyList: forall (a: *). List a = /\ (a: *).
Expand Down
36 changes: 19 additions & 17 deletions daml-lf/spec/daml-lf-1.rst
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,8 @@ Version: 1.dev

* **Add** type synonyms.

* **Rename** structural records from ``Tuple`` to ``Struct``

Abstract syntax
^^^^^^^^^^^^^^^

Expand Down Expand Up @@ -475,7 +477,7 @@ DAML-LF as a "not an Ident" notation, so should not be considered for
future addition to allowed identifier characters.

In the following, we will use identifiers to represent *built-in
functions*, term and type *variable names*, record and tuple *field
functions*, term and type *variable names*, record and struct *field
names*, *variant constructors* and *template choices*. On the other
hand, we will use names to represent *type constructors*, *type synonyms*, *value
references*, and *module names*. Finally, we will use PackageId
Expand All @@ -490,7 +492,7 @@ strings as *package identifiers*. ::
Built-in function names
F ::= Ident -- Builtin

Record and tuple field names
Record and struct field names
f ::= Ident -- Field

Variant data constructors
Expand Down Expand Up @@ -579,7 +581,7 @@ Then we can define our kinds, types, and expressions::
| ∀ α : k . τ -- TyForall: Universal quantification
| BuiltinType -- TyBuiltin: Builtin type
| Mod:T -- TyCon: type constructor
| ⟨ f₁: τ₁, …, fₘ: τₘ ⟩ -- TyTuple: Tuple type
| ⟨ f₁: τ₁, …, fₘ: τₘ ⟩ -- TyStruct: Structural record type

Expressions
e ::= x -- ExpVar: Local variable
Expand Down Expand Up @@ -610,9 +612,9 @@ Then we can define our kinds, types, and expressions::
| Mod:T @τ₁ … @τₙ { e₁ 'with' f = e₂ } -- ExpRecUpdate: Record update
| Mod:T:V @τ₁ … @τₙ e -- ExpVariantCon: Variant construction
| Mod:T:E -- ExpEnumCon:Enum construction
| ⟨ f₁ = e₁, …, fₘ = eₘ ⟩ -- ExpTupleCon: Tuple construction
| e.f -- ExpTupleProj: Tuple projection
| ⟨ e₁ 'with' f = e₂ ⟩ -- ExpTupleUpdate: Tuple update
| ⟨ f₁ = e₁, …, fₘ = eₘ ⟩ -- ExpStructCon: Struct construction
| e.f -- ExpStructProj: Struct projection
| ⟨ e₁ 'with' f = e₂ ⟩ -- ExpStructUpdate: Struct update
| u -- ExpUpdate: Update expression
| 'to_any' @τ t -- ExpToAny: Wrap a value of the given type in Any
| 'from_any' @τ t -- ExpToAny: Extract a value of the given from Any or return None
Expand Down Expand Up @@ -677,7 +679,7 @@ available for usage::
Def
::=
| 'record' T (α₁: k₁)… (αₙ: kₙ) ↦ { f₁ : τ₁, …, fₘ : τₘ }
-- DefRecord
-- DefRecord: Nominal record type
| 'variant' T (α₁: k₁)… (αₙ: kₙ) ↦ V₁ : τ₁ | … | Vₘ : τₘ
-- DefVariant
| 'enum' T ↦ E₁ | … | Eₘ -- DefEnum
Expand Down Expand Up @@ -849,7 +851,7 @@ First, we formally defined *well-formed types*. ::
Γ ⊢ Mod:T : ⋆

Γ ⊢ τ₁ : ⋆ … Γ ⊢ τₙ : ⋆
————————————————————————————————————————————— TyTuple
————————————————————————————————————————————— TyStruct
Γ ⊢ ⟨ f₁: τ₁, …, fₙ: τₙ ⟩ : ⋆

'synonym' S (α₁:k₁) … (αₙ:kₙ) ↦ τ ∈ 〚Ξ〛Mod
Expand Down Expand Up @@ -1002,16 +1004,16 @@ Then we define *well-formed expressions*. ::
Γ ⊢ e : Mod:S τ₁ … τₙ

Γ ⊢ e₁ : τ₁ … Γ ⊢ eₘ : τₘ
——————————————————————————————————————————————————————————————— ExpTupleCon
——————————————————————————————————————————————————————————————— ExpStructCon
Γ ⊢ ⟨ f₁ = e₁, …, fₘ = eₘ ⟩ : ⟨ f₁: τ₁, …, fₘ: τₘ ⟩

Γ ⊢ e : ⟨ …, fᵢ: τᵢ, … ⟩
——————————————————————————————————————————————————————————————— ExpTupleProj
——————————————————————————————————————————————————————————————— ExpStructProj
Γ ⊢ e.fᵢ : τᵢ

Γ ⊢ e : ⟨ f₁: τ₁, …, fᵢ: τᵢ, …, fₙ: τₙ ⟩
Γ ⊢ eᵢ : τᵢ
——————————————————————————————————————————————————————————————— ExpTupleUpdate
——————————————————————————————————————————————————————————————— ExpStructUpdate
Γ ⊢ ⟨ e 'with' fᵢ = eᵢ ⟩ : ⟨ f₁: τ₁, …, fₙ: τₙ ⟩

'variant' T (α₁:k₁) … (αₙ:kn) ↦ … | V : τ | … ∈ 〚Ξ〛Mod
Expand Down Expand Up @@ -1204,7 +1206,7 @@ types are the types whose values can be persisted on the ledger. ::

Note that

1. Tuples are *not* serializable.
1. Structs are *not* serializable.
2. Uninhabited variant and enum types are *not* serializable.
3. For a data type to be serializable, *all* type
parameters must be instantiated with serializable types, even
Expand Down Expand Up @@ -1545,7 +1547,7 @@ need to be evaluated further. ::
⊢ᵥ Mod:T:E

⊢ᵥ e₁ ⋯ ⊢ᵥ eₘ
——————————————————————————————————————————————————— ValExpTupleCon
——————————————————————————————————————————————————— ValExpStructCon
⊢ᵥ ⟨ f₁ = e₁, …, fₘ = eₘ ⟩

⊢ᵥ e
Expand Down Expand Up @@ -1793,16 +1795,16 @@ exact output.
e₁ ‖ E₀ ⇓ Ok v₁ ‖ E₁
eₙ ‖ Eₙ₋₁ ⇓ Ok vₙ ‖ Eₙ
—————————————————————————————————————————————————————————————————————— EvExpTupleCon
—————————————————————————————————————————————————————————————————————— EvExpStructCon
⟨f₁ = e₁, …, fₙ = eₙ⟩ ‖ E₀ ⇓ Ok ⟨f₁ = v₁, …, fₙ = vₙ⟩ ‖ Eₙ

e ‖ E₀ ⇓ Ok ⟨ f₁= v₁, …, fᵢ = vᵢ, …, fₙ = vₙ ⟩ ‖ E₁
—————————————————————————————————————————————————————————————————————— EvExpTupleProj
—————————————————————————————————————————————————————————————————————— EvExpStructProj
e.fᵢ ‖ E₀ ⇓ Ok vᵢ ‖ E₁

e ‖ E₀ ⇓ Ok ⟨ f₁= v₁, …, fᵢ = vᵢ, …, fₙ = vₙ ⟩ ‖ E₁
eᵢ ‖ E₁ ⇓ Ok vᵢ' ‖ E₂
—————————————————————————————————————————————————————————————————————— EvExpTupleUpd
—————————————————————————————————————————————————————————————————————— EvExpStructUpd
⟨ e 'with' fᵢ = eᵢ ⟩ ‖ E₀
Ok ⟨ f₁= v₁, …, fᵢ= vᵢ', …, fₙ= vₙ ⟩ ‖ E₂
Expand Down Expand Up @@ -2766,7 +2768,7 @@ defined. ::
Mod:T:E ~ᵥ Mod:T:E

e₁ ~ᵥ e₁' … eₙ ~ᵥ eₙ'
——————————————————————————————————————————————————— GenEqTupleCon
——————————————————————————————————————————————————— GenEqStructCon
⟨ f₁ = e₁, …, fₘ = eₘ ⟩ ~ᵥ ⟨ f₁ = e₁', …, fₘ = eₘ' ⟩


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,13 +142,13 @@ class TypingSpec extends WordSpec with TableDrivenPropertyChecks with Matchers {
// ExpEnumCon
E"(( Mod:Color:Blue ))" ->
T"Mod:Color",
// ExpTupleCon
// ExpStructCon
E"Λ (τ₁ : ⋆) (τ₂ : ⋆). λ (e₁ : τ₁) (e₂ : τ₂) → (( ⟨ f₁ = e₁, f₂ = e₂ ⟩ ))" ->
T"∀ (τ₁ : ⋆) (τ₂ : ⋆). τ₁ → τ₂ → (( ⟨ f₁: τ₁, f₂: τ₂ ⟩ ))",
// ExpTupleProj
// ExpStructProj
E"Λ (τ₁ : ⋆) (τ₂ : ⋆). λ (e: ⟨ f₁: τ₁, f₂: τ₂ ⟩) → (( (e).f₂ ))" ->
T"∀ (τ₁ : ⋆) (τ₂ : ⋆) . ⟨ f₁: τ₁, f₂: τ₂ ⟩ → (( τ₂ ))",
// ExpTupleUpdate
// ExpStructUpdate
E"Λ (τ₁ : ⋆) (τ₂ : ⋆). λ (e: ⟨ f₁: τ₁, f₂: τ₂ ⟩) (e₂ : τ₂) → (( ⟨ e with f₂ = e₂ ⟩ ))" ->
T"∀ (τ₁ : ⋆) (τ₂ : ⋆) . ⟨ f₁: τ₁, f₂: τ₂ ⟩ → τ₂ → (( ⟨ f₁: τ₁, f₂: τ₂ ⟩ ))",
// ExpCaseVariant
Expand Down Expand Up @@ -345,11 +345,11 @@ class TypingSpec extends WordSpec with TableDrivenPropertyChecks with Matchers {
// ExpVarCon
E"Λ (σ : ⋆ → ⋆). λ (e : σ) → (( Mod:Tree:Leaf @σ e ))",
E"Λ (σ : ⋆). λ (e : σ) → (( Mod:Tree @σ Cons @σ [e] (Nil @σ) ))",
// ExpTupleCon
// ExpStructCon
E"Λ (τ₁ : ⋆) (τ₂ : ⋆). λ (e₁ : τ₁) → (( ⟨ f₁ = e₁, f₁ = e₁ ⟩ ))",
// ExpTupleProj
// ExpStructProj
E"Λ (τ₁ : ⋆) (τ₂ : ⋆). λ (e: ⟨ f₁: τ₁, f₂: τ₂ ⟩) → (( (e).f3 ))",
// ExpTupleUpdate
// ExpStructUpdate
E"Λ (τ₁ : ⋆) (τ₂ : ⋆). λ (e: ⟨ f₁: τ₁, f₂: τ₂ ⟩) (e₂ : τ₂) → (( ⟨ e with f₃ = e₂ ⟩ ))",
E"Λ (τ₁ : ⋆) (τ₂ : ⋆) (τ₃: ⋆). λ (e: ⟨ f₁: τ₁, f₂: τ₂ ⟩) (e₃: τ₃) → (( ⟨ e with f₂ = e₃ ⟩ ))",
// ExpCaseVariant
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ object Pretty {
case V.ValueGenMap(_) =>
// FIXME https://github.com/digital-asset/daml/issues/2256
throw sys.error(s"Gen Map are not supported")
case _: model.ApiImpossible => sys.error("impossible! tuples are not serializable")
case _: model.ApiImpossible => sys.error("impossible! structs are not serializable")
}

/** Outputs an object in YAML format */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ object ApiCodecVerbose {
case _: Model.ApiGenMap =>
// FIXME https://github.com/digital-asset/daml/issues/2256
serializationError(s"Gen Map are not supported")
case _: Model.ApiImpossible => serializationError("impossible! tuples are not serializable")
case _: Model.ApiImpossible => serializationError("impossible! structs are not serializable")
}

def apiListToJsValue(value: Model.ApiList): JsValue =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,7 @@ case object LedgerApiV1 {
case v: Model.ApiRecord => fillInRecordTI(v, typ, ctx)
case v: Model.ApiVariant => fillInVariantTI(v, typ, ctx)
case _: Model.ApiImpossible =>
Left(GenericConversionError("unserializable Tuple appeared of serializable type"))
Left(GenericConversionError("unserializable Struct appeared of serializable type"))
}

def readCompletion(completion: V1.completion.Completion): Result[Option[Model.CommandStatus]] = {
Expand Down

0 comments on commit 885bbef

Please sign in to comment.