PageSourceSearch

https://aiken-lang.org/_next/static/chunks/pages/language-tour/modules-c15cd05385292a85.js

js aiken-lang.org collected 2026-09-25 19:54:52 UTC 71,889 bytes, 1 lines download raw bytes

1(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[365],{1017:function(e,s,n){(window.__NEXT_P=window.__NEXT_P||[]).push(["/language-tour/modules",function(){return n(7895)}])},7895:function(e,s,n){"use strict";n.r(s),n.d(s,{__toc:function(){return c}});var t=n(1527),i=n(3303),a=n(3900),o=n(2640);n(1052);var r=n(9810),l=n(9618);let c=[{depth:3,value:"Qualified imports",id:"qualified-imports"},{depth:4,value:"Custom names",id:"custom-names"},{depth:3,value:"Unqualified import",id:"unqualified-import"},{depth:2,value:"Opaque types",id:"opaque-types"},{depth:2,value:"Well-known modules",id:"well-known-modules"},{depth:3,value:"The prelude module",id:"the-prelude-module"},{depth:3,value:"The builtin module",id:"the-builtin-module"},{depth:2,value:"Conditional modules",id:"conditional-modules"},{depth:3,value:"Environments",id:"environments"},{depth:3,value:"Configurations",id:"configurations"},{depth:2,value:"Documentation",id:"documentation"},{depth:3,value:"Hiding module",id:"hiding-module"}];function d(e){let s=Object.assign({h1:"h1",p:"p",pre:"pre",code:"code",span:"span",em:"em",h3:"h3",h4:"h4",h2:"h2",a:"a",ol:"ol",li:"li"},(0,r.a)(),e.components);return l.mQ||h("Tabs",!1),l.mQ.Tab||h("Tabs.Tab",!0),(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.h1,{children:"Modules"}),"\n",(0,t.jsx)(s.p,{children:"Aiken programs are made up of bundles of functions and types called modules.\nEach module has its own namespace and can export types and values to be used\nby other modules in the program."}),"\n",(0,t.jsx)(s.pre,{"data-language":"aiken","data-theme":"default",hasCopyCode:!0,children:(0,t.jsxs)(s.code,{"data-language":"aiken","data-theme":"default",children:[(0,t.jsx)(s.span,{className:"line",children:(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:"// inside module lib/straw_hats/sunny.ak"})}),"\n",(0,t.jsx)(s.span,{className:"line",children:" "}),"\n",(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"fn"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"count_down"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"() {"})]}),"\n",(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"  "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:'"3... 2... 1..."'})]}),"\n",(0,t.jsx)(s.span,{className:"line",children:(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"}"})}),"\n",(0,t.jsx)(s.span,{className:"line",children:" "}),"\n",(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"fn"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"blast_off"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"() {"})]}),"\n",(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"  "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:'"BOOM!"'})]}),"\n",(0,t.jsx)(s.span,{className:"line",children:(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"}"})}),"\n",(0,t.jsx)(s.span,{className:"line",children:" "}),"\n",(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"pub"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"fn"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"set_sail"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"() {"})]}),"\n",(0,t.jsx)(s.span,{className:"line",children:(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"  ["})}),"\n",(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"    "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"count_down"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"}
1,children:"(),"})]}),"\n",(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"    "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"blast_off"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"(),"})]}),"\n",(0,t.jsx)(s.span,{className:"line",children:(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"  ]"})}),"\n",(0,t.jsx)(s.span,{className:"line",children:(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"}"})})]})}),"\n",(0,t.jsxs)(s.p,{children:["Here we can see a module named ",(0,t.jsx)(s.code,{children:"straw_hats/sunny"}),", the name determined by the\nfilename ",(0,t.jsx)(s.code,{children:"lib/straw_hats/sunny.ak"}),". Typically all the modules for one\nproject would live within a directory with the name of the project, such as\n",(0,t.jsx)(s.code,{children:"straw_hats"})," in this example."]}),"\n",(0,t.jsxs)(s.p,{children:["The ",(0,t.jsx)(s.code,{children:"pub"})," keyword makes this type usable from other modules."]}),"\n",(0,t.jsxs)(s.p,{children:["For the functions ",(0,t.jsx)(s.code,{children:"count_down"})," and ",(0,t.jsx)(s.code,{children:"blast_off"})," we have omitted the ",(0,t.jsx)(s.code,{children:"pub"}),"\nkeyword, so these functions are ",(0,t.jsx)(s.em,{children:"private"})," module functions. They can only be\ncalled by other functions within the same module."]}),"\n",(0,t.jsxs)(s.p,{children:["Functions, type-aliases and constants can all be exported from a module using\nthe ",(0,t.jsx)(s.code,{children:"pub"})," keyword."]}),"\n",(0,t.jsx)(s.h3,{id:"qualified-imports",children:"Qualified imports"}),"\n",(0,t.jsxs)(s.p,{children:["To use functions or types from another module we need to import them using the\n",(0,t.jsx)(s.code,{children:"use"})," keyword."]}),"\n",(0,t.jsx)(s.pre,{"data-language":"aiken","data-theme":"default",hasCopyCode:!0,children:(0,t.jsxs)(s.code,{"data-language":"aiken","data-theme":"default",children:[(0,t.jsx)(s.span,{className:"line",children:(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:"// inside module src/straw_hats/laugh_tale.ak"})}),"\n",(0,t.jsx)(s.span,{className:"line",children:" "}),"\n",(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"use"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" straw_hats"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"/"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"sunny"})]}),"\n",(0,t.jsx)(s.span,{className:"line",children:" "}),"\n",(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"pub"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"fn"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"find_the_one_piece"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"() {"})]}),"\n",(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"  sunny."}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"set_sail"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"()"})]}),"\n",(0,t.jsx)(s.span,{className:"line",children:(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"}"})})]})}),"\n",(0,t.jsx)(s.h4,{id:"custom-names",children:"Custom names"}),"\n",(0,t.jsxs)(s.p,{children:["It is also possible to give a module a custom name\nwhen importing it using the ",(0,t.jsx)(s.code,{children:"as"})," keyword."]}),"\n",(0,t.jsx)(s.pre,{"data-language":"aiken","data-theme":"default",hasCopyCode:!0,children:(0,t.jsxs)(s.code,{"data-language":"aiken","data-theme":"default",children:[(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"use"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" unix"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"/"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"dog"})]}),"\n",(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"use"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" animal"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"/"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"dog "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"as"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" kitty"})]})]})}),"\n",(0,t.jsx)(s.p,{children:"This may be useful to differentiate between multiple modules that would have\nthe same default name when imported."}),"\n",(0,t.jsxs)(s.p,{children:["The definition ",(0,t.jsx)(s.code,{children:"use straw_hats/sunny"})," creates a new variable with the name\n",(0,t.jsx)(s.code,{children:"sunny"})," and the value of the ",(0,t.jsx)(s.code,{children:"sunny"})," module."]}),"\n",(0,t.jsxs)(s.p,{children:["In the ",(0,t.jsx)(s.code,{children:"find_the_one_piece"})," function we call the imported module's public ",(0,t.jsx)(s.code,{children:"set_sail"}),"\nfunction using the ",(0,t.jsx)(s.code,{children:"."})," operator. If we had attempted to call ",(0,t.jsx)(s.code,{children:"count_down"})," it\nwould result in a compile time error as this function is private to the\n",(0,t.jsx)(s.code,{children:"sunny"})," module."]}),"\n",(0,t.jsx)(s.h3,{id:"unqualified-import",children:"Unqualified import"}),"\n",(0,t.jsx)(s.p,{children:"Values and types can also be imported in an unqualified fashion."}),"\n",(0,t.jsx)(s.pre,{"data-language":"ak","data-theme":"default",hasCopyCode:!0,children:(0,t.jsxs)(s.code,{"data-language":"ak","data-theme":"default",children:[(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"use"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" animal"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"/"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"dog.{"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"Dog"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:", stroke}"})]}),"\n",(0,t.jsx)(s.span,{className:"line",children:" "}),"\n",(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"pub"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"fn"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"foo"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"}
1,children:"() {"})]}),"\n",(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"  "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"let"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" puppy "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"="}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"Dog"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" { name: "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:'"Zeus"'}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" }"})]}),"\n",(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"  "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"stroke"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"(puppy)"})]}),"\n",(0,t.jsx)(s.span,{className:"line",children:(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"}"})})]})}),"\n",(0,t.jsx)(s.p,{children:"This may be useful for values that are used frequently in a module, but\ngenerally qualified imports are preferred as it makes it clearer where the\nvalue is defined."}),"\n",(0,t.jsx)(s.p,{children:"You may also combine unqualified imports with custom names as such:"}),"\n",(0,t.jsx)(s.pre,{"data-language":"aiken","data-theme":"default",hasCopyCode:!0,children:(0,t.jsx)(s.code,{"data-language":"aiken","data-theme":"default",children:(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"use"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" animal"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"/"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"dog.{"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"Dog"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:", stroke} "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"as"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" kitty"})]})})}),"\n",(0,t.jsx)(s.h2,{id:"opaque-types",children:"Opaque types"}),"\n",(0,t.jsx)(s.p,{children:"At times it may be useful to create a type and make the constructors and\nfields private so that users of this type can only use the type through\npublicly exported functions."}),"\n",(0,t.jsxs)(s.p,{children:["For example we can create a ",(0,t.jsx)(s.code,{children:"Counter"})," type which holds an int which can be\nincremented. We don't want the user to alter the ",(0,t.jsx)(s.code,{children:"Int"})," value other than by\nincrementing it, so we can make the type opaque to prevent them from being\nable to do this."]}),"\n",(0,t.jsx)(s.pre,{"data-language":"aiken","data-theme":"default",hasCopyCode:!0,children:(0,t.jsxs)(s.code,{"data-language":"aiken","data-theme":"default",children:[(0,t.jsx)(s.span,{className:"line",children:(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:"// The type is defined with the opaque keyword"})}),"\n",(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"pub"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"opaque"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"type"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"Counter"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" {"})]}),"\n",(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"  "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"Counter"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"(value: "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"Int"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:")"})]}),"\n",(0,t.jsx)(s.span,{className:"line",children:(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"}"})}),"\n",(0,t.jsx)(s.span,{className:"line",children:" "}),"\n",(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"pub"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"fn"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"new"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"}
1,children:"() {"})]}),"\n",(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"  "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"Counter"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"("}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:"0"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:")"})]}),"\n",(0,t.jsx)(s.span,{className:"line",children:(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"}"})}),"\n",(0,t.jsx)(s.span,{className:"line",children:" "}),"\n",(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"pub"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"fn"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"increment"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"(counter: "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"Counter"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:") {"})]}),"\n",(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"  "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"Counter"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"(counter.value "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"+"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:"1"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:")"})]}),"\n",(0,t.jsx)(s.span,{className:"line",children:(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"}"})})]})}),"\n",(0,t.jsxs)(s.p,{children:["Because the ",(0,t.jsx)(s.code,{children:"Counter"})," type has been marked as ",(0,t.jsx)(s.code,{children:"opaque"})," it is not possible for\ncode in other modules to construct or pattern match on counter values or\naccess the ",(0,t.jsx)(s.code,{children:"value"})," field. Instead other modules have to manipulate the opaque\ntype using the exported functions from the module, in this case ",(0,t.jsx)(s.code,{children:"new"})," and\n",(0,t.jsx)(s.code,{children:"increment"}),"."]}),"\n",(0,t.jsxs)(l.UW,{type:"warning",children:[(0,t.jsxs)(s.p,{children:["It isn't possible to downcast from ",(0,t.jsx)(s.span,{"data-rehype-pretty-code-fragment":"",children:(0,t.jsx)(s.code,{"data-language":"ak","data-theme":"default",children:(0,t.jsx)(s.span,{className:"line",children:(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"Data"})})})})," into an opaque type because it\nisn't generally possibly to know what restrictions applies to that type. For\nexample, imagine a ",(0,t.jsx)(s.span,{"data-rehype-pretty-code-fragment":"",children:(0,t.jsx)(s.code,{"data-language":"ak","data-theme":"default",children:(0,t.jsx)(s.span,{className:"line",children:(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"Rational"})})})})," opaque type holding a pair of integer values as\n",(0,t.jsx)(s.em,{children:"numerator"})," and ",(0,t.jsx)(s.em,{children:"denominator"}),"."]}),(0,t.jsxs)(s.p,{children:["By using an opaque type, one can ensure that the ",(0,t.jsx)(s.em,{children:"denominator"})," remains always\nnon-negative, and that both numbers remain coprime. Hence, it is in many cases\nunsafe to downcast any arbitrary pair of integer into a ",(0,t.jsx)(s.code,{children:"Rational"})," since there's\nmore than just a structural equivalence at play."]}),(0,t.jsx)(s.p,{children:"For the same reasons, it isn't possible to use an opaque type (or any type\nholding an opaque type) as a validator's datum and/or redeemer."})]}),"\n",(0,t.jsxs)(s.p,{children:["There's a ",(0,t.jsx)(s.em,{children:"special treatment"})," for an opaque type with only one constructor,\nand if that constructor has only 1 field. Under the hood, it behaves like a\nHaskell's ",(0,t.jsx)(s.code,{children:"newtype"}),". This matters when we're dealing with CBOR."]}),"\n",(0,t.jsx)(s.p,{children:"For example:"}),"\n",(0,t.jsx)(s.pre,{"data-language":"aiken","data-theme":"default",hasCopyCode:!0,children:(0,t.jsxs)(s.code,{"data-language":"aiken","data-theme":"default",children:[(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"pub"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"opaque"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"type"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"NewType"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"<"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"a"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:">"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" { field: a }"})]}),"\n",(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"pub"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"fn"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"new_type"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"(a) "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"->"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"NewType"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"<"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"a"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:">"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" { "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"NewType"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"(a) }"})]}),"\n",(0,t.jsx)(s.span,{className:"line",children:(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:".."})}),"\n",(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"trace"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"new_type"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"("}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:"43"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:") "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:"// 43"})]}),"\n",(0,t.jsx)(s.span,{className:"line",children:" "}),"\n",(0,t.jsx)(s.span,{className:"line",children:(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:"// Compare that to a non-opaque type:"})}),"\n",(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"pub"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"type"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"Constr"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"<"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"a"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:">"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" { field: a }"})]}),"\n",(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"pub"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"fn"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"new_constr"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"(a) "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"->"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"Constr"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"<"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"a"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:">"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" { "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"Constr"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"(a) }"})]}),"\n",(0,t.jsx)(s.span,{className:"line",children:(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:".."})}),"\n",(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"trace"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"new_constr"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"("}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:"43"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:") "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:"// 121([_ 43])"})]})]})}),"\n",(0,t.jsx)(s.h2,{id:"well-known-modules",children:"Well-known modules"}),"\n",(0,t.jsx)(s.h3,{id:"the-prelude-module",children:"The prelude module"}),"\n",(0,t.jsxs)(s.p,{children:["There are two modules that are built into the language, the first is the\n",(0,t.jsx)(s.code,{children:"aiken"})," prelude module. By default its types and values are automatically\nimported into every module you write, but you can still chose to import it the\nregular way. This may be useful if you have created a type or value with the\nsame name as an item from the prelude."]}),"\n",(0,t.jsx)(s.pre,{"data-language":"aiken","data-theme":"default",hasCopyCode:!0,children:(0,t.jsxs)(s.code,{"data-language":"aiken","data-theme":"default",children:[(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"use"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" aiken"})]}),"\n",(0,t.jsx)(s.span,{className:"line",children:" "}),"\n",(0,t.jsx)(s.span,{className:"line",children:(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:"/// This definition locally overrides the `Option` type"})}),"\n",(0,t.jsx)(s.span,{className:"line",children:(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:"/// and the `Some` constructor."})}),"\n",(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"pub"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"type"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"Option"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" {"})]}),"\n",(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"  "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"Some"})]}),"\n",(0,t.jsx)(s.span,{className:"line",children:(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"}"})}),"\n",(0,t.jsx)(s.span,{className:"line",children:" "}),"\n",(0,t.jsx)(s.span,{className:"line",children:(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:"/// The original `Option` and `Some` can still be used"})}),"\n",(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"pub"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"fn"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"go"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"}
1,children:"() "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"->"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" aiken."}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"Option"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"<"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"Int"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:">"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" {"})]}),"\n",(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"  aiken."}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"Some"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"("}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:"1"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:")"})]}),"\n",(0,t.jsx)(s.span,{className:"line",children:(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"}"})})]})}),"\n",(0,t.jsxs)(s.p,{children:["The content of the Prelude module is documented in ",(0,t.jsx)(s.a,{href:"https://aiken-lang.github.io/prelude/aiken.html",children:"aiken-lang/prelude"})]}),"\n",(0,t.jsx)(s.h3,{id:"the-builtin-module",children:"The builtin module"}),"\n",(0,t.jsx)(s.p,{children:"The second module that comes with the language is for exposing useful builtin\nfunctions from Plutus core. Most underlying platform functions are available\nhere using a \"snake_case\" name. Much of Aiken's syntax ends up compiling to\ncombinations of certain bultins but many aren't \"exposed\" through the syntax\nand need to be used directly. The standard library wraps these in a more\nAiken-friendly interface so you'll probably never need to use these directly\nunless you're making your own standard library."}),"\n",(0,t.jsx)(s.pre,{"data-language":"aiken","data-theme":"default",hasCopyCode:!0,children:(0,t.jsxs)(s.code,{"data-language":"aiken","data-theme":"default",children:[(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"use"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" aiken"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"/"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"builtin"})]}),"\n",(0,t.jsx)(s.span,{className:"line",children:" "}),"\n",(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"fn"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"eq"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"(a, b) {"})]}),"\n",(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"    builtin."}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"equals_integer"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"(a, b)"})]}),"\n",(0,t.jsx)(s.span,{className:"line",children:(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"}"})}),"\n",(0,t.jsx)(s.span,{className:"line",children:" "}),"\n",(0,t.jsx)(s.span,{className:"line",children:(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:"// is implicitly used when doing:"})}),"\n",(0,t.jsx)(s.span,{className:"line",children:" "}),"\n",(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"a "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"=="}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" b"})]})]})}),"\n",(0,t.jsxs)(s.p,{children:["The content of the builtin module is documented in ",(0,t.jsx)(s.a,{href:"https://aiken-lang.github.io/prelude/aiken/builtin.html",children:"aiken-lang/prelude"}),"."]}),"\n",(0,t.jsx)(s.h2,{id:"conditional-modules",children:"Conditional modules"}),"\n",(0,t.jsx)(s.h3,{id:"environments",children:"Environments"}),"\n",(0,t.jsxs)(s.p,{children:["Since ",(0,t.jsx)(s.code,{children:"v1.1.0"}),", Aiken supports conditional environment modules. Environment modules follow special rules:"]}),"\n",(0,t.jsxs)(s.ol,{children:["\n",(0,t.jsxs)(s.li,{children:["They must be located in an ",(0,t.jsx)(s.code,{children:"env"})," directory at the root of the project."]}),"\n",(0,t.jsxs)(s.li,{children:["When used, at least one of them must be called ",(0,t.jsx)(s.code,{children:"default.ak"}),"; it is used by default when no explicit module is provided."]}),"\n",(0,t.jsx)(s.li,{children:"Only one of them is available at the time, in a given compilation pass."}),"\n",(0,t.jsxs)(s.li,{children:["From within other modules, they are always referred to as ",(0,t.jsx)(s.code,{children:"env"}),", regardless of their ",(0,t.jsx)(s.em,{children:"actual name"}),"."]}),"\n"]}),"\n",(0,t.jsx)(s.p,{children:"So for example, imagine the following project structure:"}),"\n",(0,t.jsx)(s.pre,{"data-language":"text","data-theme":"default",hasCopyCode:!0,children:(0,t.jsxs)(s.code,{"data-language":"text","data-theme":"default",children:[(0,t.jsx)(s.span,{className:"line",children:(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"."})}),"\n",(0,t.jsx)(s.span,{className:"line",children:(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"├── aiken.toml"})}),"\n",(0,t.jsx)(s.span,{className:"line",children:(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"├── env"})}),"\n",(0,t.jsx)(s.span,{className:"line",children:(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"│\xa0\xa0 ├── default.ak"})}),"\n",(0,t.jsx)(s.span,{className:"line",children:(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"│\xa0\xa0 ├── preprod.ak"})}),"\n",(0,t.jsx)(s.span,{className:"line",children:(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"│\xa0\xa0 └── preview.ak"})}),"\n",(0,t.jsx)(s.span,{className:"line",children:(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"└── validators"})}),"\n",(0,t.jsx)(s.span,{className:"line",children:(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" \xa0\xa0 └── main.ak"})})]})}),"\n",(0,t.jsxs)(s.p,{children:["From within ",(0,t.jsx)(s.code,{children:"main"}),", one can assume the existence of a module ",(0,t.jsx)(s.code,{children:"env"})," and import it like any other module ",(0,t.jsx)(s.span,{"data-rehype-pretty-code-fragment":"",children:(0,t.jsx)(s.code,{"data-language":"ak","data-theme":"default",children:(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"use"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" env"})]})})}),". The content of the module depends on the ",(0,t.jsx)(s.code,{children:"--env"})," argument passed to the command used to ",(0,t.jsx)(s.code,{children:"check"})," or ",(0,t.jsx)(s.code,{children:"build"})," the project. When ",(0,t.jsx)(s.code,{children:"--env"})," is omitted, it is assumed to be ",(0,t.jsx)(s.code,{children:"default.ak"}),". Note that each of those modules must define a similar API. Usually, they will export constants that are used throughout the validator but that depend on the execution environment."]}),"\n",(0,t.jsx)(s.p,{children:"For example:"}),"\n",(0,t.jsx)(s.pre,{"data-language":"aiken","data-theme":"default",filename:"validators/main.ak",hasCopyCode:!0,children:(0,t.jsxs)(s.code,{"data-language":"aiken","data-theme":"default",children:[(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"use"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" env"})]}),"\n",(0,t.jsx)(s.span,{className:"line",children:" "}),"\n",(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"}
1,children:"validator"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"main"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"() {"})]}),"\n",(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"  "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"mint"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"(redeemer, policy_id, self)  {"})]}),"\n",(0,t.jsx)(s.span,{className:"line",children:(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"    self.signatories"})}),"\n",(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"      "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"|>"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" list."}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"has"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"(env.administrator)"})]}),"\n",(0,t.jsx)(s.span,{className:"line",children:(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"  }"})}),"\n",(0,t.jsx)(s.span,{className:"line",children:(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"}"})})]})}),"\n",(0,t.jsxs)(l.mQ,{items:["default","preprod","preview"],children:[(0,t.jsx)(l.mQ.Tab,{children:(0,t.jsx)(s.pre,{"data-language":"aiken","data-theme":"default",filename:"env/default.ak",hasCopyCode:!0,children:(0,t.jsx)(s.code,{"data-language":"aiken","data-theme":"default",children:(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"pub"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"const"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" administrator "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"="}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" #"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:'"0000000000"'})]})})})}),(0,t.jsx)(l.mQ.Tab,{children:(0,t.jsx)(s.pre,{"data-language":"aiken","data-theme":"default",filename:"env/preprod.ak",hasCopyCode:!0,children:(0,t.jsx)(s.code,{"data-language":"aiken","data-theme":"default",children:(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"pub"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"const"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" administrator "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"="}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" #"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:'"12341234"'})]})})})}),(0,t.jsx)(l.mQ.Tab,{children:(0,t.jsx)(s.pre,{"data-language":"aiken","data-theme":"default",filename:"env/preview.ak",hasCopyCode:!0,children:(0,t.jsx)(s.code,{"data-language":"aiken","data-theme":"default",children:(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"pub"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"const"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" administrator "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"="}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" #"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:'"56785678"'})]})})})})]}),"\n",(0,t.jsxs)(s.p,{children:["The environment names are not restricted (other than the usual restriction for Aiken's module names). They can contain arbitrary logic and definitions and import other modules as well as other environment modules by explicitly importing them as ",(0,t.jsx)(s.span,{"data-rehype-pretty-code-fragment":"",children:(0,t.jsx)(s.code,{"data-language":"ak","data-theme":"default",children:(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"use"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" {env}"})]})})})," (e.g. ",(0,t.jsx)(s.code,{children:"use preview"}
1),"). Rules regarding import cycles, however, still apply."]}),"\n",(0,t.jsx)(s.h3,{id:"configurations",children:"Configurations"}),"\n",(0,t.jsx)(s.p,{children:"Environment modules are quite flexible and expressive. They are useful when needing to wield complex dynamic configurations together which may even leverage other functions. In many cases though, their full power isn't needed and one only needs to define a handful of static constants. For these scenarios, Aiken provides a similar features called conditional configuration values."}),"\n",(0,t.jsxs)(s.p,{children:["Those configurations are defined directly in the ",(0,t.jsx)(s.code,{children:"aiken.toml"})," and can represent either integers, booleans, bytearrays or lists / tuples of thoses. Like environment, they expect one configuration to be named ",(0,t.jsx)(s.code,{children:"default"}),". All values under it are then injected into a special module ",(0,t.jsx)(s.span,{"data-rehype-pretty-code-fragment":"",children:(0,t.jsx)(s.code,{"data-language":"ak","data-theme":"default",children:(0,t.jsx)(s.span,{className:"line",children:(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"config"})})})})," which can be imported in the usual ways."]}),"\n",(0,t.jsx)(s.p,{children:"Here's a thorough example of a conditional configuration, with their Aiken's equivalent:"}),"\n",(0,t.jsx)(s.pre,{"data-language":"toml","data-theme":"default",filename:"aiken.toml",hasCopyCode:!0,children:(0,t.jsxs)(s.code,{"data-language":"toml","data-theme":"default",children:[(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"name "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"="}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:'"aiken-lang/scratchpad"'})]}),"\n",(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"version "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"="}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:'"1.0.0"'})]}),"\n",(0,t.jsx)(s.span,{className:"line",children:" "}),"\n",(0,t.jsx)(s.span,{className:"line",children:(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"[config.default]"})}),"\n",(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"price "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"="}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:"1000000"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"               "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:"# pub const price: Int = 1_000_000"})]}),"\n",(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"is_mainnet "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"="}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:"true"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"             "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:"# pub const is_mainnet: Bool = True"})]}),"\n",(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"network "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"="}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:'"mainnet"'}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"           "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:'# pub const network: ByteArray = "mainnet"'})]}),"\n",(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"quotas "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"="}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" ["}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:"1"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:","}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:"2"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:","}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:"3"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"]            "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:"# pub const ratio: List<Int> = [1, 2, 3]"})]}),"\n",(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"asset "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"="}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" ["}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:'"HOSKY"'}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-punctuation)"},children:","}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:"42"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"]         "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:'# pub const asset: (ByteArray, Int) = ("HOSKY", 42)'})]}),"\n",(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"[config.default.owner]        "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:'# pub const owner: ByteArray = #"0000111122223333"'})]}),"\n",(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"bytes "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"="}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:'"0000111122223333"'})]}),"\n",(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"encoding "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"="}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-string-expression)"},children:'"hex"'})]})]})}
1),"\n",(0,t.jsx)(s.p,{children:"Then, one can refer to any of the configuration value as they would from a standard module:"}),"\n",(0,t.jsx)(s.pre,{"data-language":"aiken","data-theme":"default",hasCopyCode:!0,children:(0,t.jsxs)(s.code,{"data-language":"aiken","data-theme":"default",children:[(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"use"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" config"})]}),"\n",(0,t.jsx)(s.span,{className:"line",children:" "}),"\n",(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"fn"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-function)"},children:"main"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"() {"})]}),"\n",(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"  "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"if"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" config.is_mainnet {"})]}),"\n",(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"    config.price "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"*"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-constant)"},children:"2"})]}),"\n",(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"  } "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:"else"}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:" {"})]}),"\n",(0,t.jsxs)(s.span,{className:"line",children:[(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"    "}),(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-keyword)"},children:".."})]}),"\n",(0,t.jsx)(s.span,{className:"line",children:(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"  }"})}),"\n",(0,t.jsx)(s.span,{className:"line",children:(0,t.jsx)(s.span,{style:{color:"var(--shiki-color-text)"},children:"}"})})]})}),"\n",(0,t.jsxs)(s.p,{children:["Like conditional environment modules, the ",(0,t.jsx)(s.code,{children:"--env"})," option drives the selection of the right configuration values. Yet unlike modules, configuration values cannot refer to other configuration values, and are limited to what the TOML syntax supports."]}),"\n",(0,t.jsx)(s.h2,{id:"documentation",children:"Documentation"}),"\n",(0,t.jsxs)(s.p,{children:["You may add user-facing documentation at the head of modules with a module\ndocumentation comment ",(0,t.jsx)(s.code,{children:"////"})," (quadruple slash!) per line. Markdown is supported\nand this text block will be included with the module's entry in generated HTML\ndocumentation."]}),"\n",(0,t.jsx)(s.h3,{id:"hiding-module",children:"Hiding module"}),"\n",(0,t.jsx)(s.p,{children:"At times, you may want to hide modules from the generated documentation because\nthey may contains internal functions that are not relevant to expose to any\nusers, but split out for various reasons."}),"\n",(0,t.jsxs)(s.p,{children:["To hide a module, you can start the module documentation with the tag ",(0,t.jsx)(s.code,{children:"@hidden"}),"."]}),"\n",(0,t.jsx)(s.pre,{"data-language":"aiken","data-theme":"default",hasCopyCode:!0,children:(0,t.jsxs)(s.code,{"data-language":"aiken","data-theme":"default",children:[(0,t.jsx)(s.span,{className:"line",children:(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:"//// @hidden"})}),"\n",(0,t.jsx)(s.span,{className:"line",children:(0,t.jsx)(s.span,{style:{color:"var(--shiki-token-comment)"},children:"//// Some more documentation"})})]})})]})}function h(e,s){throw Error("Expected "+(s?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}let p={MDXContent:function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{wrapper:s}=Object.assign({},(0,r.a)(),e.components);return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(d,{...e})}):d(e)},pageOpts:{filePath:"src/pages/language-tour/modules.mdx",route:"/language-tour/modules",frontMatter:{title:"Modules",description:"Aiken is a functional programming language for Cardano smart contracts where code is organized into reusable bundles called modules. Modules are files containing functions, types, and constants, with their namespace determined by file path. Used to structure projects, share code between validators, import the standard library, and control visibility with pub.",difficulty:"beginner",keywords:["modules","use","import","pub","namespace","opaque types","standard library","stdlib","prelude","aiken.toml","dependencies"],topics:["modules","imports","namespaces","visibility","stdlib"],prerequisites:["functions","custom-types"],related:["functions","custom-types","tests"]},pageMap:[{kind:"Meta",data:{index:{title:"Aiken",type:"page",display:"hidden",theme:{layout:"raw"}},"user-manual":{title:"Documentation",type:"page",href:"/installation-instructions"},stdlib:{title:"Standard library",type:"page",href:"https://aiken-lang.github.io/stdlib/"},packages:{title:"Packages",type:"page",href:"https://packages.aiken-lang.org"},playground:{title:"Playground",type:"page",href:"https://play.aiken-lang.org"},about:{title:"About",type:"page",href:"/credits"},"-- Basics --":{type:"separator",title:"Basics"},"installation-instructions":"Installation",fundamentals:"Fundamentals","language-tour":"Language Tour","-- Examples --":{type:"separator",title:"Examples"},"example--hello-world":"Hello, World!","example--vesting":"Vesting","example--gift-card":"Gift Card","-- Advanced --":{type:"separator",title:"Advanced"},"optimizing-programs":"Optimizing Programs",uplc:"Untyped Plutus Core","-- Appendix --":{type:"separator",title:"Ap
1pendix"},"ecosystem-overview":"Ecosystem Overview",resources:"Resources",glossary:"Glossary",faq:"F.A.Q.",credits:{title:"About",display:"hidden",theme:{breadcrumb:!1,footer:!0,sidebar:!1,toc:!1,pagination:!1}}}},{kind:"MdxPage",name:"credits",route:"/credits"},{kind:"MdxPage",name:"ecosystem-overview",route:"/ecosystem-overview",frontMatter:{title:"Ecosystem Overview",description:"Aiken is a functional programming language for Cardano smart contracts that compiles to Untyped Plutus Core (UPLC). The ecosystem overview compares the alternative languages for writing Cardano validators — including PlutusTx (Haskell-based), OpShin (Python-based), Helios (JavaScript-based), and Plu-ts (TypeScript-based) — and clarifies that all ultimately compile to UPLC. Helps developers understand how Aiken fits alongside other Cardano development tools.",difficulty:"beginner",keywords:["ecosystem","PlutusTx","OpShin","Helios","Plu-ts","UPLC","Untyped Plutus Core","Haskell","comparison","smart contract languages","Cardano"],topics:["ecosystem","language-comparison","plutustx","opshin","helios"],prerequisites:[],related:["getting-started","eutxo"]}},{kind:"MdxPage",name:"example--gift-card",route:"/example--gift-card"},{kind:"Folder",name:"example--hello-world",route:"/example--hello-world",children:[{kind:"Meta",data:{basics:"First steps","end-to-end":"End-to-End"}},{kind:"MdxPage",name:"basics",route:"/example--hello-world/basics"},{kind:"Folder",name:"end-to-end",route:"/example--hello-world/end-to-end",children:[{kind:"Meta",data:{mesh:"with Mesh (TypeScript)",pycardano:"with PyCardano (Python)","cardano-cli":"with cardano-cli (CLI)"}},{kind:"MdxPage",name:"cardano-cli",route:"/example--hello-world/end-to-end/cardano-cli"},{kind:"MdxPage",name:"mesh",route:"/example--hello-world/end-to-end/mesh"},{kind:"MdxPage",name:"pycardano",route:"/example--hello-world/end-to-end/pycardano"}]}]},{kind:"Folder",name:"example--vesting",route:"/example--vesting",children:[{kind:"Meta",data:{mesh:"with Mesh (JavaScript)"}},{kind:"MdxPage",name:"mesh",route:"/example--vesting/mesh"}]},{kind:"MdxPage",name:"faq",route:"/faq"},{kind:"Folder",name:"fundamentals",route:"/fundamentals",children:[{kind:"Meta",data:{"getting-started":"Getting Started",eutxo:"EUTxO Crash Course","common-design-patterns":"Common Design Patterns","what-i-wish-i-knew":"What I Wish I Knew"}},{kind:"MdxPage",name:"common-design-patterns",route:"/fundamentals/common-design-patterns",frontMatter:{title:"Common Design Patterns",description:"Aiken is a functional programming language for Cardano smart contracts built on the EUTxO model. Common design patterns are proven architectural approaches refined across Plutus V1, V2, and V3 — including enforcing output uniqueness, one-shot minting policies, the withdraw-zero trick, and avoiding double-satisfaction vulnerabilities. A reference for writing secure, efficient validators that correctly handle EUTxO-based smart contract challenges.",difficulty:"intermediate",keywords:["design patterns","double satisfaction","output uniqueness","one-shot minting","withdraw zero","Plutus V1","Plutus V2","Plutus V3","security","anti-patterns"],topics:["design-patterns","security","best-practices","eutxo-patterns"],prerequisites:["eutxo","validators"],related:["eutxo","validators","what-i-wish-i-knew"]}},{kind:"MdxPage",name:"eutxo",route:"/fundamentals/eutxo",frontMatter:{title:"EUTxO Crash Course",description:"Aiken is a functional programming language for writing smart contracts on Cardano, which uses the Extended Unspent Transaction Output (EUTxO) model. EUTxO extends the basic UTxO model with datums (data attached to outputs as contract state), redeemers (user-provided arguments to unlock funds), and scripts (predicate functions that return True or False). The foundational execution model that determines how all Aiken validators process transactions and enforce on-chain logic.",difficulty:"beginner",keywords:["EUTxO","UTxO","datum","redeemer","script","transaction","inputs","outputs","address","script purpose","spend","mint","withdraw","publish","vote","propose"],topics:["eutxo","transactions","datums","redeemers","script-purposes"],prerequisites:[],related:["getting-started","validators","common-design-patterns"]}},{kind:"MdxPage",name:"getting-started",route:"/fundamentals/getting-started",frontMatter:{title:"Getting Started",description:"Aiken is a functional programming language and toolchain for writing Cardano smart contracts. Getting started covers installing the aikup version manager and aiken CLI, scaffolding a new project with aiken new, understanding the project structure (aiken.toml, lib/, validators/), and key commands like aiken build, aiken check, and aiken docs. The entry point for new developers to set up their environment and begin writing validators.",difficulty:"beginner",keywords:["getting started","installation","aikup","aiken new","aiken build","aiken check","aiken docs","aiken.toml","project structure","setup","stdlib","standard library"],topics:["getting-started","installation","project-setup","cli"],prerequisites:[],related:["eutxo","primitive-types","validators"]}}
1,{kind:"MdxPage",name:"what-i-wish-i-knew",route:"/fundamentals/what-i-wish-i-knew",frontMatter:{title:"What I Wish I Knew",description:"Aiken is a functional programming language for Cardano smart contracts. This page is a curated collection of tips, gotchas, and hard-won knowledge about the Cardano ecosystem — covering reliable documentation sources, ledger quirks, CBOR serialisation subtleties, native scripts, reward accounts, address formats, and common debugging pitfalls. Saves developers hours of debugging by surfacing non-obvious details of building on Cardano.",difficulty:"intermediate",keywords:["tips","gotchas","CBOR","CDDL","native scripts","addresses","reward accounts","script hash","ledger quirks","debugging","Cardano Developer Portal"],topics:["tips","gotchas","cardano-internals","debugging","addresses"],prerequisites:["eutxo","getting-started"],related:["common-design-patterns","troubleshooting","eutxo"]}}]},{kind:"MdxPage",name:"glossary",route:"/glossary"},{kind:"MdxPage",name:"index",route:"/",frontMatter:{title:"The modern smart contract platform for Cardano"}},{kind:"MdxPage",name:"installation-instructions",route:"/installation-instructions"},{kind:"Folder",name:"language-tour",route:"/language-tour",children:[{kind:"Meta",data:{"primitive-types":"Primitive Types","variables-and-constants":"Variables & Constants",functions:"Functions","custom-types":"Custom Types","control-flow":"Control Flow",validators:"Validators",modules:"Modules",tests:"Tests",bench:"Benchmarks",troubleshooting:"Troubleshooting"}},{kind:"MdxPage",name:"bench",route:"/language-tour/bench",frontMatter:{title:"Benchmarks",description:"Aiken is a functional programming language for Cardano smart contracts where on-chain execution costs (memory and CPU) directly impact transaction fees. Benchmarks are written using the bench keyword with a Sampler that generates increasingly larger inputs to measure how costs scale. Used to compare implementation approaches, identify performance bottlenecks, and optimize validators before mainnet deployment.",difficulty:"intermediate",keywords:["bench","benchmarks","Sampler","execution costs","memory","CPU","performance","aiken bench","optimization","transaction fees"],topics:["benchmarks","performance","execution-costs","optimization"],prerequisites:["tests","functions"],related:["tests","troubleshooting"]}},{kind:"MdxPage",name:"control-flow",route:"/language-tour/control-flow",frontMatter:{title:"Control Flow",description:"Aiken is a functional programming language for Cardano smart contracts that treats every block as an expression. Control flow is handled through if/else expressions, when/is pattern matching, the pipe operator, and recursion — there are no loops. Used to direct validator logic, destructure custom types, handle transaction scenarios, and compose operations.",difficulty:"beginner",keywords:["when","is","if","else","pattern matching","pipe operator","expect","recursion","expression blocks","control flow","no loops"],topics:["control-flow","pattern-matching","when-is","if-else","pipe-operator","recursion"],prerequisites:["primitive-types","custom-types"],related:["functions","custom-types","troubleshooting"]}},{kind:"MdxPage",name:"custom-types",route:"/language-tour/custom-types",frontMatter:{title:"Custom Types",description:"Aiken is a functional programming language for Cardano smart contracts with a strong static type system. Custom types are named collections of fields defined with the type keyword, supporting records, enums, generics, and algebraic data types — similar to structs and enums in Rust. Used to define datums, redeemers, and any structured data validators need to process on-chain.",difficulty:"beginner",keywords:["type","custom types","records","enums","constructors","algebraic data types","generics","destructuring","opaque types","Data","datum","redeemer"],topics:["custom-types","records","enums","algebraic-data-types","generics"],prerequisites:["primitive-types","functions"],related:["control-flow","validators","primitive-types"]}},{kind:"MdxPage",name:"functions",route:"/language-tour/functions",frontMatter:{title:"Functions",description:"Aiken is a functional programming language for Cardano smart contracts where functions are first-class values. Functions are defined using the fn keyword with typed arguments and an implicit return. Used to structure validator logic, build reusable libraries, and compose operations via the pipe operator, anonymous functions, and backpassing.",difficulty:"beginner",keywords:["fn","functions","anonymous functions","pipe operator","backpassing","labeled arguments","generics","type variables","first-class functions"],topics:["functions","fn","pipe-operator","backpassing","anonymous-functions"],prerequisites:["primitive-types","variables-and-constants"],related:["control-flow","modules","validators"]}},{kind:"MdxPage",name:"modules",route:"/language-tour/modules",frontMatter:{title:"Modules",description:"Aiken is a functional programming language for Cardano smart contracts where code is organized into reusable bundles called modules. Modules are files containing functions, types, and constants, with their namespace determined by file path. Used to structure projects, share code between validators, import the standard library, and control visibility with pub.",difficulty:"beginner",keywords:["modules","use","import","pub","namespace","opaque types","standard library","stdlib","prelude","aiken.toml","dependencies"],topics:["modules","imports","namespaces","visibility","stdlib"],prerequisites:["functions","custom-types"],related:["functions","custom-types","tests"]}},{kind:"MdxPage",name:"primitive-types",route:"/language-tour/primitive-types",frontMatter:{title:"Primitive Types",description:"Aiken is a functional programming language for writing Cardano smart contracts that compiles to Plutus Core. Primitive types are the 
16 built-in data types (Bool, Int, String, ByteArray, Data, and Void) plus base building blocks like Lists, Tuples, Options, and Pairs — the fundamental building blocks for defining validator logic, transaction data, and on-chain state.",difficulty:"beginner",keywords:["Bool","Int","String","ByteArray","Data","Void","List","Tuple","Option","Pair","primitive types","Aiken types"],topics:["types","primitive-types","data-types"],prerequisites:[],related:["variables-and-constants","custom-types","functions"]}},{kind:"MdxPage",name:"tests",route:"/language-tour/tests",frontMatter:{title:"Tests",description:"Aiken is a functional programming language for Cardano smart contracts with first-class support for unit tests and property-based tests. Tests are written using the test keyword as named functions that return a Bool, and they execute on the same Plutus virtual machine used on-chain. Used to verify validator logic, run property-based tests with fuzzers, and measure execution costs.",difficulty:"intermediate",keywords:["test","unit tests","property-based tests","fuzzers","Fuzzer","aiken check","execution costs","memory","CPU","testing validators"],topics:["tests","unit-tests","property-based-tests","fuzzers"],prerequisites:["functions","control-flow","validators"],related:["bench","troubleshooting","validators"]}},{kind:"MdxPage",name:"troubleshooting",route:"/language-tour/troubleshooting",frontMatter:{title:"Troubleshooting",description:"Aiken is a functional programming language for Cardano smart contracts where the constrained on-chain execution environment makes debugging challenging. Troubleshooting tools include the trace keyword for labelling execution paths, the ? trace-if-false operator, CBOR diagnostic notation for inspecting serialised data, and expect for catching runtime failures. Used to debug validator logic during development and diagnose why transactions fail.",difficulty:"intermediate",keywords:["trace","troubleshooting","debugging","CBOR diagnostic","expect","trace-if-false","?","error messages","on-chain debugging"],topics:["troubleshooting","debugging","trace","cbor-diagnostic"],prerequisites:["functions","control-flow","validators"],related:["tests","bench","validators"]}},{kind:"MdxPage",name:"validators",route:"/language-tour/validators",frontMatter:{title:"Validators",description:"Aiken is a functional programming language for Cardano smart contracts. Validators are named blocks defined with the validator keyword that contain one or more handlers (spend, mint, withdraw, publish, vote, propose) — each a predicate function returning True or False to authorize on-chain actions. Validators support parameters for configuration, multi-purpose handlers via fallback (else), and can be invoked as standalone functions for testing. The core construct for implementing all smart contract business logic on Cardano.",difficulty:"intermediate",keywords:["validator","handlers","spend","mint","withdraw","publish","vote","propose","datum","redeemer","Transaction","ScriptContext","parameters","fallback","else","multi-purpose","predicate","fail","expect","plutus.json","CIP-0057","blueprint"],topics:["validators","handlers","script-purposes","parameters","multi-purpose-validators"],prerequisites:["functions","custom-types","control-flow","eutxo"],related:["tests","modules","common-design-patterns","troubleshooting"]}},{kind:"MdxPage",name:"variables-and-constants",route:"/language-tour/variables-and-constants",frontMatter:{title:"Variables & Constants",description:"Aiken is a functional programming language for Cardano smart contracts where all values are immutable by default. Variables are declared with let bindings inside functions, while constants are declared with const at the module level and are fully evaluated at compile-time. Used to store and reference values throughout validator logic and across modules.",difficulty:"beginner",keywords:["let","const","variables","constants","immutable","bindings","shadowing","type annotations"],topics:["variables","constants","let-bindings","immutability"],prerequisites:["primitive-types"],related:["primitive-types","functions","modules"]}}]},{kind:"MdxPage",name:"language-tour",route:"/language-tour"},{kind:"MdxPage",name:"optimizing-programs",route:"/optimizing-programs"},{kind:"MdxPage",name:"resources",route:"/resources"},{kind:"Folder",name:"uplc",route:"/uplc",children:[{kind:"Meta",data:{syntax:"Syntax",cli:"Command-line utilities",builtins:"Builtins"}},{kind:"MdxPage",name:"builtins",route:"/uplc/builtins"},{kind:"MdxPage",name:"cli",route:"/uplc/cli"},{kind:"MdxPage",name:"syntax",route:"/uplc/syntax"}]},{kind:"MdxPage",name:"uplc",route:"/uplc"}],flexsearch:{codeblocks:!0},readingTime:{text:"8 min read",minutes:7.38,time:442800,words:1476},title:"Modules",headings:c},pageNextRoute:"/language-tour/modules",nextraLayout:a.ZP,themeConfig:o.Z};s.default=(0,i.j)(p)}},function(e){e.O(0,[774,736,640,888,179],function(){return e(e.s=1017)}),_N_E=e.O()}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.