From 9329e31221fc4ed471aec6008bc27cf45b158e25 Mon Sep 17 00:00:00 2001 From: Angelika Tyborska Date: Sat, 10 Aug 2024 11:32:30 +0200 Subject: [PATCH 1/3] Revert "Take-a-number needs a named function example (#1486)" This reverts commit dc4784045a10c1761d271ec44d8250099884ad16. --- concepts/processes/introduction.md | 4 ++-- exercises/concept/take-a-number/.docs/hints.md | 4 +--- exercises/concept/take-a-number/.docs/introduction.md | 4 ++-- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/concepts/processes/introduction.md b/concepts/processes/introduction.md index c809acf864..98912ec81a 100644 --- a/concepts/processes/introduction.md +++ b/concepts/processes/introduction.md @@ -5,11 +5,11 @@ 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> ``` -`spawn/1` creates a new process that executes the given 0-arity function and returns a _process identifier_ (PID). The new process will stay alive as long as the function executes, and then silently exit. +`spawn/1` creates a new process that executes the given function and returns a _process identifier_ (PID). The new process will stay alive as long as the function executes, and then silently exit. Elixir's processes should not be confused with operating system processes. Elixir's processes use much less memory and CPU. It's perfectly fine to have Elixir applications that run hundreds of Elixir processes. diff --git a/exercises/concept/take-a-number/.docs/hints.md b/exercises/concept/take-a-number/.docs/hints.md index 60789d730b..2ab5184adc 100644 --- a/exercises/concept/take-a-number/.docs/hints.md +++ b/exercises/concept/take-a-number/.docs/hints.md @@ -8,8 +8,7 @@ ## 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. +- You will need another function that the new process will execute. ## 2. Report the machine state @@ -39,4 +38,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 diff --git a/exercises/concept/take-a-number/.docs/introduction.md b/exercises/concept/take-a-number/.docs/introduction.md index 1aa2ea8cac..e6670ad8bd 100644 --- a/exercises/concept/take-a-number/.docs/introduction.md +++ b/exercises/concept/take-a-number/.docs/introduction.md @@ -7,11 +7,11 @@ 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> ``` -`spawn/1` creates a new process that executes the given 0-arity function and returns a _process identifier_ (PID). The new process will stay alive as long as the function executes, and then silently exit. +`spawn/1` creates a new process that executes the given function and returns a _process identifier_ (PID). The new process will stay alive as long as the function executes, and then silently exit. Elixir's processes should not be confused with operating system processes. Elixir's processes use much less memory and CPU. It's perfectly fine to have Elixir applications that run hundreds of Elixir processes. From d4eb7b1d722d21319a23d4027ca927316a4aa30a Mon Sep 17 00:00:00 2001 From: Angelika Tyborska Date: Sat, 10 Aug 2024 11:48:08 +0200 Subject: [PATCH 2/3] The first step does not require starting a receive loop --- concepts/processes/introduction.md | 2 +- exercises/concept/take-a-number/.docs/hints.md | 9 ++++++--- exercises/concept/take-a-number/.docs/instructions.md | 10 ++++++++-- exercises/concept/take-a-number/.docs/introduction.md | 2 +- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/concepts/processes/introduction.md b/concepts/processes/introduction.md index 98912ec81a..225bf13c19 100644 --- a/concepts/processes/introduction.md +++ b/concepts/processes/introduction.md @@ -9,7 +9,7 @@ spawn(fn -> 2 + 2 end) # => #PID<0.125.0> ``` -`spawn/1` creates a new process that executes the given function and returns a _process identifier_ (PID). The new process will stay alive as long as the function executes, and then silently exit. +`spawn/1` creates a new process that executes the given 0-arity function and returns a _process identifier_ (PID). The new process will stay alive as long as the function executes, and then silently exit. Elixir's processes should not be confused with operating system processes. Elixir's processes use much less memory and CPU. It's perfectly fine to have Elixir applications that run hundreds of Elixir processes. diff --git a/exercises/concept/take-a-number/.docs/hints.md b/exercises/concept/take-a-number/.docs/hints.md index 2ab5184adc..3fb1bbace1 100644 --- a/exercises/concept/take-a-number/.docs/hints.md +++ b/exercises/concept/take-a-number/.docs/hints.md @@ -8,15 +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. +- 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 @@ -26,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 diff --git a/exercises/concept/take-a-number/.docs/instructions.md b/exercises/concept/take-a-number/.docs/instructions.md index ad6bbaaffc..8b8db0e15b 100644 --- a/exercises/concept/take-a-number/.docs/instructions.md +++ b/exercises/concept/take-a-number/.docs/instructions.md @@ -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() @@ -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 @@ -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 diff --git a/exercises/concept/take-a-number/.docs/introduction.md b/exercises/concept/take-a-number/.docs/introduction.md index e6670ad8bd..e75b617d2d 100644 --- a/exercises/concept/take-a-number/.docs/introduction.md +++ b/exercises/concept/take-a-number/.docs/introduction.md @@ -11,7 +11,7 @@ spawn(fn -> 2 + 2 end) # => #PID<0.125.0> ``` -`spawn/1` creates a new process that executes the given function and returns a _process identifier_ (PID). The new process will stay alive as long as the function executes, and then silently exit. +`spawn/1` creates a new process that executes the given 0-arity function and returns a _process identifier_ (PID). The new process will stay alive as long as the function executes, and then silently exit. Elixir's processes should not be confused with operating system processes. Elixir's processes use much less memory and CPU. It's perfectly fine to have Elixir applications that run hundreds of Elixir processes. From aa0829ce354be87b43e0f7e85c75969e26d92ce4 Mon Sep 17 00:00:00 2001 From: Angelika Tyborska Date: Sat, 10 Aug 2024 12:02:25 +0200 Subject: [PATCH 3/3] Format --- exercises/concept/take-a-number/.docs/hints.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/take-a-number/.docs/hints.md b/exercises/concept/take-a-number/.docs/hints.md index 3fb1bbace1..3cca7fe738 100644 --- a/exercises/concept/take-a-number/.docs/hints.md +++ b/exercises/concept/take-a-number/.docs/hints.md @@ -28,7 +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. +- 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