Skip to content

Commit

Permalink
Merge pull request #111 from moonbitlang/Yoorkin-patch-1
Browse files Browse the repository at this point in the history
add some description of punning and `..`
  • Loading branch information
bobzhang authored Nov 21, 2023
2 parents 658ad90 + e5eb2fd commit 15cf7e6
Showing 1 changed file with 56 additions and 1 deletion.
57 changes: 56 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,53 @@ struct Stack {
}
```

#### Constructing Struct with Shorthand

If you already have some variable like `name` and `email`, it's redundant to repeat those name when constructing a struct:

```go
fn init{
let name = "john"
let email = "[email protected]"
let u = { id: 0, name: name, email: email }
}
```

You can use shorthand instead, it behaves exactly the same.

```go
fn init{
let name = "john"
let email = "[email protected]"
let u = { id: 0, name, email }
}
```

#### Struct Update Syntax

It's useful to create a new struct based on an existing one, but with some fields updated.

```rust
struct User {
id: Int
name: String
email: String
}

fn to_string(self : User) -> String {
"{ id: " + self.id.to_string() +
", name: " + self.name +
", email: " + self.email + " }"
}

fn init {
let user = { id: 0, name: "John Doe", email: "[email protected]" }
let updated_user = { ..user, email: "[email protected]" }
println(user) // output: { id: 0, name: John Doe, email: [email protected] }
println(updated_user) // output: { id: 0, name: John Doe, email: [email protected] }
}
```

### Enum

Enum types are similar to algebraic data types in functional languages. An enum can have a set of cases. Additionally, every case can specify associated values of different types, similar to a tuple. The label for every case must be capitalized, which is called a data constructor. An enum can be constructed by calling a data constructor with arguments of specified types. The construction of an enum must be annotated with a type. An enum can be destructed by pattern matching, and the associated values can be bound to variables that are specified in each pattern.
Expand Down Expand Up @@ -386,14 +433,22 @@ fn init {

## Pattern Matching

We have shown a use case of pattern matching for enums, but pattern matching is not restricted to enums. For example, we can also match expressions against Boolean values, numbers, characters, strings, tuples, arrays, and struct literals. Since there is only one case for those types other than enums, we can pattern match them using `let`/`var` binding instead of `match` expressions. Note that the scope of bound variables in `match` is limited to the case where the variable is introduced, while `let`/`var` binding will introduce every variable to the current scope. Furthermore, we can use underscores `_` as wildcards for the values we don’t care about.
We have shown a use case of pattern matching for enums, but pattern matching is not restricted to enums. For example, we can also match expressions against Boolean values, numbers, characters, strings, tuples, arrays, and struct literals. Since there is only one case for those types other than enums, we can pattern match them using `let`/`var` binding instead of `match` expressions. Note that the scope of bound variables in `match` is limited to the case where the variable is introduced, while `let`/`var` binding will introduce every variable to the current scope. Furthermore, we can use underscores `_` as wildcards for the values we don’t care about, use `..` to ignore remaining fields of struct or elements of array.

```go
let id = match u {
{ id: id, name: _, email: _ } => id
}
// is equivalent to
let { id: id, name: _, email: _ } = u
// or
let { id: id, ..} = u
```

```go
let ary = [1,2,3,4]
let [a, b, ..] = ary // a = 1, b = 2
let [.., a, b] = ary // a = 3, b = 4
```

There are some other useful constructs in pattern matching. For example, we can use `as` to give a name to some pattern, and we can use `|` to match several cases at once. A variable name can only be bound once in a single pattern, and the same set of variables should be bound on both sides of `|` patterns.
Expand Down

0 comments on commit 15cf7e6

Please sign in to comment.