跳到正文豫言技术文档

豫言 / 技术规范

本篇描述 4cdeca1 的实现。版本与适用边界见基线说明。

标签函数类型

这是当前编译器在独立实现基线之上增加的语言规则。标签属于函数类型,按参数位置核对,检查后擦除。本文与文言稿同步。

签一:语法

「差」乃化「被减数」曰「数」又化「减数」曰「数」为「数」者也。
「差」者得「被减数」曰「甲」又得「减数」曰「乙」而
 「甲」减「乙」
也。

「差」于「被减数」曰「一零」于「减数」曰「三」。

标签写在完整操作符中:化〇为〇而〇、化〇为〇者□而〇、遇〇为〇者□而〇、会〇为□而〇、〇于〇为〇。得 的标签右边须为局部名称;得 仍以 者「局部名」 绑定函数体。独立标签项与标签项外括号无法解析。

标签须为非空名称,数字记号、注释和编译器内部名称不可作标签。标签文字独立于名称环境,局部名可以与标签相同。标签允许重复,各位置的真实参数类型可以不同。

查规约关系表之前,五个带标签操作符分别映射为 化〇而〇、化〇者□而〇、遇〇者□而〇、会□而〇、〇于〇,沿用原操作符的规约关系。调用照旧左结合。定义域可以直接写类型应用,如 化「表」为「列」于「数」而「数」;调用中的复合实参须自行括起,如 于「值」曰(「加」于「一」于「二」)。

签二:类型规则

记普通箭头为 A→B,标签箭头为 ~签:A→B。

规则 普通箭头 标签箭头
形成 A、B 均为类型 A、B 均为类型且标签合法
引入 将局部名按 A 加入环境,按 B 检查体 将局部名按 A 加入环境,按 B 检查体;定义的标签须为签
消去 实参按 A 检查 实参标签须为签,实参值按 A 检查
相等 域与结果逐项相等 标签文字、域与结果逐项相等

得 在验参数类型后合成函数体类型,按参数有无标签合成相应箭头。标签保持原文,局部变量依原有绑定规则换名。

两种箭头是独立的类型构造。完整标签函数类型可以作为类型别名、参数、返回值、元组项、容器元素或泛型类型实参。变量、条件选择和调用返回的函数值均按完整类型检查。

合一比较标签和子类型。待求类型变量可以解为完整标签函数类型;独立标签项是参数描述,不能作为待求类型变量的解。期望普通回调的位置须接收普通函数;可用普通匿名函数调用标签函数来显式转接。

签三:应用与模式

第 n 个实参对应第 n 个形参,标签与真实类型均逐位检查。带标签位须写同一标签;普通位直接写实参。标签重复时仍按位置处理。

参数组、完全应用、字面右箭头展平、返回函数类型别名另起一组、隐式 凡 与 以 均沿用原有规则。隐式参数可以是类型参数,也可以是隐式值参数(凡「x」属 A 而 B,见依值类型);两者都不带标签,标签项不能作为其实参。依值箭头可以带标签:化「签」为 A 者「x」而 B。

隐式参数求解预读实参时穿过标签包装,按真实域类型匹配;读取类型的五种入口与一次有序推定规则见类型与模块类四。实参值、构造器子模式与局部变量按剥去标签后的真实类型检查。

签四:擦除与边界

类型检查后调用与模式中的标签包装消失。带类型抽象的域中保留标签,供阶段文件、接口类型、相等与悬停使用,随后随类型标注擦除。标签不参与自由变量、名称查找或换名。

运行时实参顺序、求值交错、尾位置、直接调用与原有整数去装箱保持原规则。构造器字段形、签名类别和宿主边界形按真实类型计算。无体声明按各参数有无标签合成相应匿名函数;宿主字段名和 Wasm 参数形照旧。

JSON 与豫言阶段源码保存标签项和未检查的标签抽象。标签项有一个子式;标签抽象有一个绑定体;检查后的阶段拒绝残留的未检查标签抽象。悬停中的标签箭头显示 (化「标签」为 类型 而 结果类型)。

签五:实现范围

普通值函数、匿名函数、值构造器与模式、GC 和底层模式、无体接口签名均适用。首版的类型构造器参数和着色语言遇标签时给出明确诊断。顶层函数的标签参数可以设为可省参数,见签六;可变参数、乱序调用、部分应用、标签简写和自动转接均维持既有语言边界。

当前编译器已删除 循□以〇。顶层递归以紧邻的完整签名与定义建立;局部递归写 复令。仓内原来 循「名」以 的用例已改用上述签名递归。

签六:可省参数

顶层函数的标签参数可以设为可省参数(提案 00019):签名写 可化「标签」为 类型 而,定义在同一位置写 得「标签」曰「局部名」阙则 值 而,调用时可以不传。

「框」乃
 化「宽」曰「数」可阙
 又化「高」曰「数」可阙
 又化「名」曰「文」
 为「文」者也。
「框」者得「宽」曰「宽值」阙则「二六」又得「高」曰「高值」阙则「一六」又得「名」曰「名值」而
 「名值」接『:』接(「述数」于「宽值」)接『×』接(「述数」于「高值」)
也。

「书」于(「框」于「名」曰『甲』)。
「书」于(「框」于「高」曰「三六」于「名」曰『乙』)。

两条调用依次印出 甲:26×16 与 乙:26×36。

