sml

SML { ❄ }

中文 EN

Chapter 2: Blocks and Nesting

Chapter 2: Blocks and Nesting

The previous chapter only had flat key values. The real configuration is hierarchical - one person has an ‘address’, and one service has a’ database setting ‘. This chapter studies object blocks andarrays.

2.1 Object Blocks (Nested Key Values)

Wrap a set of key values in curly braces {} to form a “block”:

address: {
    street: "21 2nd Street"
    city: New York
    state: NY
}

Colons can omit - this is a characteristic of SML:

address {
    street: "21 2nd Street"
    city: New York
    state: NY
}

The above two writing methods are completely equivalent. address { }address: { }, You can use whichever you like.

2.2 blocks can be infinitely nested

database {
    primary {
        host: db1.internal
        port: 5432
    }
    replica {
        host: db2.internal
        port: 5432
    }
}

Key point: SML does not rely on indentation to determine hierarchy, but relies on curly braces. So you can freely indent, indentation errors have no impact on parsing (but it is recommended to keep indentation, which is friendly to people).

2.3 Array

Square brackets [] represent arrays. Commas can be omitted between elements, and line breaks can also be used:

tags: [ logging metrics tracing ]      # 裸词数组,逗号可省
ports: [ 80, 443, 8080 ]               # 带逗号也行
empty: []

Array elements can also be blocks (object arrays):

endpoints: [
    { path: /health method: GET }
    { path: /api/v1 method: POST }
]

Blocks in the array also support “colon saving”:

users: [
    { name: alice role: admin }
    { name: bob role: user }
]

2.4 Top Three Forms

The top-level of an SML file can be:

  1. Key value/block mixed sorting (most common)
   name: gateway
   database { host: db1 }
  1. Pure array (suitable for “record lists”, such as sending history)
   [
     { ts: 2026-08-30T10:00 to: a@b.c status: ok }
     { ts: 2026-08-30T11:00 to: x@y.z status: fail }
   ]
      • Single object block**
   {
     name: gateway
     port: 8080
   }

The top-level scalar (such as writing a separate 42) cannot be round-trip - the SML top-level must be a “container”. This is an inherent limitation of the format.

2.5 Give it a try with your hands

Upgrade the “business card” in Chapter 1 to a hierarchical structure:

name: 张三
contact {
    email: zhangsan@example.com
    phone: "138-0000-0000"
}
skills: [ rust sml linux ]

After parsing, you will get: name="张三", contact.email=..., skills is an array containing 3 elements.

→ [Chapter 3: Fragment Inheritance](/en/book/ch03 fragments)

Hands on practice

After reading this chapter, directly modify SML in the editor below and click “Run” to immediately see the parsing results or validation errors - having output is necessary for efficient learning.

✍ 动手练习 写一个 address 块(street、city="New York"、state=NY),一个 database 块含 primary/replica 两个子块(各含 host、port=5432),一个 users 数组,元素是含 name/role 的块。
💡 提示:试试把 address { } 写成 address: { },结果是否一样?
✍ 自测考题:第 2 章自测:块与数组 得分 0 / 4
Q1. address { city: NY } 和 address: { city: NY } 两种写法结果一样吗?
Q2. 下面哪个能正确表示一个数组?
Q3. 行内对象 { name: alice role: admin } 正确的是?
Q4. 判断:SML 的数组可以混合不同类型,如 [ 1 "two" true ]。