On this page:
2.1 Overview of Basic Syntax
2.1.1 First Program
2.1.2 Comments
2.1.3 Data Types
2.1.4 Assignment
2.1.5 Value Retrieval
2.1.6 Infix Operations
2.1.7 Arrays
2.1.8 Objects
2.1.9 Path
2.1.10 User-defined Functions
2.1.11 Branching
2.1.12 Looping

2 Overview🔗ℹ

One of the core principles in the design of the Raqet language is: to keep the syntax as similar to Qing as possible.

The syntax of the Raqet language is mainly based on the Qing language, with fewer concepts to learn, making it an extremely easy programming language. Before diving into the specifics of Raqet language syntax, let’s first get an overall understanding of its syntax design. This part is suitable for users with programming experience to quickly grasp the Raqet language. If you don’t have programming experience and can’t understand it, that’s fine; we will provide a more detailed introduction later.

Every Raqet program stored in a text file should start with the following line:

#lang qing

This is not a syntax construct of Raqet; it is for Racket executable to determine which language to use.

When Raqet language code is input into the compiler, it is first divided into syntactic tokens, which can be categorized into four types–—keywords, symbols, variables, functions

Among them, keywords and symbols are fixed, and the keywords include:

                如果    再则    否则    
执行    直到    返回    跳出    继续    取反
异步    等待    尝试    排查    例行    遍历    导入    导出

One may have noticed that there are two extra keywords than that of Qing: 导入 and 导出. This is because modules in Raqet are statically linked. They act as require and provide in Racket.

Since the keyword itself is in Chinese, if it is combined with other Chinese code, it may cause ambiguity in sentence segmentation. Therefore, please remember that the keyword needs to be separated from other code, by using spaces, symbols, etc. The simplest way is to leave spaces before and after it.

The second type of grammar element is the symbol, including:

; A half-width semicolon at the beginning indicates a single-line comment
;; Two consecutive semicolons are the start of a multi-line comment, extending to another pair of consecutive double semicolons
, A comma has no specific meaning and only serves as a separator in Qing language; it is discarded during parsing
"" Half-width double quotes are used to denote strings
$ Dollars are used to pass a single parameter to a function
 
{ }    [ ]    ( )    << >>
 
+    -    *    /    %    +=    -=    *=    /=    %=
>    <    ==    >=    <=    !=    <>
&&    ||
=    :

Unlike Qing language, Raqet supports half-width symbols only. This is simply due to the fact that I cannot type full-width symbols on my keyboard. Most full-width symbols in Qing have corresponding ASCII counterparts, except for Chinese comma (、) and title marks (《 》), which is represented by the dollar symbol ($) and double less/greater than signs in ASCII respectively.

We have also provided corresponding Chinese characters for some symbols, but it is important to note that symbols will automatically act as separators in the syntax. Therefore, they can be written together with other code, but when using Chinese characters as a substitute, spaces need to be added before and after to avoid ambiguity in punctuation. The symbols and their corresponding Chinese characters include:

            除以        自加    自减    自乘    自除    自模
大于    小于    等于    大于等于    小于等于    不等于
    
    设为

Besides the fixed keywords and symbols, the rest are user-defined variables and functions. For these two syntactic elements, Raqet language uses a simple method for marking.

Those starting with # are variables, and it cannot be just a single # sign. The syntax parsing starts from the # sign and continues until the next separator, including spaces or symbols. For example:

#变量1
#甲
#乙

Those starting with @ are functions, and it cannot be just a single @ sign. The syntax parsing starts from the @ sign and continues until the next separator, including spaces or symbols. For example:

@显示
@读文本文件

2.1 Overview of Basic Syntax🔗ℹ

2.1.1 First Program🔗ℹ
@displayln $ "你好, 编程世界"
2.1.2 Comments🔗ℹ

Everything from the semicolon to the end of the line is a comment. Comments are not executed as code. Multi-line comments start with two semicolons and end with another pair of semicolons.

; This is a single-line comment. This content serves as an explanation of the code and will not be executed.
 
;;
    This is a multi-line comment
    Supporting multi-line comments
    This part of the content will not be executed
;;
2.1.3 Data Types🔗ℹ
 ; Represents the absence of a value or an empty value.
 ; Logical type, represents logical true.
 ; Logical type, represents logical false.
0xFF ; Binary type, represents binary data.
123 ; This is an integer.
4.56 ; This is a decimal.
"这是一段字符串" ; The part enclosed in double quotes is a string.
2.1.4 Assignment🔗ℹ
#甲: 123 ; Using a colon to bind the value 123 to the variable #甲 in the current context.
#乙 = 4.56 ; Using an equal sign to search for the variable #乙 in the context chain and bind the value 4.56.

Unlike Qing, Raqet is lexically scoped. Referencing an undefined variable will result in a compile-time error rather than defaulting to . The = operator can only assign values to variables, and only : can define (aka declare) variables.

