Skip to content

Commit

Permalink
Refine Take-A-Number (#1511)
Browse files Browse the repository at this point in the history
* Revert "Take-a-number needs a named function example (#1486)"

This reverts commit dc47840.

* The first step does not require starting a receive loop

* Format
  • Loading branch information
angelikatyborska authored Aug 29, 2024
1 parent 6b27c26 commit 3ea44a6
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 9 deletions.
2 changes: 1 addition & 1 deletion concepts/processes/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ In Elixir, all code runs inside processes.
By default, a function will execute in the same process from which it was called. When you need to explicitly run a certain function in a new process, use `spawn/1`:

```elixir
spawn(&my_function/0)
spawn(fn -> 2 + 2 end)
# => #PID<0.125.0>
```

Expand Down
11 changes: 6 additions & 5 deletions exercises/concept/take-a-number/.docs/hints.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,17 @@
## 1. Start the machine

- The machine should run in a new process. There is [a built-in function that starts a new process][kernel-spawn-1].
- You will need another function that the new process will execute. You can name it, for example, `loop`.
- Use the [capture operator][special-forms-capture] to pass a named function as an argument.
- Use a 0-arity anonymous function when starting a new process. This function doesn't need to do anything yet.

## 2. Report the machine state

- The machine's process needs to respond to messages.
- You will need a new named function. You can name it, for example, `loop`.
- This new function should accept one argument, the state.
- The 0-arity anonymous function from the previous step can call the new named function, passing the initial state.
- The new named function needs to respond to messages.
- There is [a built-in function that waits for a message to arrive in the process's mailbox][kernel-receive].
- There is [a built-in function that sends a message to another process][kernel-send].
- Use recursion to wait for more than one message.
- Pass the machine's state as an argument to the recursive function.

## 3. Give out numbers

Expand All @@ -27,6 +28,7 @@

- This step doesn't require sending any messages as a response.
- A process will exit if it has no more code to execute.
- When you need to create an "empty" code block in Elixir, you can use `nil` as the only expression in that code block.
- This is a base case of the recursive function.

## 5. Ignore unexpected messages
Expand All @@ -39,4 +41,3 @@
[kernel-spawn-1]: https://hexdocs.pm/elixir/Kernel.html#spawn/1
[kernel-receive]: https://hexdocs.pm/elixir/Kernel.SpecialForms.html#receive/1
[kernel-send]: https://hexdocs.pm/elixir/Kernel.html#send/2
[special-forms-capture]: https://hexdocs.pm/elixir/Kernel.SpecialForms.html#&/1
10 changes: 8 additions & 2 deletions exercises/concept/take-a-number/.docs/instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ You are writing an embedded system for a Take-A-Number machine. It is a very sim

## 1. Start the machine

Implement the `start/0` function. It should spawn a new process that has an initial state of `0` and is ready to receive messages. It should return the process's PID.
Implement the `start/0` function. It should spawn a new process and return the process's PID. The new process doesn't need to do anything yet.

```elixir
TakeANumber.start()
Expand All @@ -15,12 +15,15 @@ Note that each time you run this code, the PID may be different.

## 2. Report the machine state

Modify the machine so that it can receive `{:report_state, sender_pid}` messages. It should send its current state (the last given out ticket number) to `sender_pid` and then wait for more messages.
Modify the machine so that the newly spawned process is ready to receive messages (start a _receive loop_) with an initial state of `0`. It should be able to receive `{:report_state, sender_pid}` messages. As a response to those messages, it should send its current state (the last given out ticket number) to `sender_pid` and then wait for more messages.

```elixir
machine_pid = TakeANumber.start()

# a client sending a message to the machine
send(machine_pid, {:report_state, self()})

# a client receiving a message from the machine
receive do
msg -> msg
end
Expand All @@ -34,8 +37,11 @@ Modify the machine so that it can receive `{:take_a_number, sender_pid}` message

```elixir
machine_pid = TakeANumber.start()

# a client sending a message to the machine
send(machine_pid, {:take_a_number, self()})

# a client receiving a message from the machine
receive do
msg -> msg
end
Expand Down
2 changes: 1 addition & 1 deletion exercises/concept/take-a-number/.docs/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ In Elixir, all code runs inside processes.
By default, a function will execute in the same process from which it was called. When you need to explicitly run a certain function in a new process, use `spawn/1`:

```elixir
spawn(&my_function/0)
spawn(fn -> 2 + 2 end)
# => #PID<0.125.0>
```

Expand Down

0 comments on commit 3ea44a6

Please sign in to comment.