This issue describes how to implement the pattern-matching-types concept exercise for the C# track.
Please please please read the docs before starting. Posting PRs without reading these docs will be a lot more frustrating for you during the review cycle, and exhaust Exercism's maintainers' time. So, before diving into the implementation, please read up on the following documents:
The goal of this exercise is to teach the student the basics of the Concept of Pattern Matching in C#.
switch expressions.This Concepts Exercise's Concepts are:
pattern-matching-types: know how to do type pattern matching.pattern-matching-variables: know how to do variable pattern matchingpattern-matching-when-clauses: know how to use when clauses in pattern matching.This Concept Exercise's prerequisites Concepts are:
pattern-matching-constants: how to use the switch statement to do constant pattern matching.casting: know how regular casting works.Any data types used in this exercise (e.g. strings) should also be added as prerequisites.
This exercise does not require any specific representation logic to be added to the representer.
This exercise does not require any specific analyzer logic to be added to the analyzer.
To implement this exercise, please follow these instructions.
If you have any questions while implementing the exercise, please post the questions as comments in this issue.
Please assign me to this issue, potential implementation here
@MarkusReynolds1989 I've updated your issue a little bit with the following changes:
Example.cs file to the .meta directorydesign.md file to the .meta directory.meta/design.md.docs files (for consistency)Thanks for creating the issue!
In general, I'd like this exercise to focus just on the modern, C# 8 pattern matching as described here. This means teaching:
is type pattern expression.switch statement.when clause in a switch statement.var expression in a case expression.switch expressionsThis would mean that the exercise's prerequisites would become:
conditionals-switch: know how to use a regular (old-school) switch statement.conditionals-if: know to write an if-statement.inheritance: know how inheritance works in C# and how to define base and derived classes.type-conversions-classes: this would teach the is and as operators, as well as introducing casts for classes.Note that for the Concepts and prerequisites, our main reference is this document:
https://github.com/exercism/v3/blob/master/languages/csharp/reference/README.md
Let's start with getting all maintainers to agree on what the exercise should be teaching. Once we've agreed on that, we can move on to the actual implementation.
I like the idea that we just use the C# 8.0 pattern match because in my opinion it's the best one anyway.
As for telling a story with the assignment, I liked the Zoo idea but what if we could move this more into the domain of business or database management? Perhaps we could write up some different classes for personnel, time etc. that would mimic a real companies data classes and pattern match on those? Then we could have the arms of the match just do updates or something depending on what is sent in.
I think it is pretty good to focus on the newer C# 8.0 pattern matching but, I think it would also be interesting to somehow show them a comparison of the older way of pattern matching and make a comparison between them. Maybe remind the instructor of this in the instructor's notes?
To @Alexpud's point, I like the idea of being able to show the students other other potential ways of solving the same problem, perhaps that would be something we could put in the after.md?
Regarding the story that we want to tell in this exercise, I assume we don't want to re-use what's here for potential copyright issues and/or the fact that students might find this article and have the answer already?
https://docs.microsoft.com/en-us/dotnet/csharp/tutorials/pattern-matching
Have we fleshed out what the zoo story line could be?
I think it is pretty good to focus on the newer C# 8.0 pattern matching but, I think it would also be interesting to somehow show them a comparison of the older way of pattern matching and make a comparison between them. Maybe remind the instructor of this in the instructor's notes?
To @Alexpud's point, I like the idea of being able to show the students other other potential ways of solving the same problem, perhaps that would be something we could put in the after.md?
The instructions should make it clear that this is an extension of the existing switch, which is a prerequisite to this exercise and students should thus already know about. We can definitely include some nice resources in our after.md document where the old and new approaches are compared.
Regarding the story that we want to tell in this exercise, I assume we don't want to re-use what's here for potential copyright issues and/or the fact that students might find this article and have the answer already?
https://docs.microsoft.com/en-us/dotnet/csharp/tutorials/pattern-matching
No we can't re-use that.
I liked the Zoo idea but what if we could move this more into the domain of business or database management? Perhaps we could write up some different classes for personnel, time etc. that would mimic a real companies data classes and pattern match on those
I'm totally fine with such a scenario. Whatever works, as long as it has got some sort of theme. And the inheritance does have to make sense (I've seen tons of bad inheritance examples :D).
Maybe we can collectively brainstorm a bit on the story? @MarkusReynolds1989 Were you thinking a hierarchy like Employee -> Manager/CEO/etc.?
I think it is pretty good to focus on the newer C# 8.0 pattern matching but, I think it would also be interesting to somehow show them a comparison of the older way of pattern matching and make a comparison between them. Maybe remind the instructor of this in the instructor's notes?
To @Alexpud's point, I like the idea of being able to show the students other other potential ways of solving the same problem, perhaps that would be something we could put in the after.md?
The instructions should make it clear that this is an extension of the existing
switch, which is a prerequisite to this exercise and students should thus already know about. We can definitely include some nice resources in ourafter.mddocument where the old and new approaches are compared.Regarding the story that we want to tell in this exercise, I assume we don't want to re-use what's here for potential copyright issues and/or the fact that students might find this article and have the answer already?
https://docs.microsoft.com/en-us/dotnet/csharp/tutorials/pattern-matchingNo we can't re-use that.
I liked the Zoo idea but what if we could move this more into the domain of business or database management? Perhaps we could write up some different classes for personnel, time etc. that would mimic a real companies data classes and pattern match on those
I'm totally fine with such a scenario. Whatever works, as long as it has got some sort of theme. And the inheritance does have to make sense (I've seen tons of bad inheritance examples :D).
Maybe we can collectively brainstorm a bit on the story? @MarkusReynolds1989 Were you thinking a hierarchy like Employee -> Manager/CEO/etc.?
Yes, exactly like that. We could calculate their pay per hour or benefits or something.
Yes, exactly like that. We could calculate their pay per hour or benefits or something.
I like that! Do you like it @robkeim @Alexpud?
One question I have for everyone, should I put the classes in separate files as I think is standard, or should we group them together so it's easier for students to see the inheritance?
public abstract class Employee
{
private string Name;
private int PositionCode;
//etc.
public Employee(...){etc.}
public Int PayPerHour(...){implement...}
}
public class CEO : Employee
{
//Should this be in a separate file?
}
I'd like some feedback into what in particular we'd like the methods to potential be to pattern match on as well. I understand we don't want it to be math heavy so I'm welcome to any ideas!
@
Yes, exactly like that. We could calculate their pay per hour or benefits or something.
I like that! Do you like it @robkeim @Alexpud?
I do like it!
Now, regarding
One question I have for everyone, should I put the classes in separate files as I think is standard, or should we group them together so it's easier for students to see the inheritance?
public abstract class Employee { private string Name; private int PositionCode; //etc. public Employee(...){etc.} public Int PayPerHour(...){implement...} } public class CEO : Employee { //Should this be in a separate file? }I'd like some feedback into what in particular we'd like the methods to potential be to pattern match on as well. I understand we don't want it to be math heavy so I'm welcome to any ideas!
I would also prefer to separate the classes into separate files but, I think that would be a little different from what we see on exercism exercises though. But, that might be a sign that we can start doing that now, maybe that can teach the student more about organizing solutions and projects better.
But, then again, it comes to a limitation: right now, we submit only the main file for the solution, so dividing the execise into different files would force us to solve that problem.
What do you guys think? @ErikSchierboom @robkeim
One question I have for everyone, should I put the classes in separate files as I think is standard, or should we group them together so it's easier for students to see the inheritance?
I'd like the classes to be in the same file, as that will make the in-browser coding experience so much better.
maybe that can teach the student more about organizing solutions and projects better.
Small note: we want to teach language fluency, but not language proficiency. In general, you can think of this as: we want users to know how to write C#, but not necessarily how to write C# in a corporate environment. We can link to/write a document that goes into details on how to organize a project, for example in the after.md file.
//All in the same file so the student can read it easily and so it runs in the web
public abstract class Employee
{
private string Name;
private int PositionCode;
//etc.
public Employee(...){etc.}
public Int PayPerHour(...){implement...}
}
public class CEO : Employee
{
//Constructor etc
public string DisplayInfo()
{
return $"Employee Name is {Name}\nEmployee pay per hour is {Salary}\nEmployee position code is {PositionCode}";
}
}
...
var employee = Employee switch
{
CEO c => Console.WriteLine(c.DisplayInfo());
_=> etc...
In this example:
We could just ask them to return the display string and test that pretty easily.
No math
Simple inheritence
The student can pattern match on the kind of employee and we can hard code a salary, name etc. on each field.
All great! So we can now move on to thinking of a test structure to teach the things we want to teach. So what I would love is for the tests to guide the student towards different solutions. Ideally, I'd want the student to learn about:
if (x is Y) .... pattern. No switch-based pattern matching needed, just keeping it simple.when clauses needed.when clause.With C# 8, there are even more types of patterns that are supported:
I'm wondering if this it would make sense to include these here too, or if a separate, advanced pattern matching exercise would make sense. I'm leaning towards the latter personally.
@MarkusReynolds1989 Could you inline the hints in this issue? It currently refers to your fork.
No math
Simple inheritence
The student can pattern match on the kind of employee and we can hard code a salary, name etc. on each field.All great! So we can now move on to thinking of a test structure to teach the things we want to teach. So what I would love is for the tests to guide the student towards different solutions. Ideally, I'd want the student to learn about:
- A simple
if (x is Y) ....pattern. No switch-based pattern matching needed, just keeping it simple.- A type-based switch. No
whenclauses needed.- A type-based switch statement that uses a
whenclause.With C# 8, there are even more types of patterns that are supported:
- Positional pattern
- Property pattern
- Tuple pattern
I'm wondering if this it would make sense to include these here too, or if a separate, advanced pattern matching exercise would make sense. I'm leaning towards the latter personally.
@MarkusReynolds1989 Could you inline the hints in this issue? It currently refers to your fork.
I'd say we should probably keep that advanced pattern matching to another topic as well, I actually haven't read too much into it so that would be a learning experience for me myself, but it does look very powerful.
I'd say we should probably keep that advanced pattern matching to another topic as well, I actually haven't read too much into it so that would be a learning experience for me myself, but it does look very powerful.
It is. Great. Let's do that in a separate exercise.
Agreed that those things sound like they should be a separate exercise.
I think I'm missing something, because I don't see where we're going to have the pattern matching happening. Given the latest example from @MarkusReynolds1989 there's a switch on the employee that calls a method for the ceo in the Ceo class. If the exercise is going the way I see it going (as I mentioned, maybe I'm not understanding something correctly), wouldn't it make more sense to solve it with polymorphism and have DisplayInfo be an abstract method of Employee?
Agreed that those things sound like they should be a separate exercise.
I think I'm missing something, because I don't see where we're going to have the pattern matching happening. Given the latest example from @MarkusReynolds1989 there's a
switchon the employee that calls a method for the ceo in theCeoclass. If the exercise is going the way I see it going (as I mentioned, maybe I'm not understanding something correctly), wouldn't it make more sense to solve it with polymorphism and haveDisplayInfobe an abstract method ofEmployee?
You are right, I don't think I had enough coffee when I made that example
Hey I was letting this rest for a little while, if we are more settled I'll go ahead and clear the pull I already made, and add in a draft pull of a new solution to this. I think at this point we can pretty much kill the last one I did as it doesn't really fit into what we discussed here.
I can start working on the new version as early as today.
That would be great! And I think it would indeed be best to start over.
I'm going to have to focus on work for the next couple weeks and then I"m leaving the country for a week on the 6th. I'll do what I can to get these put together for a draft before then but I can't promise it will be ready. Just wanted to give everyone a heads up.
No worries, take your time! I'd rather it was done well than hastily :)
@MarkusReynolds1989 We're refining the various Concept exercise issues. Would you mind me updating this issue to conform to the latest version?
Sorry, I've been trying to catch up with work since I've been back. Please feel free to make any changes. I'll continue to work on this when I have more time.
No worries, thanks for the quick reply! I'll update the issue.
@MarkusReynolds1989 The issue has been updated. The main changes are:
switch statement to pattern match on constant values (basic, old-school switch).is, as and explicit casts.switch statement.when clauses in pattern matching.This can be closed as it has been implemented in the football-match-reports exercise.
Most helpful comment
I'd like the classes to be in the same file, as that will make the in-browser coding experience so much better.
Small note: we want to teach language fluency, but not language proficiency. In general, you can think of this as: we want users to know how to write C#, but not necessarily how to write C# in a corporate environment. We can link to/write a document that goes into details on how to organize a project, for example in the
after.mdfile.