We currently have 3 different concept exercises that touch on errors and raise:
rpn-calculator (teaches errors, try-raise) https://github.com/exercism/v3/tree/88eb1dd9f43c62e6cac3c5d35ae10ad818514238/languages/elixir/exercises/concept/rpn-calculatorIt teaches that some operations might raise an error, how to rescue from an error, and mentions the ok/error tuple vs bang! function convention.
stack-overflow (teaches exceptions) https://github.com/exercism/v3/tree/88eb1dd9f43c62e6cac3c5d35ae10ad818514238/languages/elixir/exercises/concept/stack-underflow
It teaches how to define your own errors and how to raise them.
rpn-calculator-output (teaches try-rescue-else-after, dynamic-dispatch) https://github.com/exercism/v3/tree/f29582eef12e3a0b9d7ce4c99d619469a06caa31/languages/elixir/exercises/concept/rpn-calculator-output
It expands on try-rescue introducing the else and after options, and teaches about dynamic dispatch (x = ModuleName; x.func()).
While rpn-calculator and stack-overflow are perfectly good concept exercises, I have some doubts about rpn-calculator-output.
rpn-calculator-outputThe else/after options are not a stand-alone concept, but part of try-rescue. They are also not widely used. It should be enough to mention them briefly in about.md of the try-rescue concept.
The exercise depends on those operations:
{:ok, pid} = resource.open()
IO.write(pid, "...")
resource.close(pid)
This pattern could be taught either by introducing File or Port. I am 100% certain we can't teach ports on Exercism, but I am not sure about files. I heard that we shouldn't teach that... But even if I could teach an Elixir beginner about the File module, I would start with read and write as those are much simpler to use and usually what people are looking for.
I would like us to talk about a solution to this problem. My only idea at this moment is to delete the rpn-calculator-output concept exercise and come up with a new idea for an exercise that teaches dynamic-dispatch.
I agree with your proposed solution.
It is rare for me to reach for the else/after part of a try-rescue block, but I think if it is there, we should at least provide the users (students?) with the option to read more about it, so perhaps we can also change rpn-calculator exercise to guide students to a bit of documentation about it, if we decide it's not worth being part of the exercise itself?
Regarding dynamic dispatch:
I find it quite useful, however we tend to use it at work during refactors, when we determine that there is a pattern between a group of modules, rather than writing the first implementation using dynamic dispatch.
With this in mind, as an idea for an exercise, we could provide most of the code already written (maybe 2-3 modules?) and guide the students through handling just the dynamic dispatch part. What do you say?
During a rather quick google search, I've come across this blog post, which seems like a nice way of explaining it's uses. perhaps we could also use this as inspiration for the exercise?
I guess I don't see this as a problem at this point as we haven't been told we can't do this yet. I don't see a problem with having a large concept broken up into two concepts, if there is some way in them to link to their complement concept (which we have been told that there will be a way to do this). Perhaps the about for each need to be massaged for each to recognise this now that concepts are more independent of the exercises.
portsAgree, I don't think there is a nice way of wrapping this up without going outside of the bounds of the elixir language. It might be nice to have a standalone concept for completeness
FileI think this problem is predicated on the way that exercism exercises have been done, not necessarily on how they could be done. I think File is a good example of how inter-process communication/messaging occurs, especially since we don't have to use an actual file to do accomplish this. I also think that read and write may be more common, _read_ is actually _open, read, then close_ so to explain it in more detail isn't a bad thing.
I don't see a problem with having a large concept broken up into two concepts
In general I would agree if the concept was an important one. Here however, we're talking about an advanced part (after/else) of a concept that even in its basic form (try/rescue/end) is discouraged by the official docs ("In practice, however, Elixir developers rarely use the try/rescue construct." https://elixir-lang.org/getting-started/try-catch-and-rescue.html).
@neenjaw Even if you don't see that as a problem, would it still be ok with you if I tried to replace rpn-calculator-output with a different exercise, only for dynamic-dispatch? I would really like to do it because I am convinced it will improve the track, but I wouldn't want to delete your exercise without having your approval first.
Here however, we're talking about an advanced part (after/else) of a concept that even in its basic form (try/rescue/end) is discouraged by the official docs
My impression from this part of the docs is that it was intended to prevent naming hierarchies (e.g. strings1 -> strings2 or strings_basic -> strings_advanced) rather than about breaking up concepts into multiple parts.
I would rather that we focus on content generation rather than content pruning unless it directly interferes with the design.
But maybe we just need another dynamic dispatch concept exercise in addition to this?
I meant the Elixir docs telling people not to use try/rescue.
I don't see the need for a second dynamic dispatch concept exercise unless it's a replacement for this one. Creating a second one wouldn't address any of my concerns with rpn-calculator-output but rather add a second exercise that would bother me in the same way (by splitting a concept into two parts...).
We're at 29 exercises already. Our goal should not only be to create as much content as possible, but also to ensure that the current content makes sense and produces a good learning experience for the user.
My reading of this is:
after/else and dynamic-dispatch).after/else is great to teach in general, and would like a meatier dynamic-dispatch exercise.Hopefully I've understood that correctly. Please tell me if I'm wrong.
I think as we have an exercise on after/else, which Tim feels is valuable, then I think it shouldn't be pruned. It seems to me that in general "the more the merrier" is the best approach for the Concepts. I hear Angelika's concerns about overloading students with vary rarely used bits though. If this didn't teach dynamic dispatch, then nothing would rely on after/else, so it wouldn't be in the critical path as a concept, so that would maybe allays Angelika's concerns about it being taught as a Concept.
So that said, if Angelika fancies making a meatier exercise on dynamic-dispatch (probably reusing some of the intro from here) that makes sense and I think solves the problems. And then this exercise can just be about after/else, and rely on dynamic-dispatch.
In terms of files, I'm happy for Elixir to use them. I agree with Tim's explanation of my position above. As Files are important within using Elixir, I think they're valid, where I feel like they wouldn't be in the same way in Ruby. Thanks for checking that, Angelika. So rpn-calculator-output can rely on that too. It then acts as a good space for practicing files, dynamic dispatching, and learning the extension of after/else.
It might then be that further down the line we might decide this sits better as a Practice Exercise, with the after/else explained in the about.md of rescue, but we can kick that can to post-launch, when we've got a better feel for everything.
Those are my thoughts from reading all this 馃檪
So then rather than deleting it, let's migrate it to a practice exercise.
We're at 29 exercises already. Our goal should not only be to create as much content as possible, but also to ensure that the current content makes sense and produces a good learning experience for the user.
Agreed, so why don't we set aside a time to do this when we have what we think is a MVP-complete track. (35 exercises? 40? or when the concepts that you've outlined in issues are implemented)
@neenjaw I would be happy with what Jeremy proposes:
dynamic-dispatch and make rpn-calculator-output depend on it instead of teaching dynamic-dispatchfile, including both the easy to use read/write, but also open/close. This would depend on processes and pids, and should prepare the student well for rpn-calculator-outputrpn-calculator-output as a concept exercise (maybe tweak about.mds? but that can wait).If you give a thumbs up, I would create tickets for that.
I see your thumbs up and raise you a hooray!
Closing in favor of:
https://github.com/exercism/v3/issues/2802
https://github.com/exercism/v3/issues/2803
Most helpful comment
@neenjaw I would be happy with what Jeremy proposes:
dynamic-dispatchand makerpn-calculator-outputdepend on it instead of teachingdynamic-dispatchfile, including both the easy to useread/write, but alsoopen/close. This would depend onprocessesandpids, and should prepare the student well forrpn-calculator-outputrpn-calculator-outputas a concept exercise (maybe tweak about.mds? but that can wait).If you give a thumbs up, I would create tickets for that.