Skill 语言语法基础

1 Skill 的语言特征

Skill 是一门高级交互编程语言,基于 Lisp 语言开发,同时也支持类 C 语言语法,但是不建议使用类 C 风格写法,有些地方用 C 风格的很别捏。发展至今,Skill 不仅支持函数式编程,还支持命令式编程,而且面向对象编程也是作了支持。

1.1 程序即数据

这是 Skill 最重要的一个特征,在 Skill 中程序和数据一样被表示为列表,所以它们就像数据一样可以被操作。我们可以动态地创建或修改列表,比如一个函数可以反复被重定义,进而影响到使用这个函数的地方,这种"程序即数据"的概念使得 Skill 可以用来编写灵活的应用程序。

1.2 Skill 的表达式

既然程序即数据,那它们就一定得有共同的表示形式,在 Skill 中也称作 S 表达式,有两种:

  • 原子

原子是一个单独的值,可以是数字、字符串、符号等,比如

ini 复制代码
123         ;数字
"hello"     ;字符串
Symbol      ;符号
  • 列表

列表是由一对圆括号包围的一系列表达式,其中第一个元素通常是函数或宏的名字,后面的元素是函数的参数。列表元素间用空格隔开。列表可以彼此嵌套使用,这也是 Skill 灵活语法的直观体现。

scss 复制代码
(list 1 2 3)        ; 创建列表 (1 2 3)
(cons 1 (list 2 3)) ; 创建列表 (1 2 3)

在上面这段代码里,list 是一个函数名称,用于创建列表;cons 也是一个函数,用来连接两个列表。

1.3 Skill 的函数调用

在 Skill 中可以像 C 语言那样调用函数,也可以使用 Skill 的 S 表达式形式。例如现在有一个函数 add,接收两个数字返回相加后的结果。

  • C语言风格
scss 复制代码
 add(1 5)  ; 返回6  
  • S 表达式风格
csharp 复制代码
(add 1 5)    ; 返回6

Skill 中,函数默认返回函数体中最后一个表达式的值,如果最后一个表达式无返回值,则返回 nil,nil 表示空值。

2 特殊符号

Skill 中有一些符合具有特殊函数,且不同于常见的语言(如 C 和 Java)。

2.1 括号 ()

在 Skill 中括号代表一个列表表达式,要求第一个参数是函数,所以不能像在 C 语言里面那样随意加。如下图所示,我们给数字 1 加括号,就会报错。

给数字 1 加括号

如果想使用括号定义列表,除了使用 list 函数外,还可以使用单引号 '。

scss 复制代码
'(1 2 3)    ; 创建列表 (1 2 3)

2.2 单引号 '

Skill 中的单引号有使用原本值的意思,类似于引用的感觉。可用于创建列表及创建符号变量以及引用函数。比如

