V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Kulics
V2EX  ›  程序员

Lite 语言——从入门到放弃(一)

  •  
  •   Kulics ·
    kulics · 2019-07-27 09:09:48 +08:00 · 3158 次点击
    这是一个创建于 1938 天前的主题,其中的信息可能已经有所发展或是发生改变。

    Lite 是我设计开发的一门编程语言,主要关注如何设计更简洁的语法,经过两年改进,现在只需要很少的代码量就可以表达现代编程语言的大部分逻辑,去掉了关键字设计。

    目前仍在持续改进中,欢迎到 Github 提意见,走过路过别忘了点个 Star。

    github.com/kulics/lite

    变量声明

    在 Lite 中,变量声明的格式为

    # id type #
    a int
    

    是的,不需要关键字开头,只需要用空格分割,后面部分就是类型。

    也不需要 ; 结尾,编译器会根据特定换行规则断句,除非想在一行内写多个语句,就可以加上 ;

    Lite 是一门强类型语言,大部分时候都需要明确的类型,但是有丰富的自动推导特性节省代码。

    赋值

    一句话带过。

    # id = value #
    a = 0
    

    声明时初始化

    把前面两个连起来就可以了。

    # id type = value #
    a int = 0
    

    Lite 具有自动推导特性,所以类型可以省略,然后就和赋值语句一样了。 编译器会分析是否存在变量,如果变量不存在就会自动声明。

    a = 0  # 创建变量 #
    a = 1  # 赋值 #
    

    注释

    Lite 使用 # 来表示注释,用前后两个包住内容即可。

    #
    注释
    注释
    注释
    #
    

    基础类型

    快速带过

    a int = 100000000            # i8 = sbyte,i16 = short,int = i32 = int,i64 = long #
    b num = 3.141592653          # f32 = float,num = f64 = double #
    c bool = true                # bool = bool #
    d str = "hello"              # str = string #
    e any = 0                    # any = object #
    

    字符串插值

    可能在其它语言里我们经常会图方便使用 + 拼接字符串。

    var txt = "hello" + integer.ToString() + "world!";
    

    现代语言会提供特殊的插值语法加糖。

    var txt = "hello $integer world!";
    

    Lite 更直接一些,省略掉 + 就可以达到插值效果,前后被字符串包围的值会被自动插值。

    txt = "hello" integer "world!"
    

    基本操作符

    快速带过

    a = 4
    b = 2
    c = a + b      # 加 #
    c = a - b      # 减 #
    c = a * b      # 乘 #
    c = a / b      # 除 #
    c = a % b      # 取余 #
    c = a ** b     # 幂 #
    c = a // b     # 根 #
    c = a %% b     # 对数 #
    
    d = false
    d = a == b   # 等于 #
    d = a >< b   # 不等于 #
    d = a > b    # 大于 #
    d = a >= b   # 大于等于 #
    d = a < b    # 小于 #
    d = a <= b   # 小于等于 #
    
    d = true & false     # 逻辑与 #
    d = true | false     # 逻辑或 #
    d = ~true            # 逻辑非 #
    

    基本集合类型

    数组类型表示为 []type ,用 []type{ value, value, value...} 包裹元素初始化。

    a []int = []int{1,2,3,4,5}
    

    一般情况下可以自动推导类型,使用 {value,value,value...} 直接初始化即可。

    a = {1,2,3,4,5}
    

    字典类型表示为 [type]type,用 [type]type{ [value]value, [value]value, [value]value...} 包裹元素初始化。

    b [str]int = [str]int{ ["1"]1, ["2"]2, ["3"]3 }
    

    一样可以使用自动推导类型。

    b = { ["1"]1, ["2"]2, ["3"]3 }
    

    使用索引语法 id[value] 即可取得某个索引对应元素的值。

    v = a[0]     # 数组索引从 0 开始 #
    v = b["3"]   
    

    选择结构

    Lite 的选择结构很简单,不需要使用 if,else,elif,switch,select,case,default,break 这些关键字。

    只需要用 ? 和指定的位置规则就可以进行多种操作。

    纯分支结构用来对单纯的条件进行匹配,只会进入条件成立的分支 ( if else )

    a = 1
    ? a == 1 {
        # 执行逻辑 #
    } a == 2 {
        # 执行逻辑 #
    } _ {
        # 当上面条件都不满足时执行逻辑 #
    }
    ? true {
        # 执行逻辑 #
    }
    

    值匹配结构用来对某个值进行多条件匹配,只会进入条件成立的分支 ( switch )

    a = 1
    a ? 1 {
        # 执行逻辑 #
    } 2,3,4 {
        # 合并多个条件执行逻辑 #
    } _ {
        # 当上面条件都不满足时执行逻辑 #
    }
    

    循环结构

    Lite 的循环结构很简单,不需要使用 for,foreach,while,loop,in,of,range 这些关键字。 只需要用 @ 和指定的位置规则就可以进行多种操作。 集合循环用来对集合进行遍历 ( foreach )

    a = 0
    arr = { 1,2,3,4,5 }
    id @ arr {    # 取出单个元素,定义为变量 id #
         a += id
    }
    

    如果需要同时取出元素的索引和值,可以使用 [id]id 语法。

    [index]value @ arr {
        # 执行逻辑 #
    }
    

    计数循环用来对指定数字集合进行遍历,比如从 0 数到 100 ( for )

    计数需要引入特殊的范围表示语法 start ..< end : step,step 为步长,可以省略,默认为 1。中间的操作符可以指定 >,>=,<,<=四种,分别表示 降序,降序到达最后一位,升序,升序到达最后一位。

    a = 0
    i @ 0 ..< 100 {  # 0 到 99 #
        a += i
    }
    i @ 0 ..<= 100 {  # 0 到 100 #
        a += i
    }
    i @ 100 ..> 0 : 2 {  # 100 到 2,步长为 2 #
        a -= i
    }
    

    条件循环,满足条件时进行继续循环 ( loop )

    @ a > b {
        # 执行逻辑 #
    }
    

    无限循环,很简单,只用 @ 就可以了 ( while )

    @ {
        # 执行逻辑 #
    }
    

    跳过当前循环和跳出循环也很简单( continue, break )

    i @ 0..<100 {
        ? i < 50 {
            # 跳过当前循环 #
            ..@
        } _ {
            # 跳出循环 #
            @..
        }
    }
    

    结尾

    以上是 Lite 最基础的语法结构,对比起其它语言的语法是否更简洁呢?

    下一次我们会来看看如何用简洁的语法表达函数和数据结构。

    22 条回复    2019-07-29 21:08:22 +08:00
    dixeran
        1
    dixeran  
       2019-07-27 09:25:43 +08:00 via Android
    “关键字”本身是有语义的,用各种符号来代替 for/in/continue,记忆成本加不少
    love
        2
    love  
       2019-07-27 09:39:05 +08:00   ❤️ 1
    建议放弃这个项目
    zhujinliang
        3
    zhujinliang  
       2019-07-27 09:42:19 +08:00 via iPhone
    如何记住 @..和..@分别对应哪个?
    ech0x
        4
    ech0x  
       2019-07-27 09:42:21 +08:00 via iPhone
    我就问一句有 sum types 吗?
    zifangsky
        5
    zifangsky  
       2019-07-27 09:56:48 +08:00
    建议放弃+1,太过花里胡哨,目测用这个语言做出来的项目在维护的时候会非常坑(不过楼主造轮子的积极性还是值得鼓励的
    jsjzyryuan
        6
    jsjzyryuan  
       2019-07-27 10:03:06 +08:00
    @ 0 .. 这是啥?
    trait
        7
    trait  
       2019-07-27 10:11:33 +08:00 via iPhone
    类型放后面又不给分隔符,过于丑陋
    Mistwave
        8
    Mistwave  
       2019-07-27 10:14:40 +08:00 via iPhone
    放弃了,把常用关键字用符号代替哪里简洁了
    ClarkAbe
        9
    ClarkAbe  
       2019-07-27 10:29:11 +08:00
    var qaq="->"
    emmmm,在 PHP 的面向对象超多 qaq 过后就特别反感 qaq,感觉小拇指都要断了,然后在 Golang 终于解脱了.....
    hourann
        10
    hourann  
       2019-07-27 11:18:19 +08:00 via iPhone
    如果要精简,利用符号来表达其他语言依托于关键字才能表达的语义的话,可以参考 J 语言,大概是这条路走到极致的表现。
    pisc
        11
    pisc  
       2019-07-27 11:48:29 +08:00 via Android   ❤️ 1
    我觉得吧,一方面,虽然不是正经做 PL 的,所以有时候显得业余和幼稚,但是想造个语言,写个编译器玩玩的什么的还是值得鼓励的。

    另一方面,我已经看到过很多次了,就是很多人会觉得会做编译器,造个编程语言是一件很了不起的事情,然后到处宣传,老忽悠,你不能拿一坨垃圾(可能你也不知道)来骗群众,让别人觉得 PL 就是这样的一个领域,这样的人已经够多了,导致现在风气特别差,或许是因为大家也不是这么了解 PL,经得起忽悠。

    我是建议如果想好好干,就把书和论文好好读一遍,别那么无知,如果想玩玩也很好啊,把态度放端正,明确告诉大家这是我做的小玩具,大家讨论讨论,我觉得那样挺好的。

    你可能也不服气,比如你把声明和赋值搞成一样,感觉非常简洁、聪明的 feature,然而放到 real world 场景下就是 bug 的温床。

    我现在越来越觉得写编译器是一回事,如果是设计语言,最重要是要有好的 taste。
    vscode
        12
    vscode  
       2019-07-27 11:50:20 +08:00
    为什么一定要用符号顶替关键字呢?挑战程序员的语言习惯真的不好。
    本身关键字就是有语义的,也符合阅读时候的脑回路习惯。
    各种符号。。。。。。
    港真,有些时候写到 a || b 我都想写成 a or b
    marcong95
        13
    marcong95  
       2019-07-27 11:53:02 +08:00
    这么看下来,好像用符号代替关键字倒也不是不可取,消去了关键字本身的语义,提供了通过语法结构区分 if/switch,for/while 的可能性。go 强行用 for 来写 while 反而怪怪的,@就没有这种感觉了

    不过我觉得 // %%不是很合理,有种强行往**靠的感觉
    marcong95
        14
    marcong95  
       2019-07-27 11:59:42 +08:00
    @marcong95 #13 如果再动态类型一下,给小朋友玩,说不定还能有点搞头。
    GM
        15
    GM  
       2019-07-27 16:31:37 +08:00
    号称关键字极少,事实上一堆 @ ! ?特殊关键字,问题是大家不看文档还不知这些特殊关键字是什么意思。
    纯粹是为了减少关键字而减少关键字。
    Leigg
        16
    Leigg  
       2019-07-27 18:21:54 +08:00 via Android
    所以,让人们使用 lite 语言的理由是什么? lite 语言的核心优势是什么?解决了什么问题?这个特点是否足以驱使人们使用 lite ? 你重点好像没说。
    Kulics
        17
    Kulics  
    OP
       2019-07-29 20:22:22 +08:00
    @marcong95
    1. // 和 %% 在语言里也没其它用途,没有语法冲突,就索性把 root 和 log 功能都加上了。都是转成库函数来运行,其实不用操作符也可以不用。只是有个 ** ,不加上我有点强迫症。
    2. 其实现在的语法去掉类型也是完全能放在动态语言上跑的,的确是挺好玩的。目前我是因为自己写项目要用,就一直折腾下来,以后有空可以捣鼓下动态类型和 shell。
    Kulics
        18
    Kulics  
    OP
       2019-07-29 20:25:19 +08:00
    @GM 嗯,数的没错,的确是 1,2,3,一堆关键字,实在是太多了,都快比我手指都多了,太难记了。
    Kulics
        19
    Kulics  
    OP
       2019-07-29 20:35:27 +08:00
    @ClarkAbe emmmmm。。。go 里面也一堆<-,解脱个啥
    Kulics
        20
    Kulics  
    OP
       2019-07-29 20:46:05 +08:00
    @hourann 谢谢你的建议,我去看了,的确有意思
    GM
        21
    GM  
       2019-07-29 20:51:53 +08:00
    @Kulics 是是是,非常少,我水平太低,不应该评论这么高大上的项目,告辞告辞。
    Kulics
        22
    Kulics  
    OP
       2019-07-29 21:08:22 +08:00
    @Leigg 这些不是我现在关注的。
    我关注的是如何用尽可能少的语法表达逻辑,还能用怎样少的字符组成功能完备的编程语言,还应该降低读写负担,尽可能把注意力留出来解决问题。
    简单性、可读性、可理解性是设计目标(当然,因人而已,挑战旧习惯从来不是容易的事情,也不是每个人都会喜欢我的路线)。
    现在只能依赖目标语言,这些能力都受目标语言影响。以后到 llvm,才有条件考虑自身的特性。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2859 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 20ms · UTC 11:35 · PVG 19:35 · LAX 03:35 · JFK 06:35
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.