Exercism problems in Ceylon.
If you're ever unsure about how to help, don't worry! You can just ask in the Exercism Gitter support channel or by creating an issue for the Ceylon track and we are happy to help you!
The Exercism-wide contributing guide covers topics relevant to contributing to the entire Exercism project, including but not limited to the Ceylon track.
- To report a bug or ask a question, create an issue.
- If you already have a fix for a bug, you could create a pull request.
Depending on what your contribution deals with, you may have to direct it at a certain repository:
- If your contribution deals with the README for a problem, it should go to problem-specifications.
- Otherwise, it probably deals with matters specific to the Ceylon track, in which case it goes to this repository.
- If you're not sure, you can try here and we will let you know if it should go in problem-specifications.
The Exercism site provides a list of exercises not on the Ceylon track. A possible contribution would be to choose one of these exercises and add it to this track. The Exercism documentation repo has a guide on porting an exercise.
Note that you will need to add the problem to the exercises
section in config.json
as well, otherwise it will not be available via exercism fetch
(or any other means, other than by cloning the repository).
The order in which the exercises are listed in config.json
is the order in which they will be served by default by exercism fetch ceylon
.
For the Ceylon track, the files needed to port an exercise are described in the next section about exercise structure.
Each exercise is located in the exercises
directory, in a directory with the same name as its slug (the leap
exercise will be at exercises/leap
, etc.).
This directory should contain the following files and directories, where <slug>
is the slug of the exercise with all hyphens deleted, and <Slug>
is the CamelCased version:
README.md
: The README for the exercise. This is generated from the problem-specifications repository then committed to the Ceylon track repository.- If there is Ceylon-specific information that should be appended to the Exercism-wide description from the problem-specifications repository, place these in a
.meta/hints.md
file in the exercise directory. - If the Exercism-wide description from the problem-specifications repository is completely unsuitable for the Ceylon track, override the template with a
.meta/readme.go.tmpl
in the exercise directory.
- If there is Ceylon-specific information that should be appended to the Exercism-wide description from the problem-specifications repository, place these in a
source/<slug>/module.ceylon
: the module descriptor.- This file declares the module and any dependencies.
- Typically, the only dependency will be on
ceylon.test
at the current Ceylon version. - We don't expect to declare any other dependencies in this module descriptor.
- The student is of course free to add any dependencies here if the student's individual submission requires them.
source/<slug>/<Slug>.ceylon
: the stub solution.- This file provides just the type signatures needed to make the tests compile.
- The implementations for all functions should all be
return nothing;
, which will intentionally fail the tests.
source/<slug>/<Slug>Test.ceylon
: The test file.- If there is an
exercises/<slug>/canonical-data.json
in theproblem-specifications
repository, the test cases should typically be those described in that file. - If you believe a case should be added or removed, try discussing it in the
problem-specifications
repository to see if it would apply to all tracks. - If a modification to the cases only makes sense for the Ceylon track, please note the change in the test file.
- If no JSON file is present, you may use the same tests as other languages implementing that exercise.
- Typically, we like to use parameterized tests to express the tests with minimal duplication in test code.
- If there is an
example/<Slug>.ceylon
: An example solution that passes the tests.- This will not be served to students (all paths containing
example
are not served). - Instead, it is used in our Travis CI run to make sure that the exercise is solvable and that the tests make sense.
- This will not be served to students (all paths containing
- optional:
example/module.ceylon
: The module descriptor for the example solution.- This is necessary only if the example solution has dependencies other than
ceylon.test
. - Wherever possible, the dependencies should be limited to modules under the
ceylon.*
namespace, to avoid burdening Travis CI with having to fetch many external dependencies. - We may consider adding external dependencies for an example solution if the exercise would be unnecessarily difficult and/or cumbersome without those particular dependencies.
- This is necessary only if the example solution has dependencies other than
- optional:
example/*.ceylon
- Other files may be included in the
example/
directory if appropriate.
- Other files may be included in the
As mentioned, Travis CI runs our tests to ensure that our exercises are solvable. The tests are run on all pull requests (PRs), and we should strive to only merge PRs for which the tests are passing.
It is possible to run these tests locally as well.
In particular, the bin/test-exercise
will test just one exercise:
bin/test-exercise exercises/leap
This script automates the process of moving the example files in, running the tests, and then moving the example files back. This is useful when changing an exercise in this repository. The test can be run locally to make sure everything is working without having to wait for Travis CI.
Various choices were made in the past to get the repository to the state it is in now. These choices aren't set in stone; they could be changed at a later date. But the rationale behind the current choices made will be noted here.
This repository uses ceylon format
:
https://github.com/eclipse/ceylon.formatter.
This should be automatically installed with ceylon
(it was known to be installed with SDKMan as of Ceylon 1.3.3).
CI will ensure that code follows ceylon format
.
All example code should be idiomatic Ceylon, to set a good example for anyone who might look at this repository for solutions to the exercises. The current maintainer may have trouble with this point, since the current maintainer is only a Ceylon beginner and may not be familiar enough with the language to tell what is idiomatic or not. Help in this area is especially appreciated.
The current maintainer finds it regrettable that the exercise slug must be repeated so many times: exercises/<slug>/source/<slug>/<Slug>.ceylon
.
exercises/<slug>
is required by Exercism, otherwise the exercise cannot be served.source/<slug>
is because the exercise files are placed in a module with the same name as the exercise slug.- It doesn't seem possible to run
ceylon test
without a module, since that is one of the arguments it requires. - They could all be named
main
or something similarly nondescript, but perhaps that would get confusing.
- It doesn't seem possible to run
<Slug>.ceylon
is not required for any particular reason.- Then again, what else would it be named?
- Again,
Main.ceylon
seems a bit too confusion-prone.
The current maintainer wishes there was less duplication, but does not really see a good way out. Any ideas here are welcome.
We provide the stubs with signatures included because we felt it was not a sufficiently interesting learning experience to make students have to puzzle out the expected signatures by just looking at the tests.
Because Ceylon is a statically-typed language, the entire test suite must type-check before it can be run at all. Thus, not providing the type signatures forces the students to figure out the types for all the functions being tested, rather than being able to focus on just one at a time.
The Ceylon track is not the only track that had to make this decision. Other tracks have discussed this as well, and come to various conclusions.
If students suggest that they would like to have the challenge of figuring out type signatures, we would gladly change our minds on this point. They might suggest this on the exercism.io site, or on this repository via issues. It's likely that the latter is more often monitored.
As mentioned above, we used parameterized tests since this avoids test code duplication.
Unfortunately, since by default all cases are enabled, this runs counter to the usual Exercism style in which only a single test case is enabled, and the student enables one more test case after making the previous one pass, taking an iterative process.
The ignore annotation does not seem like it can be applied to individual cases of a parameterized test.
One possible solution to this would be to comment out all cases except the first. If this solution were taken, students would need to be aware of this, and be informed that they need to uncomment the cases. The Travis CI run would need to uncomment the cases as well (without uncommenting any actual comments, which would probably cause syntax errors!).
The current maintainer does not have a good solution to this, so ideas here are welcome.