[{"data":1,"prerenderedAt":1332},["ShallowReactive",2],{"content-\u002Freference\u002F0.3.x\u002Ftype-system":3,"use-cases-nav":1325},{"id":4,"title":5,"author":6,"body":7,"date":6,"description":1317,"extension":1318,"meta":1319,"navigation":757,"order":84,"path":1320,"seo":1321,"stem":1322,"version":1323,"__hash__":1324},"content\u002Freference\u002F0.3.x\u002Ftype-system.md","Type System",null,{"type":8,"value":9,"toc":1301},"minimark",[10,33,62,71,106,111,114,131,135,141,158,165,196,200,203,240,243,294,300,333,337,340,365,368,387,391,394,414,418,421,442,446,449,477,481,495,526,533,556,560,563,591,594,597,605,608,633,637,644,712,724,729,732,738,819,836,901,915,921,925,928,1078,1088,1121,1125,1131,1140,1251,1254,1291,1297],[11,12,13,17,18,21,22,25,26,29,30,32],"p",{},[14,15,16],"em",{},"Finitio","'s type system is different from those you can find in a programming\nlanguage. The aim here is to capture ",[14,19,20],{},"information",", not software ",[14,23,24],{},"behavior",".\nTherefore, the definition of ",[14,27,28],{},"type"," differs. In ",[14,31,16],{},", a type is a set of\nvalues, a subtype is a subset, a supertype is a superset. That's it.",[11,34,35,36,40,41,45,46,49,50,53,54,57,58,61],{},"However, the aim here is ",[37,38,39],"strong",{},"not"," to define yet another type system with a\nfixed set of available types such as ",[42,43,44],"code",{},"boolean",", ",[42,47,48],{},"string"," and ",[42,51,52],{},"integer",", but\nrather to provide an abstract way of building ",[14,55,56],{},"information types"," and to\n'connect' them to the types available in a ",[14,59,60],{},"host"," programming language, or\ndata exchange language.",[11,63,64,65,67,68,70],{},"For this, a ",[14,66,16],{}," implementation has to define a representation function\nthat maps, for each ",[14,69,16],{}," type, a type of the host language that will\nrepresent values of the information type. This representation function is\nhost\u002Fimplementation-specific; see the documentation of the binding you use.",[72,73,78],"pre",{"className":74,"code":75,"language":76,"meta":77,"style":77},"language-finitio shiki shiki-themes github-light github-dark","Rep(FinitioType) -> HostType\n","finitio","",[42,79,80],{"__ignoreMap":77},[81,82,85,89,93,96,99,103],"span",{"class":83,"line":84},"line",1,[81,86,88],{"class":87},"sj4cs","Rep",[81,90,92],{"class":91},"sVt8B","(",[81,94,95],{"class":87},"FinitioType",[81,97,98],{"class":91},") ",[81,100,102],{"class":101},"szBVR","->",[81,104,105],{"class":87}," HostType\n",[107,108,110],"h2",{"id":109},"any-type","Any type",[11,112,113],{},"Any type captures the set of all possible 'values' representable in the\nhost language. It is mostly provided for the sake of completeness and some\nimplementation needs by specific bindings. It is occasionally useful in\n\"don't care\" situations too. Any is captured by a single dot:",[72,115,117],{"className":74,"code":116,"language":76,"meta":77,"style":77},"Any = .\n",[42,118,119],{"__ignoreMap":77},[81,120,121,125,128],{"class":83,"line":84},[81,122,124],{"class":123},"sScJk","Any",[81,126,127],{"class":101}," =",[81,129,130],{"class":87}," .\n",[107,132,134],{"id":133},"builtin-types","Builtin types",[11,136,137,138,140],{},"A builtin type starts with a dot followed by the name of an abstraction in the\nhost language, a Ruby class for instance. The set of values captured by the\n",[14,139,16],{}," type is defined the same set as the host abstraction. For instance,",[72,142,144],{"className":74,"code":143,"language":76,"meta":77,"style":77},".Integer  # The set of values captured by the Integer class\n",[42,145,146],{"__ignoreMap":77},[81,147,148,151,154],{"class":83,"line":84},[81,149,150],{"class":91},".",[81,152,153],{"class":87},"Integer",[81,155,157],{"class":156},"sJ8bj","  # The set of values captured by the Integer class\n",[11,159,160,161,164],{},"To avoid builtins being spread everywhere, it is usual to define type aliases\nand build higher-level types with those aliases instead. This also provides\nbetter host-language independence and interoperability. For instance, the\nso-called ",[14,162,163],{},"default system"," in Finitio-rb includes the following definitions:",[72,166,168],{"className":74,"code":167,"language":76,"meta":77,"style":77},"Integer = .Integer\nNil     = .NilClass\n",[42,169,170,182],{"__ignoreMap":77},[81,171,172,174,176,179],{"class":83,"line":84},[81,173,153],{"class":123},[81,175,127],{"class":101},[81,177,178],{"class":91}," .",[81,180,181],{"class":87},"Integer\n",[81,183,185,188,191,193],{"class":83,"line":184},2,[81,186,187],{"class":123},"Nil",[81,189,190],{"class":101},"     =",[81,192,178],{"class":91},[81,194,195],{"class":87},"NilClass\n",[107,197,199],{"id":198},"sub-types","Sub types",[11,201,202],{},"Sub types are subsets of values. Finitio uses so-called 'specialization by\nconstraint' to define sub types. E.g., the set of positive integers can be\ndefined as follows:",[72,204,206],{"className":74,"code":205,"language":76,"meta":77,"style":77},"Posint = Integer( i | i >= 0 )\n",[42,207,208],{"__ignoreMap":77},[81,209,210,213,215,218,221,225,228,231,234,237],{"class":83,"line":84},[81,211,212],{"class":123},"Posint",[81,214,127],{"class":101},[81,216,217],{"class":87}," Integer",[81,219,220],{"class":91},"( ",[81,222,224],{"class":223},"s4XuR","i",[81,226,227],{"class":101}," |",[81,229,230],{"class":91}," i ",[81,232,233],{"class":101},">=",[81,235,236],{"class":87}," 0",[81,238,239],{"class":91}," )\n",[11,241,242],{},"Multiple constraints can be distinguished by name:",[72,244,246],{"className":74,"code":245,"language":76,"meta":77,"style":77},"Evens = Integer( i | positive: i >= 0, even: i%2 == 0 )\n",[42,247,248],{"__ignoreMap":77},[81,249,250,253,255,257,259,261,263,266,269,271,273,275,278,281,284,287,290,292],{"class":83,"line":84},[81,251,252],{"class":123},"Evens",[81,254,127],{"class":101},[81,256,217],{"class":87},[81,258,220],{"class":91},[81,260,224],{"class":223},[81,262,227],{"class":101},[81,264,265],{"class":123}," positive",[81,267,268],{"class":91},": i ",[81,270,233],{"class":101},[81,272,236],{"class":87},[81,274,45],{"class":91},[81,276,277],{"class":123},"even",[81,279,280],{"class":91},": i",[81,282,283],{"class":101},"%",[81,285,286],{"class":87},"2",[81,288,289],{"class":101}," ==",[81,291,236],{"class":87},[81,293,239],{"class":91},[11,295,296,297,299],{},"All types can be sub-typed through constraints. In addition, Finitio uses\nstructural type equivalence, which means that the type captured by the\ndefinition of ",[42,298,252],{}," above is actually equivalent to the following one:",[72,301,303],{"className":74,"code":302,"language":76,"meta":77,"style":77},"Evens = PosInt( i | i % 2 == 0 )\n",[42,304,305],{"__ignoreMap":77},[81,306,307,309,311,314,316,318,320,322,324,327,329,331],{"class":83,"line":84},[81,308,252],{"class":123},[81,310,127],{"class":101},[81,312,313],{"class":87}," PosInt",[81,315,220],{"class":91},[81,317,224],{"class":223},[81,319,227],{"class":101},[81,321,230],{"class":91},[81,323,283],{"class":101},[81,325,326],{"class":87}," 2",[81,328,289],{"class":101},[81,330,236],{"class":87},[81,332,239],{"class":91},[107,334,336],{"id":335},"union-types","Union types",[11,338,339],{},"In some respect, union types are the dual of subtypes. They allow defining new\ntypes by generalization, through the union of the sets of values defined by\nother types. For instance, the missing Boolean type of Ruby is simply captured\nas:",[72,341,343],{"className":74,"code":342,"language":76,"meta":77,"style":77},"Boolean = .TrueClass|.FalseClass\n",[42,344,345],{"__ignoreMap":77},[81,346,347,350,352,354,357,360,362],{"class":83,"line":84},[81,348,349],{"class":123},"Boolean",[81,351,127],{"class":101},[81,353,178],{"class":91},[81,355,356],{"class":87},"TrueClass",[81,358,359],{"class":101},"|",[81,361,150],{"class":91},[81,363,364],{"class":87},"FalseClass\n",[11,366,367],{},"Union types are also very useful for capturing possibly missing information\n(aka NULL\u002Fnil). For instance, the following type will capture either an\ninteger or nil:",[72,369,371],{"className":74,"code":370,"language":76,"meta":77,"style":77},"MaybeInt = Integer|Nil\n",[42,372,373],{"__ignoreMap":77},[81,374,375,378,380,382,384],{"class":83,"line":84},[81,376,377],{"class":123},"MaybeInt",[81,379,127],{"class":101},[81,381,217],{"class":87},[81,383,359],{"class":101},[81,385,386],{"class":87},"Nil\n",[107,388,390],{"id":389},"seq-types","Seq types",[11,392,393],{},"Capturing sequences (aka arrays) of values is straightforward. Sequences are\nordered and may contain duplicates:",[72,395,397],{"className":74,"code":396,"language":76,"meta":77,"style":77},"Measures = [Posint]\n",[42,398,399],{"__ignoreMap":77},[81,400,401,404,406,409,411],{"class":83,"line":84},[81,402,403],{"class":123},"Measures",[81,405,127],{"class":101},[81,407,408],{"class":91}," [",[81,410,212],{"class":87},[81,412,413],{"class":91},"]\n",[107,415,417],{"id":416},"set-types","Set types",[11,419,420],{},"Capturing sets of values is straightforward too. Set are unordered and may not\ncontain duplicates:",[72,422,424],{"className":74,"code":423,"language":76,"meta":77,"style":77},"Hobbies = {String}\n",[42,425,426],{"__ignoreMap":77},[81,427,428,431,433,436,439],{"class":83,"line":84},[81,429,430],{"class":123},"Hobbies",[81,432,127],{"class":101},[81,434,435],{"class":91}," {",[81,437,438],{"class":87},"String",[81,440,441],{"class":91},"}\n",[107,443,445],{"id":444},"struct-types","Struct types",[11,447,448],{},"Capturing structs is straightforward too. Structs can be used to capture ordered pairs, triples, and so forth. Each struct component has its own type:",[72,450,452],{"className":74,"code":451,"language":76,"meta":77,"style":77},"Signature = \u003CString, Posint, Boolean>\n",[42,453,454],{"__ignoreMap":77},[81,455,456,459,461,464,466,468,470,472,474],{"class":83,"line":84},[81,457,458],{"class":123},"Signature",[81,460,127],{"class":101},[81,462,463],{"class":91}," \u003C",[81,465,438],{"class":87},[81,467,45],{"class":91},[81,469,212],{"class":87},[81,471,45],{"class":91},[81,473,349],{"class":87},[81,475,476],{"class":91},">\n",[107,478,480],{"id":479},"tuple-multi-tuple-types","Tuple & Multi-Tuple types",[11,482,483,484,487,488,491,492,150],{},"Tuples capture information facts. Unlike structs, tuples have ",[14,485,486],{},"named"," components called 'attributes'. Attributes must all have different names and are not particularly ordered. A set of such ",[42,489,490],{},"(name,Type)"," pairs is called a ",[14,493,494],{},"heading",[72,496,498],{"className":74,"code":497,"language":76,"meta":77,"style":77},"ProgrammingLanguage = { name: String, author: String, since: Date }\n",[42,499,500],{"__ignoreMap":77},[81,501,502,505,507,510,512,515,517,520,523],{"class":83,"line":84},[81,503,504],{"class":123},"ProgrammingLanguage",[81,506,127],{"class":101},[81,508,509],{"class":91}," { name: ",[81,511,438],{"class":87},[81,513,514],{"class":91},", author: ",[81,516,438],{"class":87},[81,518,519],{"class":91},", since: ",[81,521,522],{"class":87},"Date",[81,524,525],{"class":91}," }\n",[11,527,528,529,532],{},"By default, all attributes are mandatory. It is very useful in practice to allow optional attributes too. Multi-tuples provide such support. Multi-tuples are a very convenient shorthand over unions of tuple types. For instance,\nthe multi-tuple type below allows ",[42,530,531],{},"since"," to be omitted:",[72,534,536],{"className":74,"code":535,"language":76,"meta":77,"style":77},"{ name: String, author: String, since :? Date }\n",[42,537,538],{"__ignoreMap":77},[81,539,540,543,545,547,549,552,554],{"class":83,"line":84},[81,541,542],{"class":91},"{ name: ",[81,544,438],{"class":87},[81,546,514],{"class":91},[81,548,438],{"class":87},[81,550,551],{"class":91},", since :? ",[81,553,522],{"class":87},[81,555,525],{"class":91},[107,557,559],{"id":558},"relation-multi-relation-types","Relation & Multi-relation types",[11,561,562],{},"Relations are sets of tuples, all of which have the same heading. The notation for defining relation types naturally follows:",[72,564,566],{"className":74,"code":565,"language":76,"meta":77,"style":77},"Languages = {{ name: String, author: String, since: Date }}\n",[42,567,568],{"__ignoreMap":77},[81,569,570,573,575,578,580,582,584,586,588],{"class":83,"line":84},[81,571,572],{"class":123},"Languages",[81,574,127],{"class":101},[81,576,577],{"class":91}," {{ name: ",[81,579,438],{"class":87},[81,581,514],{"class":91},[81,583,438],{"class":87},[81,585,519],{"class":91},[81,587,522],{"class":87},[81,589,590],{"class":91}," }}\n",[11,592,593],{},"Relation types and their syntax are first-class in Finitio, most notably\nbecause of the availability of relational algebra for them, unlike pure sets\nof tuples.",[11,595,596],{},"Note that relations do not allow duplicates and have no significant ordering\nof their tuples. If the ordering is significant, you should consider a\nsequence of tuples instead:",[72,598,603],{"className":599,"code":601,"language":602},[600],"language-text","Preferences = [{ lang: String, reason: String }]\n","text",[42,604,601],{"__ignoreMap":77},[11,606,607],{},"Similarly to tuples, multi-relations allow optional attributes. For instance,",[72,609,611],{"className":74,"code":610,"language":76,"meta":77,"style":77},"Languages = {{ name: String, author: String, since :? Date }}\n",[42,612,613],{"__ignoreMap":77},[81,614,615,617,619,621,623,625,627,629,631],{"class":83,"line":84},[81,616,572],{"class":123},[81,618,127],{"class":101},[81,620,577],{"class":91},[81,622,438],{"class":87},[81,624,514],{"class":91},[81,626,438],{"class":87},[81,628,551],{"class":91},[81,630,522],{"class":87},[81,632,590],{"class":91},[107,634,636],{"id":635},"abstract-data-types","Abstract Data types",[11,638,639,640,643],{},"Abstract data types, also called user-defined types, provide the way to define\nhigher level abstractions easily and to optionally connect them to types of\nthe host language (e.g. a Ruby class). For instance, a ",[42,641,642],{},"Color"," abstraction can\nbe defined as follows:",[72,645,647],{"className":74,"code":646,"language":76,"meta":77,"style":77},"Color = \u003Crgb> {r: Byte, g: Byte, b: Byte},\n        \u003Chex> String( s | s =~ \u002F^#[0-9a-f]{6}$\u002Fi )\n",[42,648,649,680],{"__ignoreMap":77},[81,650,651,653,655,657,661,664,667,670,672,675,677],{"class":83,"line":84},[81,652,642],{"class":123},[81,654,127],{"class":101},[81,656,463],{"class":91},[81,658,660],{"class":659},"s9eBZ","rgb",[81,662,663],{"class":91},"> {r: ",[81,665,666],{"class":87},"Byte",[81,668,669],{"class":91},", g: ",[81,671,666],{"class":87},[81,673,674],{"class":91},", b: ",[81,676,666],{"class":87},[81,678,679],{"class":91},"},\n",[81,681,682,685,688,691,693,695,698,700,703,706,710],{"class":83,"line":184},[81,683,684],{"class":91},"        \u003C",[81,686,687],{"class":659},"hex",[81,689,690],{"class":91},"> ",[81,692,438],{"class":87},[81,694,220],{"class":91},[81,696,697],{"class":223},"s",[81,699,227],{"class":101},[81,701,702],{"class":91}," s ",[81,704,705],{"class":101},"=~",[81,707,709],{"class":708},"sA_wV"," \u002F^#[0-9a-f]{6}$\u002Fi",[81,711,239],{"class":91},[11,713,714,715,49,717,719,720,723],{},"The Color definition above shows that a color can be represented either by a\nRGB triple (through a tuple type), or by a hexadecimal string (e.g. #8a2be2).\n",[42,716,660],{},[42,718,687],{}," are called the ",[37,721,722],{},"information representations"," of the Color\nabstraction.",[725,726,728],"h3",{"id":727},"binding-an-adt-to-the-host-language","Binding an ADT to the host language",[11,730,731],{},"Defined as above, the type will behave as a union type, i.e. it will let pass\nvalid RGB triples and hexadecimal strings. Now, representations can be\ncomplemented to connect the Color abstraction to a host language type, e.g. a\nColor Ruby class, and raise the level of discourse on the programming side.\nThis amounts to providing one information contract per representation.",[11,733,734,735,737],{},"Suppose for example that the following ",[42,736,642],{}," class has been defined:",[72,739,743],{"className":740,"code":741,"language":742,"meta":77,"style":77},"language-ruby shiki shiki-themes github-light github-dark","class Color\n\n  def initialize(r, g, b)\n    @r, @g, @b = r, g, b\n  end\n  attr_reader :r, :g, :b\n\nend\n","ruby",[42,744,745,753,759,771,783,789,808,813],{"__ignoreMap":77},[81,746,747,750],{"class":83,"line":84},[81,748,749],{"class":101},"class",[81,751,752],{"class":123}," Color\n",[81,754,755],{"class":83,"line":184},[81,756,758],{"emptyLinePlaceholder":757},true,"\n",[81,760,762,765,768],{"class":83,"line":761},3,[81,763,764],{"class":101},"  def",[81,766,767],{"class":123}," initialize",[81,769,770],{"class":91},"(r, g, b)\n",[81,772,774,777,780],{"class":83,"line":773},4,[81,775,776],{"class":91},"    @r, @g, @b ",[81,778,779],{"class":101},"=",[81,781,782],{"class":91}," r, g, b\n",[81,784,786],{"class":83,"line":785},5,[81,787,788],{"class":101},"  end\n",[81,790,792,795,798,800,803,805],{"class":83,"line":791},6,[81,793,794],{"class":101},"  attr_reader",[81,796,797],{"class":87}," :r",[81,799,45],{"class":91},[81,801,802],{"class":87},":g",[81,804,45],{"class":91},[81,806,807],{"class":87},":b\n",[81,809,811],{"class":83,"line":810},7,[81,812,758],{"emptyLinePlaceholder":757},[81,814,816],{"class":83,"line":815},8,[81,817,818],{"class":101},"end\n",[11,820,821,822,825,826,829,830,832,833,835],{},"Connecting our information ADT to this Color class can be done through a\nbuiltin type and two explicit converters, called the ",[14,823,824],{},"dresser"," and the\n",[14,827,828],{},"undresser",": (We only show the ",[42,831,660],{}," case here; the ",[42,834,687],{}," one is defined in a\nsimilar way)",[72,837,839],{"className":74,"code":838,"language":76,"meta":77,"style":77},"Color = .Color \u003Crgb> {r: Byte, g: Byte, b: Byte}\n                     \\( tuple | Color.new(tuple.r, tuple.g, tuple.b) )\n                     \\( color | {r: color.r, g: color.g, b: color.b} )\n",[42,840,841,869,887],{"__ignoreMap":77},[81,842,843,845,847,849,851,853,855,857,859,861,863,865,867],{"class":83,"line":84},[81,844,642],{"class":123},[81,846,127],{"class":101},[81,848,178],{"class":91},[81,850,642],{"class":87},[81,852,463],{"class":91},[81,854,660],{"class":659},[81,856,663],{"class":91},[81,858,666],{"class":87},[81,860,669],{"class":91},[81,862,666],{"class":87},[81,864,674],{"class":91},[81,866,666],{"class":87},[81,868,441],{"class":91},[81,870,871,874,876,879,881,884],{"class":83,"line":184},[81,872,873],{"class":101},"                     \\",[81,875,220],{"class":91},[81,877,878],{"class":223},"tuple",[81,880,227],{"class":101},[81,882,883],{"class":87}," Color",[81,885,886],{"class":91},".new(tuple.r, tuple.g, tuple.b) )\n",[81,888,889,891,893,896,898],{"class":83,"line":761},[81,890,873],{"class":101},[81,892,220],{"class":91},[81,894,895],{"class":223},"color",[81,897,227],{"class":101},[81,899,900],{"class":91}," {r: color.r, g: color.g, b: color.b} )\n",[11,902,903,904,907,908,910,911,914],{},"The converters provide load\u002Fdump code to convert from information types to the\ncode abstraction and vice versa, thereby complementing a representation with a\nso-called ",[14,905,906],{},"information contract",". A binding of ",[14,909,16],{},", e.g. Finitio-rb,\nguarantees that the dresser will only be executed on valid representations of\nthe corresponding information type. As the dresser tends to be exposed to an\nunsafe world, however, it should always be kept ",[14,912,913],{},"pure and safe"," (no side\neffects, no metaprogramming, no code evaluation, etc.).",[11,916,917,918,920],{},"In order to keep ",[14,919,16],{}," schemas as clean as possible, implementations may\nprovide conventions-over-configuration protocols for automating information\ncontracts. Bindings typically come with so-called 'internal' and 'external'\nADT protocols.",[725,922,924],{"id":923},"internal-adt-protocol","Internal ADT protocol",[11,926,927],{},"For instance, Finitio-rb provides a more idiomatic way of connecting Ruby\nclasses to information types. The information contracts may indeed be moved to\nthe class itself, as one would probably do it, e.g. for testing purpose.",[72,929,931],{"className":740,"code":930,"language":742,"meta":77,"style":77},"class Color\n\n  def initialize(r, g, b)\n    @r, @g, @b = r, g, b\n  end\n  attr_reader :r, :g, :b\n\n  def self.rgb(tuple)\n    Color.new(tuple[:r], tuple[:g], tuple[:b])\n  end\n\n  def to_rgb\n    {r: @r, g: @g, b: @b}\n  end\n\nend\n",[42,932,933,939,943,951,959,963,977,981,991,1021,1026,1031,1039,1063,1068,1073],{"__ignoreMap":77},[81,934,935,937],{"class":83,"line":84},[81,936,749],{"class":101},[81,938,752],{"class":123},[81,940,941],{"class":83,"line":184},[81,942,758],{"emptyLinePlaceholder":757},[81,944,945,947,949],{"class":83,"line":761},[81,946,764],{"class":101},[81,948,767],{"class":123},[81,950,770],{"class":91},[81,952,953,955,957],{"class":83,"line":773},[81,954,776],{"class":91},[81,956,779],{"class":101},[81,958,782],{"class":91},[81,960,961],{"class":83,"line":785},[81,962,788],{"class":101},[81,964,965,967,969,971,973,975],{"class":83,"line":791},[81,966,794],{"class":101},[81,968,797],{"class":87},[81,970,45],{"class":91},[81,972,802],{"class":87},[81,974,45],{"class":91},[81,976,807],{"class":87},[81,978,979],{"class":83,"line":810},[81,980,758],{"emptyLinePlaceholder":757},[81,982,983,985,988],{"class":83,"line":815},[81,984,764],{"class":101},[81,986,987],{"class":123}," self.rgb",[81,989,990],{"class":91},"(tuple)\n",[81,992,994,997,999,1002,1005,1008,1011,1013,1015,1018],{"class":83,"line":993},9,[81,995,996],{"class":87},"    Color",[81,998,150],{"class":91},[81,1000,1001],{"class":101},"new",[81,1003,1004],{"class":91},"(tuple[",[81,1006,1007],{"class":87},":r",[81,1009,1010],{"class":91},"], tuple[",[81,1012,802],{"class":87},[81,1014,1010],{"class":91},[81,1016,1017],{"class":87},":b",[81,1019,1020],{"class":91},"])\n",[81,1022,1024],{"class":83,"line":1023},10,[81,1025,788],{"class":101},[81,1027,1029],{"class":83,"line":1028},11,[81,1030,758],{"emptyLinePlaceholder":757},[81,1032,1034,1036],{"class":83,"line":1033},12,[81,1035,764],{"class":101},[81,1037,1038],{"class":123}," to_rgb\n",[81,1040,1042,1045,1048,1051,1054,1057,1060],{"class":83,"line":1041},13,[81,1043,1044],{"class":91},"    {",[81,1046,1047],{"class":87},"r:",[81,1049,1050],{"class":91}," @r, ",[81,1052,1053],{"class":87},"g:",[81,1055,1056],{"class":91}," @g, ",[81,1058,1059],{"class":87},"b:",[81,1061,1062],{"class":91}," @b}\n",[81,1064,1066],{"class":83,"line":1065},14,[81,1067,788],{"class":101},[81,1069,1071],{"class":83,"line":1070},15,[81,1072,758],{"emptyLinePlaceholder":757},[81,1074,1076],{"class":83,"line":1075},16,[81,1077,818],{"class":101},[11,1079,1080,1081,49,1084,1087],{},"In Finitio-rb, the following definition, that refers to the builtin type but has\nno dresser\u002Fundresser, makes the assumption that the convention is met and\nwill use the ",[42,1082,1083],{},"Color.rgb(...)",[42,1085,1086],{},"Color#to_rgb"," methods:",[72,1089,1091],{"className":74,"code":1090,"language":76,"meta":77,"style":77},"Color = .Color \u003Crgb> {r: Byte, g: Byte, b: Byte}\n",[42,1092,1093],{"__ignoreMap":77},[81,1094,1095,1097,1099,1101,1103,1105,1107,1109,1111,1113,1115,1117,1119],{"class":83,"line":84},[81,1096,642],{"class":123},[81,1098,127],{"class":101},[81,1100,178],{"class":91},[81,1102,642],{"class":87},[81,1104,463],{"class":91},[81,1106,660],{"class":659},[81,1108,663],{"class":91},[81,1110,666],{"class":87},[81,1112,669],{"class":91},[81,1114,666],{"class":87},[81,1116,674],{"class":91},[81,1118,666],{"class":87},[81,1120,441],{"class":91},[725,1122,1124],{"id":1123},"external-adt-protocol","External ADT protocol",[11,1126,1127,1128,1130],{},"Sometimes, relying on methods provided by the abstraction itself is\nimpossible or not wanted (e.g. because it would lead to core extensions\nconsidered intrusive). For this reason, ",[14,1129,16],{}," bindings may also support\nso called 'external' protocols.",[11,1132,1133,1134,1136,1137,1139],{},"Support for example that the ",[42,1135,660],{}," information contract is not\nprovided by the ",[42,1138,642],{}," class itself and that it's not possible\nto implement it there. Finitio-rb also allows the developer to define the contract\nmethods in a specific module\u002Fclass:",[72,1141,1143],{"className":740,"code":1142,"language":742,"meta":77,"style":77},"module RgbContract\n\n  def self.dress(tuple)\n    Color.new(tuple[:r], tuple[:g], tuple[:b])\n  end\n\n  def self.undress(color)\n    { r: color.r, g: color.g, b: color.b }\n  end\n\nend\n",[42,1144,1145,1153,1157,1166,1188,1192,1196,1206,1239,1243,1247],{"__ignoreMap":77},[81,1146,1147,1150],{"class":83,"line":84},[81,1148,1149],{"class":101},"module",[81,1151,1152],{"class":123}," RgbContract\n",[81,1154,1155],{"class":83,"line":184},[81,1156,758],{"emptyLinePlaceholder":757},[81,1158,1159,1161,1164],{"class":83,"line":761},[81,1160,764],{"class":101},[81,1162,1163],{"class":123}," self.dress",[81,1165,990],{"class":91},[81,1167,1168,1170,1172,1174,1176,1178,1180,1182,1184,1186],{"class":83,"line":773},[81,1169,996],{"class":87},[81,1171,150],{"class":91},[81,1173,1001],{"class":101},[81,1175,1004],{"class":91},[81,1177,1007],{"class":87},[81,1179,1010],{"class":91},[81,1181,802],{"class":87},[81,1183,1010],{"class":91},[81,1185,1017],{"class":87},[81,1187,1020],{"class":91},[81,1189,1190],{"class":83,"line":785},[81,1191,788],{"class":101},[81,1193,1194],{"class":83,"line":791},[81,1195,758],{"emptyLinePlaceholder":757},[81,1197,1198,1200,1203],{"class":83,"line":810},[81,1199,764],{"class":101},[81,1201,1202],{"class":123}," self.undress",[81,1204,1205],{"class":91},"(color)\n",[81,1207,1208,1211,1213,1216,1219,1221,1223,1225,1228,1230,1232,1234,1237],{"class":83,"line":815},[81,1209,1210],{"class":91},"    { ",[81,1212,1047],{"class":87},[81,1214,1215],{"class":91}," color.",[81,1217,1218],{"class":123},"r",[81,1220,45],{"class":91},[81,1222,1053],{"class":87},[81,1224,1215],{"class":91},[81,1226,1227],{"class":123},"g",[81,1229,45],{"class":91},[81,1231,1059],{"class":87},[81,1233,1215],{"class":91},[81,1235,1236],{"class":123},"b",[81,1238,525],{"class":91},[81,1240,1241],{"class":83,"line":993},[81,1242,788],{"class":101},[81,1244,1245],{"class":83,"line":1023},[81,1246,758],{"emptyLinePlaceholder":757},[81,1248,1249],{"class":83,"line":1028},[81,1250,818],{"class":101},[11,1252,1253],{},"Then, in Finitio, the external contract can be specified as follows:",[72,1255,1257],{"className":74,"code":1256,"language":76,"meta":77,"style":77},"Color = .Color \u003Crgb> {r: Byte, g: Byte, b: Byte} .RgbContract\n",[42,1258,1259],{"__ignoreMap":77},[81,1260,1261,1263,1265,1267,1269,1271,1273,1275,1277,1279,1281,1283,1285,1288],{"class":83,"line":84},[81,1262,642],{"class":123},[81,1264,127],{"class":101},[81,1266,178],{"class":91},[81,1268,642],{"class":87},[81,1270,463],{"class":91},[81,1272,660],{"class":659},[81,1274,663],{"class":91},[81,1276,666],{"class":87},[81,1278,669],{"class":91},[81,1280,666],{"class":87},[81,1282,674],{"class":91},[81,1284,666],{"class":87},[81,1286,1287],{"class":91},"} .",[81,1289,1290],{"class":87},"RgbContract\n",[11,1292,1293,1294,1296],{},"The mechanism described here for abstract data types is actually more\ngeneral and applies to most of ",[14,1295,16],{},"'s work. The next section describes\ninformation contracts in more details.",[1298,1299,1300],"style",{},"html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .sA_wV, html code.shiki .sA_wV{--shiki-default:#032F62;--shiki-dark:#DBEDFF}",{"title":77,"searchDepth":761,"depth":761,"links":1302},[1303,1304,1305,1306,1307,1308,1309,1310,1311,1312],{"id":109,"depth":184,"text":110},{"id":133,"depth":184,"text":134},{"id":198,"depth":184,"text":199},{"id":335,"depth":184,"text":336},{"id":389,"depth":184,"text":390},{"id":416,"depth":184,"text":417},{"id":444,"depth":184,"text":445},{"id":479,"depth":184,"text":480},{"id":558,"depth":184,"text":559},{"id":635,"depth":184,"text":636,"children":1313},[1314,1315,1316],{"id":727,"depth":761,"text":728},{"id":923,"depth":761,"text":924},{"id":1123,"depth":761,"text":1124},"Finitio 0.3.x type system: how information types are built.","md",{},"\u002Freference\u002F0.3.x\u002Ftype-system",{"title":5,"description":1317},"reference\u002F0.3.x\u002Ftype-system","0.3.x","npVHGsMXJYkeESNIWMogje6zIjxLp27K6hLiDxXKb6k",[1326,1329],{"path":1327,"title":1328},"\u002Fuse-cases","Use cases",{"path":1330,"title":1331},"\u002Fuse-cases\u002Fcleaning-csv-files","Cleaning .csv files",1786026251329]