A structure (also known as a record) is an "and" type, also known as a "product" type. This is because it contains a list of fields, each potentially of a different type, so you have this and that and the other. All the fields are simultaneously valid and available.
type
andType: struct of:
intField: int,
floatField: float,
stringField: stringvarstructVar: andTypestructVar.intField = 42structVar.floatField = 3.14structVar.stringField = "Howdy!"assert structVar is andType # base typeassert structVar.stringField is string # field type
A tagged union is an "or" type, also known as a "sum" type. This is because it can store this or that or the other. The tag keeps track of which subtype is currently valid. The strength of the tagged union is in allowing it to contain multiple types, to be used for different purposes.
Tags: enum of:
intTag1, intTag2, floatTag, stringTag
OrType1: union of thisTag: Tags:
intTag1, intTag2: int, # shared subtype
floatTag: float,
stringTag: string
var
orVar1: OrType1
orVar1.intTag1 = 42 # int
orVar1 = 21 # int
orVar1 = 3.14 # error! Can't mix types
orVar1.thisTag = stringTag # reset tag, clear data
orVar1 = "Howdy!" # string
orVar1.intTag2 = 21 # int
orVar1 += 12 # ok
orVar1.thisTag = intTag1 # reset tag, keep data
assert orVar1 == 33
assert orVar1 is OrType1 # base type
assert orVar1 == 33
assert orVar1 is OrType1 # base type
assert type of orVar1 is int # subtype
assert orVar1.thisTag == Tags.intTag1
A different sort of sum type is a typed union. You don't need an enum for the discriminator, but you can't have two or more of the same type, either. The strength of a typed union is the simplicity of use.
typeOrType2: union of type:int, float, stringvarorVar2: OrType2orVar2 = 42 # intorVar2 += 3.14 # error! Can't mix types.orVar2 = 6.28 # floatorVar2 = "Howdy!" # stringassert orVar2 is OrType2 # base typeassert type of orVar2 is string # subtype
There is also a more primitive type: the untagged union. An untagged union is like a typed union but without space for remembering the subtype, so you have to keep track of what it contains separately. It is more flexible, but much more dangerous in practical use.
typeDangerous: union of:int, floatvarintOrFloat: DangerousintOrFloat = 3.14 # floatintOrFloat = 42 # intintOrFloat += 2.5 # silent error!# This compiles and runs, but has unpredictable results.assert intOrFloat is Dangerous # base typeassert type of intOrFloat is int # error!# The subtype is not recorded.
Off topic, everything changed, for me, at your Gab site. Different color, only the Korean posting and nothing else.
ReplyDeleteHaven't said much on Gab lately. It's not been the same since they went pay to play.
Delete