2.1.5 Value Retrieval🔗ℹ

Directly calling the variable name, the compiler will not look up the value of the variable in the current context. Instead, all variable positions are statically determined. They may be global variables, function parameters, local variables, closure variables, etc. For example, after the above assignment, if we input:

#甲

We will see the following output:

123
2.1.6 Infix Operations🔗ℹ

In fact, the assignment statements mentioned above are actually a kind of infix operation. Common infix operators include:

1+2*3/4-5 ; Basic arithmetic operations.
5%3 ; Modulus operation.
2>3 ; Comparison operations, including >, <, >=, <=, ==, <>.
1 小于 2 ; Infix operations have corresponding Chinese symbols, including 加, 减, 乘, 除以, 模, 大于, 小于, 大于等于, 小于等于, 等于, 不等于
 
    ; Note: When using Chinese infix symbols, be sure to have spaces or other whitespace characters before and after them, as code separators.
 
#甲 设为 123 ; 设为 is used for declaration, corresponding to the colon.
#乙  4.56 ;  is used for assignment, corresponding to the equal sign.

Here, Raqet is different from Qing again. and 设为 operators are right-associative, allowing code like this to be written:

#甲: #乙: 1
2.1.7 Arrays🔗ℹ
[1,2,3] ; Brackets represent an array, which contains multiple elements separated by commas.
[1 2 3] ; It is also fine without using commas.
[1,2.3,"你好"] ; Arrays can contain elements of any type.
2.1.8 Objects🔗ℹ
#张三: @{ ; Curly braces represent an object.
  #姓名: "ZhangSan" ; Object properties are defined using :.
  #年龄: 15
}

The implementation strategies of objects in Qing and Raqet are vastly different. In Qing, an object is a context, and an object literal can contain any code. In Raqet, objects are typically hash tables, and object literals can only contain key-value pairs.

2.1.9 Path🔗ℹ

Similar to the concept of word grouping in Chinese, when we combine variable names, it represents the access path of the variable.

#数组: [1, 2, 3]
 
#数组#1 ; Here, we first access the variable #array, and then access #1 within #数组
 
          ; #1 here indicates accessing the element at index 1, and since array indices start from 0, #1 refers to the second element, displaying 2
 
#对象: @{
  #姓名: "Zhang San"
  #年龄: 15
}
 
@显示姓名: @[#自己] {
    #displayln $ #自己#姓名
}
 
#对象#姓名 ; Here, we first access #object, then access #姓名 within #对象, displaying ``Zhang San''
#对象@显示姓名[] ; The function within the object will execute in the object's context, here it will display the #姓名 attribute within #对象

Again, due to the fact that an object is not a context, in Raqet a member function (i.e. method) of the object need to explicitly receive a “self” argument.

2.1.10 User-defined Functions🔗ℹ
@双倍 = @[#某]{              ; @ symbol indicates a function, and the format for defining a function is @[parameter list]{execution statements...}
    2 * #某
}
 
@双倍[3]     ; Calling a function is done by adding the[argument list]after the function name
 
 
@双倍 $ 3       ; If the function has only one parameter, it can be simplified by using a comma to pass the parameter
 
 
              ; Both of the above calling methods are equivalent, and the return value is 6

The 返回 statements are not currently supported.

2.1.11 Branching🔗ℹ
如果 2 < 1 {
    #displayln $ "条件为真"    ; Since the condition for branching is true, this block of code is executed
 
}else {
 
    #displayln $ "条件为假"   ; Since the condition for branching is false, this block of code is executed
}
 
 
; If there are multiple possibilities, we can use ``再则'' for multiple judgments
 
#甲 = 3
 
如果 #甲 等于 1 {
    #displayln $ "变量#甲的值为1"
} 再则 #甲 等于 2 {
    #displayln $ "变量#甲的值为2"
} 再则 #甲 等于 3 {
    #displayln $ "变量#甲的值为3"
} 否则 {
    #displayln $ "变量#甲的值大于3"
}
2.1.12 Looping🔗ℹ
#序 = 1                   ; Set the initial value of the loop control variable to 1
 
 
 #序 小于等于 10 {       ; Execute the loop while #序 is less than or equal to 10
 
    #displayln $ #序             ; This will display numbers from 1 to 10
 
    #sequence += 1             ; Increment #序 by 1 each loop
}
 
 #次:1, #次 小于等于 5, #次 自加 1 { ; Keyword ``当'' followed by three expressions
        #displayln $ #次         ; Respectively defining the loop control variable, the loop condition, and the operation on the control variable at the end of each loop.
}
 
 
#某 = 1
 
 
执行 {                    ; Execute first, then check the loop control condition, ensuring at least one execution.
        #displayln $ #某
        #某 自加 1
 
}直到 #某 等于 5