Hi!
I wanted to share some feedback this way instead of via the anonymous feedback because I think this is more honest and maybe also lets other students see this/reply.
You didn’t explicitly ask for feedback, but I still wanted to post this here, in case you want to consider it.
This post will probably be quite long, but it’s not AI-generated, and it contains a few suggestions that I think could make this course better.
The following part will sound like a long complaint, but it’s mostly an attempt at constructive feedback for the course. Overall, while I would not call the SE Lab one of my favourite courses, I see which value it provides and think this year’s iteration was quite good overall, especially with the defense improvements. So even if it’s a long list of “complaints”: most of these are just ideas, and not necessarily things that I think make the course “bad”, but rather prevent it from being as good as it could be.
I tried to structure the feedback into various categories depending on which area of the course they affect.
Organizational matters/communication
I think there were a few things that could be improved about the communication:
- The “practical tutorial” during the implementation phase was suddenly cancelled with no explanation after it was supposed to happen. This could have been done earlier.
- System test interval / mutant execution interval was not explained in any way, we mostly had to guess. The fact that system tests were not running from the start of the project was also not explained directly, the
resultsbranch had text that made it seem like they would already be running on the first day. I would appreciate a more clear explanation there in the future. - The Qualis course evaluation ended before the end of the implementation phase. I wanted to wait until the end because I wanted to actually experience everything before evaluating based on a partial impression of the course.
- Very early in the course, the forum had a post listing various tools for planning class diagrams that people may have already checked out. Then, the post was suddenly deleted and the spec required everyone to use PlantUML. Changes this late generally discourage us students from familiarizing ourselves with the tools early, and make the course look unorganized.
- Spec adjustments were only communicated through the forum, not by adjusting the PDF, which made cross-checking really annoying. This may have been intentional to make it harder to just have an LLM implement it based on the spec, but it also makes it harder for students actually working with the specification.
- A mutant was mentioned in the PDF, but didn’t actually exist; one other mutant was not in the PDF, but was tested.
Design phase
- Sometimes, reviewers contradict each other. For example, last year, I suggested simplifying parsing to utilize data classes with kotlinx deserialization so JSON is directly type-checked into data classes. The tutor I had last year claimed the library could not do this, but the project later included a library that could do this. We tried planning with it anyway and the reviewer said it would be too complicated. I disagreed with that, but because the reviewer is the one deciding whether we pass, we decided to change it. This year, presumably another reviewer seemed to suggest exactly that pattern: https://forum.se.cs.uni-saarland.de:51443/t/about-implementation-after-design-phase/123. So 3 different course staff members apparently have different opinions about the same topic. This was split across two years, but I think it is confusing and makes the review process seem less objective.
- What is communicated during the design phase about the parser is confusing. A design that is made without being aware of what the JSON schema does is less “clean” than one where the JSON schema already does ~80% of all validation.
- Relating to my earlier point, how to “cleanly” parse the files in Kotlin is not really taught in the lecture, and not cleared up by reviewers either, who seem to have conflicting opinions there. In general, writing the parser part is rather “mechanical” and doesn’t really allow for much variation in code or design, so maybe this could be simplified by providing pre-existing data classes or more guidance. Right now, it is a large amount of code, but not really a “design challenge”.
- Sequence diagrams are really annoying to create. I understand the benefits they have, but in a design that splits responsibilities across classes, a sequence diagram can get messy extremely quickly. A high-level overview diagram and then “sub-diagrams” for different actions would be cleaner and reduce the complexity of creating/reviewing them.
Implementation phase
- Regarding LLMs, I would appreciate a somewhat stricter policy. During implementation phase, a member of my group started writing tests with an LLM, which is obviously very fast, even at more complex scenarios that would probably take a human a while to correctly “plan” according to the spec. I know it’s hard to enforce something, but explicitly allowing it even encourages it.
- I guess most students also saw the Prog 2 exam results, which were not exactly good this year. At this point, many students can’t write code, even when somehow passing Prog2 (some students explicitly said this about themselves, this is not just my impression). I believe this LLM usage plays a very large role in this.
- The way individual contributions are calculated also has a few issues. It does not consider the actual effort of writing the code (e.g. a parser could easily be lots of code, but is rather “simple”, while actual simulation logic is more complicated). Small bug fixes that also involve changing the indentation (for example when removing/adding a wrapping if) suddenly make the contribution counted as someone else’s and make a person’s “code survival rate” go down. Also, I felt like whenever one person was behind in one area (main/test/systemtest), we were encouraged to do more in the other areas, leading to someone “catching up” and then someone else being “last place” and that person being told to catch up again.
- The fact that the system test runner is closed source discourages extending it (e.g. I could have built my “better systemtest runner” with an interactive overview a lot easier if the library was source viewable) and encourages bad security practices (running unverified libraries from a package registry is how a lot of supply chain security incidents recently happened)
- In some cases, detekt rules lead to less clear code in my opinion. For example, parsing can be implemented as a sequence of: parse a file, check if valid, return if not. Being allowed only 2 return statements makes writing a parse/simulation initialization function more complicated.
- Maybe the lecture could help by providing more examples of good/elegant code
Kotlin
Changing languages is probably quite complicated, but I wanted to at least mention this at the end. Overall, I think Kotlin is a good choice, but there are some things that make it confusing in my opinion:
- Copies/References: Unlike C, Rust, C++, Zig, etc., Kotlin and Java do not make it clear in the language whether a function wants a reference and whether it mutates it. Being able to clearly mark something as expecting a copy or a mutable/immutable reference makes code much more clear (at least to me).
- The way returns inside lambdas works is a bit confusing to me, but is fine after getting used to.
Considering system tests only check logs anyway, and code coverage can be generated in standardized format by various tools, allowing students to choose between languages before group assignment, similar to what for example Concurrent Programming does, could allow for more flexibility. A language like C++ or Swift (C++ may be considered “too complicated” because of the fully manual memory management) could be a good alternative language for the lecture, while still allowing everything the lecture normally teaches.
Overall, I still think you made a quite good course that does what it’s supposed to. I know this post had a lot of things that I disliked, but it’s easier to point out the things that could be improved than all the things that are good.