"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9456],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>c});var a=n(67294);function l(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function r(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?i(Object(n),!0).forEach((function(t){l(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):i(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function o(e,t){if(null==e)return{};var n,a,l=function(e,t){if(null==e)return{};var n,a,l={},i=Object.keys(e);for(a=0;a<i.length;a++)n=i[a],t.indexOf(n)>=0||(l[n]=e[n]);return l}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a<i.length;a++)n=i[a],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(l[n]=e[n])}return l}var s=a.createContext({}),p=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},u=function(e){var t=p(e.components);return a.createElement(s.Provider,{value:t},e.children)},d="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},k=a.forwardRef((function(e,t){var n=e.components,l=e.mdxType,i=e.originalType,s=e.parentName,u=o(e,["components","mdxType","originalType","parentName"]),d=p(n),k=l,c=d["".concat(s,".").concat(k)]||d[k]||m[k]||i;return n?a.createElement(c,r(r({ref:t},u),{},{components:n})):a.createElement(c,r({ref:t},u))}));function c(e,t){var n=arguments,l=t&&t.mdxType;if("string"==typeof e||l){var i=n.length,r=new Array(i);r[0]=k;var o={};for(var s in t)hasOwnProperty.call(t,s)&&(o[s]=t[s]);o.originalType=e,o[d]="string"==typeof e?e:l,r[1]=o;for(var p=2;p<i;p++)r[p]=n[p];return a.createElement.apply(null,r)}return a.createElement.apply(null,n)}k.displayName="MDXCreateElement"},44524:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>r,default:()=>m,frontMatter:()=>i,metadata:()=>o,toc:()=>p});var a=n(87462),l=(n(67294),n(3905));const i={title:"Modules",linkTitle:"Modules",type:"docs",weight:2,description:"Modules"},r=void 0,o={unversionedId:"reference/lang/spec/modules",id:"version-0.5.3/reference/lang/spec/modules",title:"Modules",description:"Modules",source:"@site/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/spec/modules.md",sourceDirName:"reference/lang/spec",slug:"/reference/lang/spec/modules",permalink:"/zh-CN/docs/0.5.3/reference/lang/spec/modules",draft:!1,editUrl:"https://github.com/kcl-lang/kcl-lang.io/tree/main/versioned_docs/version-0.5.3/reference/lang/spec/modules.md",tags:[],version:"0.5.3",lastUpdatedBy:"peefy",lastUpdatedAt:1693883286,formattedLastUpdatedAt:"2023\u5e749\u67085\u65e5",frontMatter:{title:"Modules",linkTitle:"Modules",type:"docs",weight:2,description:"Modules"},sidebar:"reference",previous:{title:"Lexical",permalink:"/zh-CN/docs/0.5.3/reference/lang/spec/lexical"},next:{title:"Schema",permalink:"/zh-CN/docs/0.5.3/reference/lang/spec/schema"}},s={},p=[{value:"Modules and the Import System",id:"modules-and-the-import-system",level:2},{value:"Packages",id:"packages",level:2},{value:"Intra-Package Name Space Sharing",id:"intra-package-name-space-sharing",level:3},{value:"Package Initialization",id:"package-initialization",level:3},{value:"Searching",id:"searching",level:2},{value:"Module Cache",id:"module-cache",level:3},{value:"Module Names",id:"module-names",level:3},{value:"Uniqueness of Module",id:"uniqueness-of-module",level:3},{value:"Standard System Packages",id:"standard-system-packages",level:2},{value:"The Built-in System Package",id:"the-built-in-system-package",level:3},{value:"Plugin Modules",id:"plugin-modules",level:3},{value:"Replacing Standard System Packages",id:"replacing-standard-system-packages",level:3},{value:"Examples",id:"examples",level:2},{value:"Importing a Standard System Package",id:"importing-a-standard-system-package",level:3},{value:"Importing a Regular Module",id:"importing-a-regular-module",level:3},{value:"Importing a Package",id:"importing-a-package",level:3},{value:"Importing a Subpackage",id:"importing-a-subpackage",level:3},{value:"Relative Importing",id:"relative-importing",level:3},{value:"Importing from a Root Path",id:"importing-from-a-root-path",level:3},{value:"Importing a Module Inside a Package",id:"importing-a-module-inside-a-package",level:3},{value:"Precedence of Importing",id:"precedence-of-importing",level:3},{value:"Package Implemented with Multiple Files",id:"package-implemented-with-multiple-files",level:3}],u={toc:p},d="wrapper";function m(e){let{components:t,...n}=e;return(0,l.kt)(d,(0,a.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,l.kt)("h2",{id:"modules-and-the-import-system"},"Modules and the Import System"),(0,l.kt)("p",null,"KCL code is organized in ",(0,l.kt)("strong",{parentName:"p"},"modules"),". For code in one module to access the code defined in another module, a process called ",(0,l.kt)("strong",{parentName:"p"},"importing")," must be used."),(0,l.kt)("p",null,"Importing is undertaken at compile-time in KCL. The advantage is to have static checking enabled."),(0,l.kt)("p",null,"A regular KCL module is a file on the file system. It is required to have a ",(0,l.kt)("inlineCode",{parentName:"p"},".k")," suffix."),(0,l.kt)("h2",{id:"packages"},"Packages"),(0,l.kt)("p",null,"To help manage modules and provide a naming hierarchy, KCL has the concept of packages. In KCL, a package maps to exactly a file system directory, and a regular module maps to a file."),(0,l.kt)("p",null,"Files directly under a package are considered parts of the package, instead of individual regular modules."),(0,l.kt)("p",null,"Packages can have sub-packages."),(0,l.kt)("p",null,"Packages are special modules:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"All packages in KCL are modules."),(0,l.kt)("li",{parentName:"ul"},"A single-file module can never be a package.")),(0,l.kt)("p",null,"All modules have a name."),(0,l.kt)("p",null,"Sub package names are separated from their parent package name by dots."),(0,l.kt)("p",null,"To summary, a regular KCL module is a ",(0,l.kt)("inlineCode",{parentName:"p"},".k")," file, and a package is a directory on the file system. All ",(0,l.kt)("inlineCode",{parentName:"p"},".k")," files directly under the directory are included in the package, other files are ignored. If the directory has subdirectories, they become sub-packages as long as there are ",(0,l.kt)("inlineCode",{parentName:"p"},".k")," files underneath."),(0,l.kt)("h3",{id:"intra-package-name-space-sharing"},"Intra-Package Name Space Sharing"),(0,l.kt)("p",null,"Inside a package, all ",(0,l.kt)("inlineCode",{parentName:"p"},".k")," files are considered parts of the package, instead of regular modules. Code in these files share a single name space and can access names defined in other files, without explicitly granted."),(0,l.kt)("h3",{id:"package-initialization"},"Package Initialization"),(0,l.kt)("p",null,"A package can have the initialization code. The code must exist in only one of the ",(0,l.kt)("inlineCode",{parentName:"p"},".k")," files under this package. The interpreter guarantees that the initialization code is executed after all definitions."),(0,l.kt)("h2",{id:"searching"},"Searching"),(0,l.kt)("p",null,"The searching begins when an ",(0,l.kt)("inlineCode",{parentName:"p"},"import")," statement is used to import a module."),(0,l.kt)("h3",{id:"module-cache"},"Module Cache"),(0,l.kt)("p",null,"In KCL, only standard system modules are cached. When a cached module is imported, the cached version is used. In other words, KCL runtime would not create another copy of the standard system module in memory."),(0,l.kt)("p",null,"However, other modules are uncached. Importing a module multiple time would create multiple instances of the module."),(0,l.kt)("h3",{id:"module-names"},"Module Names"),(0,l.kt)("p",null,"An ",(0,l.kt)("inlineCode",{parentName:"p"},"import")," statement specifies the name of the module to import. The syntax is:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre"},"import <module_name> [as <alias name>]\n")),(0,l.kt)("p",null,"The rule to search with the module name is very simple:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("strong",{parentName:"li"},"Step 1"),": Searches the module name from the ",(0,l.kt)("strong",{parentName:"li"},"standard system modules"),", then ",(0,l.kt)("strong",{parentName:"li"},"plugins modules"),".",(0,l.kt)("ul",{parentName:"li"},(0,l.kt)("li",{parentName:"ul"},"See ",(0,l.kt)("strong",{parentName:"li"},"standard system modules")," and ",(0,l.kt)("strong",{parentName:"li"},"plugins modules")," for more details. If matched, the module is imported. Otherwise, continue to ",(0,l.kt)("strong",{parentName:"li"},"Step 2"),"."))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("strong",{parentName:"li"},"Step 2"),". Whether a module name starts with a ",(0,l.kt)("inlineCode",{parentName:"li"},".")," is checked. If yes, the name is a so-called relative pathname, and we go to ",(0,l.kt)("strong",{parentName:"li"},"Step 5"),". Otherwise, continue to ",(0,l.kt)("strong",{parentName:"li"},"Step 3"),"."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("strong",{parentName:"li"},"Step 3"),": If the module name does not start with any ",(0,l.kt)("inlineCode",{parentName:"li"},"."),", then the compiler searches the nearest ",(0,l.kt)("inlineCode",{parentName:"li"},"root path")," directory from this directory to the parent, and find  the module according to the name just from the ",(0,l.kt)("inlineCode",{parentName:"li"},"root path"),". If no ",(0,l.kt)("inlineCode",{parentName:"li"},"root path")," is found, find the module according to the name from the folder the ",(0,l.kt)("inlineCode",{parentName:"li"},".k")," file including this ",(0,l.kt)("inlineCode",{parentName:"li"},"import")," statement exists.",(0,l.kt)("ul",{parentName:"li"},(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("strong",{parentName:"li"},"root path"),": the directory contains a ",(0,l.kt)("inlineCode",{parentName:"li"},"kcl.mod")," file. If matched, the module is imported. Otherwise, continue to ",(0,l.kt)("strong",{parentName:"li"},"Step 4"),"."))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("strong",{parentName:"li"},"Step 4"),": Then the compiler checks if the name is the name of any library module that requires explicit loading. If matched, the library module is imported. Otherwise, continue to ",(0,l.kt)("strong",{parentName:"li"},"Step 6"),"."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("strong",{parentName:"li"},"Step 5"),". For relative importing, find the module according to the name from the folder the ",(0,l.kt)("inlineCode",{parentName:"li"},".k")," file including this ",(0,l.kt)("inlineCode",{parentName:"li"},"import")," statement exists. Interpret leading dots using the following rule:"),(0,l.kt)("li",{parentName:"ul"},"One dot: Ignore."),(0,l.kt)("li",{parentName:"ul"},"Tow or more dots: Suppose there are ",(0,l.kt)("inlineCode",{parentName:"li"},"n")," leading dots, then the searching starts at ",(0,l.kt)("inlineCode",{parentName:"li"},"n - 1")," levels above this folder. If matched, the module is imported. Otherwise, continue to ",(0,l.kt)("strong",{parentName:"li"},"Step 6"),"."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("strong",{parentName:"li"},"Step 6"),". Module not found, report an error.")),(0,l.kt)("p",null,"Do case-sensitive search when the operating system allows. If case-sensitive search is not allowed, search directories before regular files."),(0,l.kt)("p",null,"In KCL, the ",(0,l.kt)("inlineCode",{parentName:"p"},"from <> import <>")," is unsupported, and relative import is performed with the ",(0,l.kt)("inlineCode",{parentName:"p"},"import <>")," syntax."),(0,l.kt)("h3",{id:"uniqueness-of-module"},"Uniqueness of Module"),(0,l.kt)("p",null,"Each module has a unique location path in its scope, so that a module or package could be located with a unique location path, such as ",(0,l.kt)("inlineCode",{parentName:"p"},"a.b.c"),"."),(0,l.kt)("p",null,"Searching by location path should be supported by the kcl compiler, which needs to provide corresponding searching features through the command line and api form."),(0,l.kt)("h2",{id:"standard-system-packages"},"Standard System Packages"),(0,l.kt)("p",null,"KCL supports a few standard system modules. The following is the full list of these standard system modules:"),(0,l.kt)("table",null,(0,l.kt)("tr",null,(0,l.kt)("td",null,(0,l.kt)("b",null,"Package")),(0,l.kt)("td",null,(0,l.kt)("b",null,"Member"))),(0,l.kt)("tr",null,(0,l.kt)("td",{rowspan:"4"},"datetime"),(0,l.kt)("td",null,"today")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"now")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"ticks")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"date")),(0,l.kt)("tr",null,(0,l.kt)("td",{rowspan:"16"},"math"),(0,l.kt)("td",null,"ceil")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"exp")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"expm1")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"factorial")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"floor")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"gcd")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"isfinite")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"isinf")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"isnan")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"log")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"log1p")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"log2")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"log10")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"modf")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"pow")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"sqrt")),(0,l.kt)("tr",null,(0,l.kt)("td",{rowspan:"6"},"regex"),(0,l.kt)("td",null,"replace")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"match")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"compile")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"findall")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"search")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"split")),(0,l.kt)("tr",null,(0,l.kt)("td",{rowspan:"27"},"units"),(0,l.kt)("td",null,"n")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"u")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"m")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"k")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"K")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"M")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"G")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"T")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"P")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"Ki")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"Mi")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"Gi")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"Ti")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"Pi")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"to_n")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"to_u")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"to_m")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"to_K")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"to_M")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"to_G")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"to_T")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"to_P")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"to_Ki")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"to_Mi")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"to_Gi")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"to_Ti")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"to_Pi")),(0,l.kt)("tr",null,(0,l.kt)("td",{rowspan:"3"},"json"),(0,l.kt)("td",null,"encode")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"decode")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"dump_to_file")),(0,l.kt)("tr",null,(0,l.kt)("td",{rowspan:"3"},"yaml"),(0,l.kt)("td",null,"encode")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"decode")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"dump_to_file")),(0,l.kt)("tr",null,(0,l.kt)("td",{rowspan:"16"},"net"),(0,l.kt)("td",null,"split_host_port")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"join_host_port")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"fqdn")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"parse_IP")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"to_IP4")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"to_IP16")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"IP_string")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"is_IPv4")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"is_IP")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"is_loopback_IP")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"is_multicast_IP")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"is_interface_local_multicast_IP")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"is_link_local_multicast_IP")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"is_link_local_unicast_IP")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"is_global_unicast_IP")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"is_unspecified_IP")),(0,l.kt)("tr",null,(0,l.kt)("td",{rowspan:"2"},"base64"),(0,l.kt)("td",null,"encode")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"decode")),(0,l.kt)("tr",null,(0,l.kt)("td",{rowspan:"6"},"crypto"),(0,l.kt)("td",null,"md5")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"sha1")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"sha224")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"sha256")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"sha384")),(0,l.kt)("tr",null,(0,l.kt)("td",null,"sha512"))),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"datetime",(0,l.kt)("ul",{parentName:"li"},(0,l.kt)("li",{parentName:"ul"},"ticks() -> float\nReturn the current time in seconds since the Epoch. Fractions of a second may be present if the system clock provides them."),(0,l.kt)("li",{parentName:"ul"},"date() -> str\nreturn the ",(0,l.kt)("inlineCode",{parentName:"li"},"%Y-%m-%d %H:%M:%S")," format date."),(0,l.kt)("li",{parentName:"ul"},"now() -> str\nreturn the local time. e.g. ",(0,l.kt)("inlineCode",{parentName:"li"},"'Sat Jun 06 16:26:11 1998'")),(0,l.kt)("li",{parentName:"ul"},"today() -> str\nreturn the ",(0,l.kt)("inlineCode",{parentName:"li"},"%Y-%m-%d %H:%M:%S.%{ticks}")," format date."))),(0,l.kt)("li",{parentName:"ul"},"math",(0,l.kt)("ul",{parentName:"li"},(0,l.kt)("li",{parentName:"ul"},"ceil(x) -> int\nReturn the ceiling of x as an Integral. This is the smallest integer >= x."),(0,l.kt)("li",{parentName:"ul"},"factorial(x) -> int\nReturn x!. Raise a error if x is negative or non-integral."),(0,l.kt)("li",{parentName:"ul"},"floor(x) -> int\nReturn the floor of x as an Integral. This is the largest integer <= x."),(0,l.kt)("li",{parentName:"ul"},"gcd(a: int, b: int) -> int\nReturn the greatest common divisor of x and y"),(0,l.kt)("li",{parentName:"ul"},"isfinite(x) -> bool\nReturn True if x is neither an infinity nor a NaN, and False otherwise."),(0,l.kt)("li",{parentName:"ul"},"isinf(x) -> bool\nReturn True if x is a positive or negative infinity, and False otherwise."),(0,l.kt)("li",{parentName:"ul"},"isnan(x) -> bool\nReturn True if x is a NaN (not a number), and False otherwise."),(0,l.kt)("li",{parentName:"ul"},"modf(x) -> Listfloat, float]\nReturn the fractional and integer parts of x. Both results carry the sign of x and are floats."),(0,l.kt)("li",{parentName:"ul"},"exp(x) -> float\nReturn e raised to the power of x."),(0,l.kt)("li",{parentName:"ul"},"expm1(x) -> float\nReturn exp(x)-1. This function avoids the loss of precision involved in the direct evaluation of exp(x)-1 for small x."),(0,l.kt)("li",{parentName:"ul"},"log(x, base=2.71828182845904523536028747135266250) -> float\nReturn the logarithm of x to the base e."),(0,l.kt)("li",{parentName:"ul"},"log1p(x) -> float\nReturn the natural logarithm of 1+x (base e). The result is computed in a way which is accurate for x near zero."),(0,l.kt)("li",{parentName:"ul"},"log2(x) -> float\nReturn the base 2 logarithm of x."),(0,l.kt)("li",{parentName:"ul"},"log10(x) -> float\nReturn the base 10 logarithm of x."),(0,l.kt)("li",{parentName:"ul"},"pow(x, y) -> float\nReturn x**y (x to the power of y)."),(0,l.kt)("li",{parentName:"ul"},"sqrt(x) -> float\nReturn the square root of x."))),(0,l.kt)("li",{parentName:"ul"},"regex",(0,l.kt)("ul",{parentName:"li"},(0,l.kt)("li",{parentName:"ul"},"replace(string: str, pattern: str, replace: str, count=0) -> str\nReturn the string obtained by replacing the leftmost non-overlapping occurrences of the pattern in string by the replacement."),(0,l.kt)("li",{parentName:"ul"},"match(string: str, pattern: str) -> bool\nTry to apply the pattern at the start of the string, returning a bool value True if any match was found, or False if no match was found."),(0,l.kt)("li",{parentName:"ul"},"compile(pattern: str) -> bool\nCompile a regular expression pattern, returning a bool value denoting whether the pattern is valid."),(0,l.kt)("li",{parentName:"ul"},"findall(string: str, pattern: str) -> List","[str]","\nReturn a list of all non-overlapping matches in the string."),(0,l.kt)("li",{parentName:"ul"},"search(string: str, pattern: str) -> bool\nScan through string looking for a match to the pattern, returning a bool value True if any match was found, or False if no match was found."),(0,l.kt)("li",{parentName:"ul"},"split(string: str, pattern: str, maxsplit=0) -> List","[str]","\nScan through string looking for a match to the pattern, returning a Match object, or None if no match was found."))),(0,l.kt)("li",{parentName:"ul"},"units",(0,l.kt)("ul",{parentName:"li"},(0,l.kt)("li",{parentName:"ul"},"Unit constants",(0,l.kt)("ul",{parentName:"li"},(0,l.kt)("li",{parentName:"ul"},"Fixed point: ",(0,l.kt)("inlineCode",{parentName:"li"},"n"),", ",(0,l.kt)("inlineCode",{parentName:"li"},"u"),", ",(0,l.kt)("inlineCode",{parentName:"li"},"m"),", ",(0,l.kt)("inlineCode",{parentName:"li"},"k"),", ",(0,l.kt)("inlineCode",{parentName:"li"},"K"),", ",(0,l.kt)("inlineCode",{parentName:"li"},"G"),", ",(0,l.kt)("inlineCode",{parentName:"li"},"T")," and ",(0,l.kt)("inlineCode",{parentName:"li"},"P"),"."),(0,l.kt)("li",{parentName:"ul"},"Power of 2: ",(0,l.kt)("inlineCode",{parentName:"li"},"Ki"),", ",(0,l.kt)("inlineCode",{parentName:"li"},"Mi"),", ",(0,l.kt)("inlineCode",{parentName:"li"},"Gi"),", ",(0,l.kt)("inlineCode",{parentName:"li"},"Ti")," and ",(0,l.kt)("inlineCode",{parentName:"li"},"Pi"),"."))),(0,l.kt)("li",{parentName:"ul"},"Functions",(0,l.kt)("ul",{parentName:"li"},(0,l.kt)("li",{parentName:"ul"},"to_n(num: int) -> str\nInt literal to string with ",(0,l.kt)("inlineCode",{parentName:"li"},"n")," suffix"),(0,l.kt)("li",{parentName:"ul"},"to_u(num: int) -> str\nInt literal to string with ",(0,l.kt)("inlineCode",{parentName:"li"},"u")," suffix"),(0,l.kt)("li",{parentName:"ul"},"to_m(num: int) -> str\nInt literal to string with ",(0,l.kt)("inlineCode",{parentName:"li"},"m")," suffix"),(0,l.kt)("li",{parentName:"ul"},"to_K(num: int) -> str\nInt literal to string with ",(0,l.kt)("inlineCode",{parentName:"li"},"K")," suffix"),(0,l.kt)("li",{parentName:"ul"},"to_M(num: int) -> str\nInt literal to string with ",(0,l.kt)("inlineCode",{parentName:"li"},"M")," suffix"),(0,l.kt)("li",{parentName:"ul"},"to_G(num: int) -> str\nInt literal to string with ",(0,l.kt)("inlineCode",{parentName:"li"},"G")," suffix"),(0,l.kt)("li",{parentName:"ul"},"to_T(num: int) -> str\nInt literal to string with ",(0,l.kt)("inlineCode",{parentName:"li"},"T")," suffix"),(0,l.kt)("li",{parentName:"ul"},"to_P(num: int) -> str\nInt literal to string with ",(0,l.kt)("inlineCode",{parentName:"li"},"P")," suffix"),(0,l.kt)("li",{parentName:"ul"},"to_Ki(num: int) -> str\nInt literal to string with ",(0,l.kt)("inlineCode",{parentName:"li"},"Ki")," suffix"),(0,l.kt)("li",{parentName:"ul"},"to_Mi(num: int) -> str\nInt literal to string with ",(0,l.kt)("inlineCode",{parentName:"li"},"Mi")," suffix"),(0,l.kt)("li",{parentName:"ul"},"to_Gi(num: int) -> str\nInt literal to string with ",(0,l.kt)("inlineCode",{parentName:"li"},"Gi")," suffix"),(0,l.kt)("li",{parentName:"ul"},"to_Ti(num: int) -> str\nInt literal to string with ",(0,l.kt)("inlineCode",{parentName:"li"},"Ti")," suffix"),(0,l.kt)("li",{parentName:"ul"},"to_Pi(num: int) -> str\nInt literal to string with ",(0,l.kt)("inlineCode",{parentName:"li"},"Pi")," suffix"))))),(0,l.kt)("li",{parentName:"ul"},"json",(0,l.kt)("ul",{parentName:"li"},(0,l.kt)("li",{parentName:"ul"},"encode(data: any, sort_keys: bool = False, indent: int = None, ignore_private: bool = False, ignore_none: bool = False) -> str\nSerialize a KCL object ",(0,l.kt)("inlineCode",{parentName:"li"},"data")," to a JSON formatted str."),(0,l.kt)("li",{parentName:"ul"},"decode(value: str) -> any\nDeserialize ",(0,l.kt)("inlineCode",{parentName:"li"},"value")," (a string instance containing a JSON document) to a KCL object."),(0,l.kt)("li",{parentName:"ul"},"dump_to_file(data: any, filename: str, ignore_private: bool = False, ignore_none: bool = False) -> None\nSerialize a KCL object ",(0,l.kt)("inlineCode",{parentName:"li"},"data")," to a JSON formatted str and write it into the file ",(0,l.kt)("inlineCode",{parentName:"li"},"filename"),"."))),(0,l.kt)("li",{parentName:"ul"},"yaml",(0,l.kt)("ul",{parentName:"li"},(0,l.kt)("li",{parentName:"ul"},"encode(data: any, sort_keys: bool = False, ignore_private: bool = False, ignore_none: bool = False) -> str\nSerialize a KCL object ",(0,l.kt)("inlineCode",{parentName:"li"},"data")," to a YAML formatted str."),(0,l.kt)("li",{parentName:"ul"},"decode(value: str) -> any\nDeserialize ",(0,l.kt)("inlineCode",{parentName:"li"},"value")," (a string instance containing a YAML document) to a KCL object."),(0,l.kt)("li",{parentName:"ul"},"dump_to_file(data: any, filename: str, ignore_private: bool = False, ignore_none: bool = False) -> None\nSerialize a KCL object ",(0,l.kt)("inlineCode",{parentName:"li"},"data")," to a YAML formatted str and write it into the file ",(0,l.kt)("inlineCode",{parentName:"li"},"filename"),"."))),(0,l.kt)("li",{parentName:"ul"},"net",(0,l.kt)("ul",{parentName:"li"},(0,l.kt)("li",{parentName:"ul"},"split_host_port(ip_end_point: str) -> List","[str]","\nSplit the 'host' and 'port' from the ip end point."),(0,l.kt)("li",{parentName:"ul"},"join_host_port(host, port) -> str\nMerge the 'host' and 'port'."),(0,l.kt)("li",{parentName:"ul"},"fqdn(name: str = '') -> str\nReturn Fully Qualified Domain Name (FQDN)."),(0,l.kt)("li",{parentName:"ul"},"parse_IP(ip) -> str\nParse 'ip' to a real IP address"),(0,l.kt)("li",{parentName:"ul"},"to_IP4(ip) -> str\nGet the IP4 form of 'ip'."),(0,l.kt)("li",{parentName:"ul"},"to_IP16(ip) -> int\nGet the IP16 form of 'ip'."),(0,l.kt)("li",{parentName:"ul"},"IP_string(ip: str | int) -> str\nGet the IP string."),(0,l.kt)("li",{parentName:"ul"},"is_IPv4(ip: str) -> bool\nWhether 'ip' is a IPv4 one."),(0,l.kt)("li",{parentName:"ul"},"is_IP(ip: str) -> bool\nWhether ip is a valid ip address."),(0,l.kt)("li",{parentName:"ul"},"is_loopback_IP(ip: str) -> bool\nWhether 'ip' is a loopback one."),(0,l.kt)("li",{parentName:"ul"},"is_multicast_IP(ip: str) -> bool\nWhether 'ip' is a multicast one."),(0,l.kt)("li",{parentName:"ul"},"is_interface_local_multicast_IP(ip: str) -> bool\nWhether 'ip' is a interface, local and multicast one."),(0,l.kt)("li",{parentName:"ul"},"is_link_local_multicast_IP(ip: str) -> bool\nWhether 'ip' is a link local and multicast one."),(0,l.kt)("li",{parentName:"ul"},"is_link_local_unicast_IP(ip: str) -> bool\nWhether 'ip' is a link local and unicast one."),(0,l.kt)("li",{parentName:"ul"},"is_global_unicast_IP(ip: str) -> bool\nWhether 'ip' is a global and unicast one."),(0,l.kt)("li",{parentName:"ul"},"is_unspecified_IP(ip: str) -> bool\nWhether 'ip' is a unspecified one."))),(0,l.kt)("li",{parentName:"ul"},"base64",(0,l.kt)("ul",{parentName:"li"},(0,l.kt)("li",{parentName:"ul"},'encode(value: str, encoding: str = "utf-8") -> str\nEncode the string ',(0,l.kt)("inlineCode",{parentName:"li"},"value")," using the codec registered for encoding."),(0,l.kt)("li",{parentName:"ul"},'decode(value: str, encoding: str = "utf-8") -> str\nDecode the string ',(0,l.kt)("inlineCode",{parentName:"li"},"value")," using the codec registered for encoding."))),(0,l.kt)("li",{parentName:"ul"},"crypto",(0,l.kt)("ul",{parentName:"li"},(0,l.kt)("li",{parentName:"ul"},'md5(value: str, encoding: str = "utf-8") -> str\nEncrypt the string ',(0,l.kt)("inlineCode",{parentName:"li"},"value")," using ",(0,l.kt)("inlineCode",{parentName:"li"},"MD5")," and the codec registered for encoding."),(0,l.kt)("li",{parentName:"ul"},'sha1(value: str, encoding: str = "utf-8") -> str\nEncrypt the string ',(0,l.kt)("inlineCode",{parentName:"li"},"value")," using ",(0,l.kt)("inlineCode",{parentName:"li"},"SHA1")," and the codec registered for encoding."),(0,l.kt)("li",{parentName:"ul"},'sha224(value: str, encoding: str = "utf-8") -> str\nEncrypt the string ',(0,l.kt)("inlineCode",{parentName:"li"},"value")," using ",(0,l.kt)("inlineCode",{parentName:"li"},"SHA224")," and the codec registered for encoding."),(0,l.kt)("li",{parentName:"ul"},'sha256(value: str, encoding: str = "utf-8") -> str\nEncrypt the string ',(0,l.kt)("inlineCode",{parentName:"li"},"value")," using ",(0,l.kt)("inlineCode",{parentName:"li"},"SHA256")," and the codec registered for encoding."),(0,l.kt)("li",{parentName:"ul"},'sha384(value: str, encoding: str = "utf-8") -> str\nEncrypt the string ',(0,l.kt)("inlineCode",{parentName:"li"},"value")," using ",(0,l.kt)("inlineCode",{parentName:"li"},"SHA384")," and the codec registered for encoding."),(0,l.kt)("li",{parentName:"ul"},'sha512(value: str, encoding: str = "utf-8") -> str\nEncrypt the string ',(0,l.kt)("inlineCode",{parentName:"li"},"value")," using ",(0,l.kt)("inlineCode",{parentName:"li"},"SHA512")," and the codec registered for encoding."))),(0,l.kt)("li",{parentName:"ul"},"manifests",(0,l.kt)("ul",{parentName:"li"},(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},'yaml_stream(values: [any], opts: {str:} = {sort_keys = False, ignore_private = True, ignore_none = False, sep = "---"}'),". This function is used to serialize the KCL object list into YAML output with the ",(0,l.kt)("inlineCode",{parentName:"li"},"---")," separator")))),(0,l.kt)("h3",{id:"the-built-in-system-package"},"The Built-in System Package"),(0,l.kt)("p",null,"KCL provides a list of built-in system modules, which are loaded automatically and can be directly used without providing any module name. For example, ",(0,l.kt)("inlineCode",{parentName:"p"},"print")," is a widely used built-in module."),(0,l.kt)("p",null,"The following is the full list of these built-in system modules:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"print()",(0,l.kt)("ul",{parentName:"li"},(0,l.kt)("li",{parentName:"ul"},"The print function."))),(0,l.kt)("li",{parentName:"ul"},"multiplyof(a, b)",(0,l.kt)("ul",{parentName:"li"},(0,l.kt)("li",{parentName:"ul"},"Check if the modular result of a and b is 0"))),(0,l.kt)("li",{parentName:"ul"},"isunique(inval)",(0,l.kt)("ul",{parentName:"li"},(0,l.kt)("li",{parentName:"ul"},"Check if a list has duplicated elements"))),(0,l.kt)("li",{parentName:"ul"},"len(inval)\nReturn the length of a value"),(0,l.kt)("li",{parentName:"ul"},"abs(x)\nReturn the absolute value of the argument."),(0,l.kt)("li",{parentName:"ul"},"all(iterable)\nReturn True if bool(x) is True for all values x in the iterable. If the iterable is empty, return True."),(0,l.kt)("li",{parentName:"ul"},"any(iterable)\nReturn True if bool(x) is True for any x in the iterable. If the iterable is empty, return False."),(0,l.kt)("li",{parentName:"ul"},"bin(number)\nReturn the binary representation of an integer."),(0,l.kt)("li",{parentName:"ul"},"hex(number)\nReturn the hexadecimal representation of an integer."),(0,l.kt)("li",{parentName:"ul"},"oct(number)\nReturn the octal representation of an integer."),(0,l.kt)("li",{parentName:"ul"},"ord(c) -> int\nReturn the Unicode code point for a one-character string."),(0,l.kt)("li",{parentName:"ul"},"sorted(iterable)\nReturn a new list containing all items from the iterable in ascending order. A custom key function can be supplied to customize the sort order, and the reverse flag can be set to request the result in descending order."),(0,l.kt)("li",{parentName:"ul"},"range(start, end, step=1)\nReturn the range of a value with start, end and step parameter."),(0,l.kt)("li",{parentName:"ul"},"min(iterable)\nWith a single iterable argument, return its smallest item. The default keyword-only argument specifies an object to return if the provided iterable is empty. With two or more arguments, return the smallest argument."),(0,l.kt)("li",{parentName:"ul"},"max(iterable)\nWith a single iterable argument, return its biggest item. The default keyword-only argument specifies an object to return if the provided iterable is empty. With two or more arguments, return the largest argument."),(0,l.kt)("li",{parentName:"ul"},"sum(iterable, start)\nReturn the sum of a 'start' value (default: 0) plus an iterable of numbers. When the iterable is empty, return the start value. This function is intended specifically for use with numeric values and may reject non-numeric types."),(0,l.kt)("li",{parentName:"ul"},"pow(x, y, z)\nEquivalent to ",(0,l.kt)("inlineCode",{parentName:"li"},"x**y")," (with two arguments) or ",(0,l.kt)("inlineCode",{parentName:"li"},"x**y % z")," (with three arguments). Some types, such as ints, are able to use a more efficient algorithm when invoked using the three argument form."),(0,l.kt)("li",{parentName:"ul"},"round(number, ndigits)\nRound a number to a given precision in decimal digits. The return value is an integer if ndigits is omitted or None. Otherwise the return value has the same type as the number. ndigits may be negative."),(0,l.kt)("li",{parentName:"ul"},"typeof(x: any, *, full_name: bool = False) -> str\nReturn the type of the value 'x' at runtime. When the 'full_name' is 'True', return the full package type name such as ",(0,l.kt)("inlineCode",{parentName:"li"},"pkg.schema"),".")),(0,l.kt)("h3",{id:"plugin-modules"},"Plugin Modules"),(0,l.kt)("p",null,"KCL compiler needs to provide the ability to dynamically expand and load plugin modules without modifying the compiler itself. KCL compiler needs to support flexible pluggable module extension mechanism, so that KCL users can use more abundant built-in function capabilities to simplify writing."),(0,l.kt)("p",null,"KCL compiler needs to ensure the stability and safety of the expansion mechanism, without affecting the core of the compiler."),(0,l.kt)("p",null,"Searching extended plugin module is performed after the standard system module. The standard system module has a higher priority in naming. If it exists a standard or built-in system module with the same name, the extended plugin module will be ignored."),(0,l.kt)("p",null,"Importing and using the extended plugin module should be consistent with the standard or built-in system module."),(0,l.kt)("h3",{id:"replacing-standard-system-packages"},"Replacing Standard System Packages"),(0,l.kt)("p",null,"Replacing standard system modules is not allowed."),(0,l.kt)("h2",{id:"examples"},"Examples"),(0,l.kt)("p",null,"We show more module features through an example."),(0,l.kt)("p",null,"Suppose we have the following directories and files:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre"},"    .\n    \u251c\u2500\u2500 mod1.k\n    \u251c\u2500\u2500 mod2.k\n    \u251c\u2500\u2500 pkg1\n    \u2502\xa0\xa0 \u251c\u2500\u2500 def1.k\n    \u2502\xa0\xa0 \u251c\u2500\u2500 def2.k\n    \u2502\xa0\xa0 \u2514\u2500\u2500 def3init.k\n    \u2514\u2500\u2500 pkg2\n        \u251c\u2500\u2500 file2.k\n        \u2514\u2500\u2500 subpkg3\n            \u2514\u2500\u2500 file3.k\n")),(0,l.kt)("p",null,"From the structure we can see that ",(0,l.kt)("inlineCode",{parentName:"p"},"pkg1")," and ",(0,l.kt)("inlineCode",{parentName:"p"},"pkg2")," are two packages, ",(0,l.kt)("inlineCode",{parentName:"p"},"subpkg3")," is a subpackage of ",(0,l.kt)("inlineCode",{parentName:"p"},"pkg2"),", and ",(0,l.kt)("inlineCode",{parentName:"p"},"mod1.k")," and ",(0,l.kt)("inlineCode",{parentName:"p"},"mod2.k")," are regular modules."),(0,l.kt)("h3",{id:"importing-a-standard-system-package"},"Importing a Standard System Package"),(0,l.kt)("p",null,"The following statement can import the standard system module ",(0,l.kt)("inlineCode",{parentName:"p"},"math")),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-python"},"import math\n")),(0,l.kt)("p",null,"This is the only way to import a standard system module. After importing a standard system module, functions, variables and schemas defined in it can be used. For example, the following statement uses the ",(0,l.kt)("inlineCode",{parentName:"p"},"log10")," function\ndefined in ",(0,l.kt)("inlineCode",{parentName:"p"},"math")),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-python"},"a = math.log10(100) # a is 2 after computation.\n")),(0,l.kt)("h3",{id:"importing-a-regular-module"},"Importing a Regular Module"),(0,l.kt)("p",null,"In ",(0,l.kt)("inlineCode",{parentName:"p"},"mod1.k"),", we can import ",(0,l.kt)("inlineCode",{parentName:"p"},"mod2")," using one of the following syntaxes."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-python"},"import mod2\n")),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-python"},"import .mod2\n")),(0,l.kt)("p",null,"The difference is that in the first syntax, the KCL compiler will first try to check if ",(0,l.kt)("inlineCode",{parentName:"p"},"mod2")," matches any of the standard system modules' name. Since it does not match any standard system module's name, the statement will check the directory where ",(0,l.kt)("inlineCode",{parentName:"p"},"mod1.k")," resists in, like what the second statement does."),(0,l.kt)("p",null,"Suppose in ",(0,l.kt)("inlineCode",{parentName:"p"},"mod2.k")," there is a definition of a variable::"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-python"},"a = 100\n")),(0,l.kt)("p",null,"After importing ",(0,l.kt)("inlineCode",{parentName:"p"},"mod2"),", we can access ",(0,l.kt)("inlineCode",{parentName:"p"},"a")," in ",(0,l.kt)("inlineCode",{parentName:"p"},"mod1.k")," using the following syntax"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-python"},"b = mod2.a\n")),(0,l.kt)("h3",{id:"importing-a-package"},"Importing a Package"),(0,l.kt)("p",null,"In ",(0,l.kt)("inlineCode",{parentName:"p"},"mod1.k"),", we can import ",(0,l.kt)("inlineCode",{parentName:"p"},"pkg1")," using one of the following syntaxes."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-python"},"import pkg1\n")),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-python"},"import .pkg1\n")),(0,l.kt)("p",null,"The difference is that in the first syntax, the KCL compiler will first try to check if ",(0,l.kt)("inlineCode",{parentName:"p"},"pkg1")," matches any of the standard system modules' name. Since it does not match any standard system module's name, the statement will check the directory where ",(0,l.kt)("inlineCode",{parentName:"p"},"mod1.k")," resists in, like what the second statement does."),(0,l.kt)("p",null,"We can use similar statements to import ",(0,l.kt)("inlineCode",{parentName:"p"},"pkg2"),". Note that importing ",(0,l.kt)("inlineCode",{parentName:"p"},"pkg2")," will not import ",(0,l.kt)("inlineCode",{parentName:"p"},"subpkg3"),"."),(0,l.kt)("p",null,"The name of the package is the name of the imported module."),(0,l.kt)("p",null,"Suppose in ",(0,l.kt)("inlineCode",{parentName:"p"},"file2.k")," that is inside ",(0,l.kt)("inlineCode",{parentName:"p"},"pkg2")," there is a definition to variable ",(0,l.kt)("inlineCode",{parentName:"p"},"foo")),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-python"},"foo = 100\n")),(0,l.kt)("p",null,"This variable can be used in ",(0,l.kt)("inlineCode",{parentName:"p"},"mod1.k")," after importing ",(0,l.kt)("inlineCode",{parentName:"p"},"pkg2")," like the following"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-python"},"bar = pkg2.foo\n")),(0,l.kt)("h3",{id:"importing-a-subpackage"},"Importing a Subpackage"),(0,l.kt)("p",null,"To import ",(0,l.kt)("inlineCode",{parentName:"p"},"subpkg3")," from ",(0,l.kt)("inlineCode",{parentName:"p"},"mod1.k"),", one of the following statements can be used."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-python"},"import pkg2.subpkg3\n")),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-python"},"import .pkg2.subpkg3\n")),(0,l.kt)("p",null,"The behaviors of these statements are identical."),(0,l.kt)("p",null,"The name of the subpackage is the name of the imported module."),(0,l.kt)("p",null,"Suppose in ",(0,l.kt)("inlineCode",{parentName:"p"},"file3.k")," that is inside ",(0,l.kt)("inlineCode",{parentName:"p"},"subpkg3")," there is a definition to variable ",(0,l.kt)("inlineCode",{parentName:"p"},"foo")),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-python"},"foo = 100\n")),(0,l.kt)("p",null,"This variable can be used in ",(0,l.kt)("inlineCode",{parentName:"p"},"mod1.k")," after importing ",(0,l.kt)("inlineCode",{parentName:"p"},"subpkg3")," like the following"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-python"},"bar = subpkg3.foo\n")),(0,l.kt)("h3",{id:"relative-importing"},"Relative Importing"),(0,l.kt)("p",null,"Relative importing is useful when there is code trying to import modules that does not exist recursively inside the current directory."),(0,l.kt)("p",null,"For example, the following statements, if written in ",(0,l.kt)("inlineCode",{parentName:"p"},"file3.k"),", can be used to import ",(0,l.kt)("inlineCode",{parentName:"p"},"pkg2"),", ",(0,l.kt)("inlineCode",{parentName:"p"},"pkg1")," and ",(0,l.kt)("inlineCode",{parentName:"p"},"mod2")," respectively."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-python"},"import ...pkg2 # Go two levels up then import pkg2\nimport ...pkg1 # Go two levels up then import pkg1\nimport ...mod2 # Go two levels up then import mod2\n")),(0,l.kt)("h3",{id:"importing-from-a-root-path"},"Importing from a Root Path"),(0,l.kt)("p",null,"Suppose we have a ",(0,l.kt)("inlineCode",{parentName:"p"},"kcl.mod")," file in the directory to mark it as a root path, then we have the following files:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre"},"    .\n    |\u2500\u2500 kcl.mod\n    \u251c\u2500\u2500 mod1.k\n    \u251c\u2500\u2500 mod2.k\n    \u251c\u2500\u2500 pkg1\n    \u2502\xa0\xa0 \u251c\u2500\u2500 def1.k\n    \u2502\xa0\xa0 \u251c\u2500\u2500 def2.k\n    \u2502\xa0\xa0 \u2514\u2500\u2500 def3init.k\n    \u2514\u2500\u2500 pkg2\n        \u251c\u2500\u2500 file2.k\n        \u2514\u2500\u2500 subpkg3\n            \u2514\u2500\u2500 file3.k\n")),(0,l.kt)("p",null,"In ",(0,l.kt)("inlineCode",{parentName:"p"},"pkg1")," ",(0,l.kt)("inlineCode",{parentName:"p"},"def1.k"),", we can import ",(0,l.kt)("inlineCode",{parentName:"p"},"pkg2.subpkg3")," ",(0,l.kt)("inlineCode",{parentName:"p"},"file3")," using the following syntaxes."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-python"},"import pkg2.subpkg3.file3\n")),(0,l.kt)("p",null,"Importing from the root path is very convenient when the code is trying to import modules from a directory needs to look up multiple directories above this directory. At also, it is helpful to organize a large number of files in a root directory."),(0,l.kt)("h3",{id:"importing-a-module-inside-a-package"},"Importing a Module Inside a Package"),(0,l.kt)("p",null,"Note that ",(0,l.kt)("inlineCode",{parentName:"p"},"subpkg3")," is only implemented with one file ",(0,l.kt)("inlineCode",{parentName:"p"},"file3.k"),". The file can be regarded as a regular module and imported directly."),(0,l.kt)("p",null,"In ",(0,l.kt)("inlineCode",{parentName:"p"},"mod1.k"),", the importing statement would be::"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-python"},"import pkg2.subpkg3.file3\n")),(0,l.kt)("p",null,"Different from importing ",(0,l.kt)("inlineCode",{parentName:"p"},"subpkg3"),", now the name of the module is ",(0,l.kt)("inlineCode",{parentName:"p"},"file3"),". We can access the variable ",(0,l.kt)("inlineCode",{parentName:"p"},"foo")," defined in this module with the following\nstatement"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-python"},"bar = file3.foo\n")),(0,l.kt)("h3",{id:"precedence-of-importing"},"Precedence of Importing"),(0,l.kt)("p",null,"When an import statement specifies a package to import, the virtual machine first looks for a directory named according to the import statement in the file system."),(0,l.kt)("p",null,"If such a directory is not found, the virtual machine looks for a single file module."),(0,l.kt)("p",null,"For example, when the statement ",(0,l.kt)("inlineCode",{parentName:"p"},"import a.b.c")," appears, the virtual machine first looks for the directory ",(0,l.kt)("inlineCode",{parentName:"p"},"a/b/c")," from the directory of the current file. If ",(0,l.kt)("inlineCode",{parentName:"p"},"a/b/c")," is not found, the virtual machine looks for a file named ",(0,l.kt)("inlineCode",{parentName:"p"},"a/b/c.k"),". If the file is also absent, an error is reported."),(0,l.kt)("h3",{id:"package-implemented-with-multiple-files"},"Package Implemented with Multiple Files"),(0,l.kt)("p",null,"Package ",(0,l.kt)("inlineCode",{parentName:"p"},"pkg1")," is implemented with multiple KCL files."),(0,l.kt)("p",null,"Multiple files can be used to define variables, schemas and functions, and they can access names defined in other files of this package."),(0,l.kt)("p",null,"For example, suppose ",(0,l.kt)("inlineCode",{parentName:"p"},"def1.k")," defines a variable ",(0,l.kt)("inlineCode",{parentName:"p"},"foo"),", ",(0,l.kt)("inlineCode",{parentName:"p"},"def2.k")," defines ",(0,l.kt)("inlineCode",{parentName:"p"},"bar"),", and ",(0,l.kt)("inlineCode",{parentName:"p"},"def3init.k")," defines a variable ",(0,l.kt)("inlineCode",{parentName:"p"},"baz"),", when ",(0,l.kt)("inlineCode",{parentName:"p"},"pkg1")," is imported by ",(0,l.kt)("inlineCode",{parentName:"p"},"mod1.k"),", all these variable can be used"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-python"},"import pkg1\na = pkg1.foo + pkg1.bar + pkg1.baz\n")),(0,l.kt)("p",null,"Inside a module, names defined in a file can be accessed in another file without further importing. For example, suppose ",(0,l.kt)("inlineCode",{parentName:"p"},"bar")," in ",(0,l.kt)("inlineCode",{parentName:"p"},"def2.k")," would invoke ",(0,l.kt)("inlineCode",{parentName:"p"},"foo")," defined in ",(0,l.kt)("inlineCode",{parentName:"p"},"def1.k"),", it can directly use ",(0,l.kt)("inlineCode",{parentName:"p"},"foo")," like the following"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-python"},"bar = foo + 1\n")))}m.isMDXComponent=!0}}]);