ini 复制代码
'a    ; 创建符合 a
'abc  ; 创建符合 abc
(fboundp 'add)  ; 这里的单引号就是引用函数 add 的意思

2.3 分号 ;

分号用于单行注释,我在之前已经有使用过,多行注释的形式则跟其他语言类似,使用 /* ... */ 的形式。

2.4 空格

空格用于Skill 中的元素分割。

2.5 大括号 {}

大括号把多个表达式组合成一个表达式,返回值是最后一个表达式的返回值,可以减少不必要的返回值。如图所示,下面的代码只有一个返回值 5。

大括号的使用

2.6 t

t 表示布尔值 true,false 使用 nil。此外,所有的非 nil 值都会被认为是 true,尤其要注意 0 也是 true,这与 C++ 中很不同。

2.7 中括号 []

中括号用于数组的下标访问。

3 变量及变量类型

前文我们多次提到符号、变量之类的词,这里就说说 Skill 中的变量。

变量在 Skill 中叫做 Symbol,是动态类型,使用前不需要先声明,跟 python 很像。

Skill 中的变量默认是全局变量,局部变量需要特别声明,尤其要注意这点,否则很容易改变全局变量的值,造成逻辑错误。

3.1 变量类型

  • 符号 symbol

symbol 既是刚刚说到的变量,又代表一种数据类型,类似 char 类型的变量。

第一次 a 的类型是 symbol

  • 字符串 string

是的,就是我们熟知的字符串,无需多言。

  • 整数 integer

整数。

  • 浮点数 float

浮点数。

  • 列表 list

列表是一种数据结构,也可以说是一种变量类型,这里我们就傻傻不分清,在 Skill 中连程序都是数据,数据结构其实没那么严格。

使用 list 函数或者单引号创建列表。列表对元素个数、元素类型没有限制,可以任意嵌套。要注意,使用单引号定义 list 时,不会对内部的表达式进行展开求值。

使用单引号 ' 定义list

还可以使用冒号定义只有两个元素的 list,常用于定义坐标。

ini 复制代码
 a = ( 1 : 4 )    ;定义列表 (1 4)
  • 数组 array

使用 declare 定义数组:

ini 复制代码
(declare week[7])    ; 定义一个含7个元素的数组

数组元素使用 [] 的形式进行访问,下标从 0 开始。数组可以直接使用等会赋值,是浅拷贝。

  • 关联表 Association Tables

以 key/value 的形式保存的数据的集合,key 的类型没有限制,可以是任意类型。使用 makeTable 函数创建一个table:

ini 复制代码
myTable = (makeTable "table1" 0)

"table1"是表名,并不是变量名称,0 表示从表中查不到 key 时返回 0。

3.2 局部变量

  • 使用 let 定义局部变量

不声明初始值的格式如下,定义了 a,b 两个局部变量。

使用 let 定义局部变量

声明初始值的格式,如下,局部变量 a 的初始值是 7,b 的初始值是 5.

使用 let 定义局部变量并赋初始值

  • 使用 prog 定义局部变量

prog 增加了对 return 和 go 的支持,要注意,prog 和 循环一起使用时,return 始终是返回到 prog 的外围,prog 没有赋初始值的语法。

3.3 局部变量的特性

局部变量能穿透到函数内部,就跟全局变量一样。

下图定义了两个函数 trOne 和 trTwo,trOne 先定义了局部变量 aGlobal 然后调用了函数 trTwo;trTwo 函数第一行会打印 aGlobal 的值。

局部变量穿透到函数内部

如果我们调用 trOne,发现内部的 trTwo 函数里第一行的 aGlobal 是 trOne 里定义的局部变量,值为 5;如果我们在 trOne 外面直接调用 trTwo,此时访问的是全局变量 aGlobal。

相关推荐
旧故新长1 分钟前
支持Function Call的本地ollama模型对比评测-》开发代理agent
人工智能·深度学习·机器学习
微学AI14 分钟前
融合注意力机制和BiGRU的电力领域发电量预测项目研究,并给出相关代码
人工智能·深度学习·自然语言处理·注意力机制·bigru
.生产的驴16 分钟前
SpringBoot 封装统一API返回格式对象 标准化开发 请求封装 统一格式处理
java·数据库·spring boot·后端·spring·eclipse·maven
景天科技苑24 分钟前
【Rust】Rust中的枚举与模式匹配,原理解析与应用实战
开发语言·后端·rust·match·enum·枚举与模式匹配·rust枚举与模式匹配
知来者逆25 分钟前
计算机视觉——速度与精度的完美结合的实时目标检测算法RF-DETR详解
图像处理·人工智能·深度学习·算法·目标检测·计算机视觉·rf-detr
一勺汤28 分钟前
YOLOv11改进-双Backbone架构:利用双backbone提高yolo11目标检测的精度
人工智能·yolo·双backbone·double backbone·yolo11 backbone·yolo 双backbone
武汉唯众智创30 分钟前
高职人工智能技术应用专业(计算机视觉方向)实训室解决方案
人工智能·计算机视觉·人工智能实训室·计算机视觉实训室·人工智能计算机视觉实训室
Johny_Zhao41 分钟前
MySQL 高可用集群搭建部署
linux·人工智能·mysql·信息安全·云计算·shell·yum源·系统运维·itsm
一只可爱的小猴子1 小时前
2022李宏毅老师机器学习课程笔记
人工智能·笔记·机器学习
地瓜机器人1 小时前
乐聚机器人与地瓜机器人达成战略合作,联合发布Aelos Embodied具身智能
人工智能·机器人