The first test is here. It seems to me that they are treating Robot as a variable whose content can be changed by robot_simulator:place/3. Do you think so? Am I missing something?
Hello Im a newb so this might be totally wrong, but the way I would do this is make robot a process, so create would spawn a process (or an actor). That actor can have its own state (as a record or something) and then the messages to it can create new versions of that state. This means you can have state, and it can change over time, but the functions in your robot process will be functionally pure, you wont actually be modifying the state.
% in robot as a gen_server
handle_call(advance, _From, S = #state{pos=P, dir=D}) ->
NewPosition = handle_advance(P, D),
{noreply, S#state{pos=NewPosition}}. % here is a new state
handle_advance({X, Y}, north) -> {X, Y + 1 };
handle_advance({X, Y}, south) -> {X, Y - 1 };
...
Someone please jump in and batter me if this is wrong
Without giving you too much information, @phsort is right.
Robot (the variable) is supposed to be a handle for a living Robot.
There is more than one way to implement that, but the typical one is to use a process for each robot and return its Pid on robot_simulator:create/0.
If you want to be more creative, you can try implementing the robot by storing its state in an ets table… But I would recommend you to try this approach only after you had learn how to solve the issue with processes
Short answer: @phsort and @elbrujohalcon are right: you are supposed to do it with a process, be it a gen_server or gen_statem implementation or just a plain loop.
And @elbrujohalcon is also right that you could do it with an ets table (or the pdict even, if you want to get real dirty ), but that is (IMO) really not the way it should be done. While Exercism has no requirements concerning how an exercise is to be solved, my advice is to not deliberately do things different than everybody else just for the sake of doing it different
That said, @adolfont, if you are stuck (or just want to cheat), there is always a reference/example solution in the exercises It is not always the best solution, mind you, it is just there to demonstrate that the exercise can be solved.
I will admit to having uploaded a couple of non-working solutions to see how others have handled different problems when I’ve been completely stuck. And, of course, getting great advice on the Erlang Slack #learning channel.
Just an update. As pointed out above, there was nothing wrong with the tests. If there is something wrong, it is that this exercise is intermediate for other languages but for Erlang, having to use gen_server, it is closer to hard. However it was very fun to solve and @elbrujohalcon (my mentor on Exercism) helped me a lot. Thanks!
Good job! “Have to” may be a bit of an exaggeration, I think this one is easier to solve without gen_servers using just ! and receive, but gen_servers are great and it’s a good thing if you already got to learn to use them.
gen_server is not necessarily the optimal way to solve all problems involving message passing though. It’s out of scope for the exercise, but consider for example if two robots could co-exist using your solution.