LSR 004 - 匿名函数表达式
基本信息
- LSR 编号 004
- 标题 匿名函数表达式
- 作者 sugared functor, CGrakeski
- 状态 草案
- 类型 标准规范
- 创建日期 2025年8月13日
- Lamina 版本 未决议
摘要
匿名函数表达式,又称lambda表达式,在部分语言也叫闭包,在下文讨论中简称为lambda。
lambda是一种没有名称的函数,它们通常用在需要临时使用某些函数,且使用完毕后即可被丢弃(也即只用一次)的场景。
为了使得Lamina语言紧跟现代化语言的行列,特设立本草案。
技术规范
注:语法参考于尾随系lambda语言,本草案作者也建议使用该风格的lambda,具体原因请见下文
lamdba的语法如下:
{ arg1,arg2 -> code() }
使用antlr文法描述如下:
lambda : '{' stmt* '}'
| '{' name (',' name)* '->' stmt* };
当lambda不需要参数时,允许lambda不声明参数列表:
{ code(); };
lambda也可以复制给变量,调用被赋值的变量与调用正常函数一致:
var f = {};
f();
也可以调用字面量
{}();
调用表达式使用antlr写作:
expr : invoke | ... ;
invoke : expr '(' expr? (',' expr)* ')';
该文法是左递归文法
大部分现代化语言将自动返回lambda的最后一个表达式的值,故本草案如此规定。
var value = { 1 ; 2 ; }();
//value为2
尾随匿名函数
尾随匿名函数是一种语法糖。当我们传给函数lamdba时,我们会这样写:
func foo(f) {
f();
}
foo({ print("okay"); });
调用foo函数时包裹参数的括号是可选的,如尾随风格的匿名函数直接去掉括号:
foo { print("okay"); };
对于多参函数则采用如下方法:
//下面两个调用相同
foo(1,{ print("okay"); });
foo(1) { print("okay"); };
尾随匿名函数的antlr定义如下
expr : invoke | lambda | ... ;
invoke : expr '(' expr? (',' expr)* ')'
| expr ('(' expr? (',' expr)* ')')? lambda ;
该文法是左递归文法
多尾随匿名函数
目前大部分尾随风格系的lambda语言都不支持多尾随匿名函数,故本草案作者不支持也不反对该部分提议
尾随匿名函数参见上文,若函数具有多个函数参数,如:
func foo(f1,f2) {
f1();
f2();
}
则写作多尾随调用可如此:
foo { print("1"); } { print("2"); };