规则:

  1. 写法。 签名的参数位置写 可化〇为〇而〇,可省参数必须带标签,可化 类型 而 报错。定义的参数处写 会〇为□默认〇而〇。签名为 可化 的参数,定义必须写默认值;签名为 化 的参数,定义写默认值时报错。两种写法的规约关系分别按 化〇而〇、会□而〇 查表。
  2. 默认值。 默认值是数据:字面量、构造器作用于数据、顶层数据的名字,与提案 00006的顶层数据规则相同,按签名里的参数类型检查。默认值含其他计算时报“可省参数的默认值只能是数据”。
  3. 配对与补齐。 调用照常写 于「标签」为 值,实参按签名次序书写。类型检查沿签名第一组显式参数逐个配对:可省参数的下一个实参标签相同就用这个实参,否则补上默认值;必填参数缺少、标签写错、次序与签名不同时分别报错。补齐后的调用是参数齐全的普通标签调用,标签照旧擦除,运行时没有额外开销。隐式参数照常用 以 给出或推定。
  4. 只能当场调用。 带可省参数的函数出现处必须是调用的头(「函」于 …、「函」以 … 于 …);当值传递、存进组值、作返回值都报“「函」带可省参数,只能当场调用;要当值用,请包一层 λ”。函数值的类型因此只有普通的带标签箭头。函数体里递归调用自己同样可以省掉可省参数。一条语句只有一个函数名、该函数的参数又全可阙时,这个函数名就是占据整句的调用头,等于全省调用(议题 201):类型检查把它补成参数齐全的调用,默认值照常补齐。这个函数名出现在别的式子里(当实参、存组值、作返回值、写在 令 的定义处)时仍按值用报错;给函数起别名的具名定义(「甲」者「函」也。)同样按值用报错。
  5. 跨模块。 默认值随模块的检查后定义导出,别的模块调用时照样补齐;默认值改了,调用方随依赖重新编译。
  6. 适用文件。 普通源文件、测试、脚本与 。底层。豫 都可以用。。接口。豫、。应用接口。豫、。底层接口。豫、。内建。豫 等无体声明与构造器暂不用 可化,写了报错。
  7. 转发。 包装函数要把可省参数转给内层函数时,自己也声明为可省参数并写默认值。

实现:可省参数的标签在类型里带内部后缀,与必填标签互不相等;签名与定义归并时,每个默认值拆成排在函数之前的隐藏顶层定义「《《默认:函数:标签》》」,类型取该参数的类型;调用处省掉的实参补成对它的引用。顶层匿名语句(脚本与壳里的一句)只写全可阙的函数名时,类型检查把整句补成不带实参的调用再照常补齐默认值;具名定义与别处按值用仍报错。悬停把可省参数显示为 可化「标签」为 类型 而。格式化器把含 可化 的签名排成每个参数单独一行。

后续版本事项:默认值引用前面的参数或类型参数;可省参数的类型引用类型参数(议题 #510,提案 00050 依赖);接口文件里的可省参数;调用处显式取默认值的写法。

签七:构造写法

「头」【项,…】 的头是「列」「典」「组值」「组类」与「《《扩展名》》」以外的名字时,这是构造写法(提案 00018 议十九)。语法分析器照旧;阐述把它记成构造节点(头加项列),名称解析按普通名字找头,类型检查按构造调用约定把它降为带标签调用,此后照常编译。

「框」乃
 化「宽」曰「数」可阙而
 化「名」曰「文」而
 化「子项」曰(「列」于「文」)而
 「文」
也。

「框」【「名」者『甲』也,『子一』,『子二』】

这一处等于 「框」于「宽」曰「二六」于「名」曰『甲』于「子项」曰(「列」【『子一』,『子二』】)(「宽」取默认值 26)。

构造调用约定:

  1. 头。 头是第一组显式参数全带标签的函数;有不带标签的参数时报“「头」不接受构造写法”。头找不到时报“未定义的构造「头」”。
  2. 命名项。 「名」者 值 也 对应带标签参数 于「名」为 值,可按任意次序书写,降级时按签名排好。签名里没有这个标签时报“构造「头」没有属性「名」”,并列出可用的属性。
  3. 可省与必填。 签名里是 可化 的参数可以不写,取定义里 默认 给的值(签六);其余参数必填,缺少时报“构造「头」缺少必填属性「名」”。
  4. 子项。 字符串项与其余项依次放进标签为「子项」的参数(类型须是 (「列」于 甲)),没有子项时是空列;头没有「子项」参数却写了子项时报“「头」不接受子项”。甲是「文」时字符串项直接放入;甲是恰有一个只收字符串的构造器的和类型时,字符串项用这个构造器包一层;其余情况报错。
  5. 信号提升。 参数类型是 「信号」于 甲、命名项的值合成出信号以外的类型时,值用「信号」类型名为「常量信号」的构造器包一层(只在构造写法里)。
  6. 小数字面。 参数类型(或信号的元素类型)是「小数」时,整数字面量当作小数字面量。
  7. 表达式码。 参数类型是 「式码」于 甲(设计库,提案 00018 第五节)、值是顶层函数名时,值用「造表达式码」构造器包一层,并附编译器把这个函数(连同它调用的函数)译成的受限中间表示文字(库/译场/分职/匠心译/式码译。豫)。降级时先写占位文字,整份文件检查完后才翻译(此时同文件的函数都已检查)。表达式层只收整数、小数、爻与元组上的算术、比较、若、虑与对顶层函数的调用,调用图须无环。
  8. 当场调用。 构造写法就是当场调用,合乎签六第 4 条。「列」「典」「组值」「组类」保留给内建写法,同名函数只能用普通调用写法。

实现:阐述(内建操作符对象定义。豫 的「阐述通序列」)对其余的头返回通用序列节点,命名项记成命名项节点;类型检查的合成与检查两个入口遇到它时调用 构造写法降级。豫 的「降构造写法」,生成带标签调用后照常检查。

后续版本事项:字符串项的包装目前只认字符串字面量,类型为「文」的变量与表达式在后续版本包装;构造节点的悬停与语义标记。