-
Notifications
You must be signed in to change notification settings - Fork 106
"Junior tasks" for batteries
New or potential contributors often wonder what could be done to help the project. In this document, we tried to describe some tasks that would currently be helpful, and that we think new contributors could handle.
If you're interested in one of those tasks, feel free to work on them, or ask us more detail about them. Please send us a mail on the development mailing list to let us know what you're doing, so that we avoid conflicts and duplicate work.
Of course, we're also open to other forms of contribution that are not mentioned here. If you have ideas, just come discuss them on the mailing-list. We also have a discussion mailing list for discussing things that are not directly related to code changes. Both lists are hosted by OcamlCore.
The Option
module misses an equality function.
Some pointers: BatOption.ml, BatOption.mli.
The Deque
module miss an equality function (equal
): we may want to
check if two deque currently have the same content. Due to the
implementation of deques, polymorphic equality is not what we want
here: two Deque with the same elements may not be polymorphically
equal.
Some pointers: BatDeque.ml, BatDeque.mli
If you want more: you can also add compare
. On the longer term, it
would be helpful to check if other modules lack those functions,
especially when polymorphic equality/comparison is not appropriate.
The add
function of the Map
module add a (key, value) pair to
the map. If the key is already present in the map, it is updated to
point to the new value. It would be good to have an add_if_absent
function that would retain the old value (if you can come with
a better name, discuss it on the list).
Some pointers: BatMap.ml, BatMap.mli
Note: due to factorisation between functorized an polymorphic maps,
the Map
module implementation is a bit more complex than most
Batteries module. If you need more details, ask on the list. See
also this comment in BatMap.ml
Array
miss some binary operators. It already have map2
, iter2
and some other, but miss for example fold_left2
that is in
List. It would be good that all binary operation of List
are also
in Array
.
If you want more: its not clear which operations should have
a binary version, and which shouldn't. Maybe we can do more that
what List
currently have. If you have any opinion on that, come
discuss it on the list. It would also be interesting to look at what
other modules have and should have.
Some pointers: Array documentation, List documentation
We have an issue tracker where anyone may report bugs, inconsistencies, or improvement proposal and feature wishes. Feel free to report on it, this is very useful. But you may also turn it in the other direction, and help us resolving those issues. Someone is asking for a feature and you're confident it's a good fit for batteries? You can provide a patch for it. Please consider discussing it on the list if you're unsure it's going to be accepted (for example, maybe an OCaml/C binding to ImageMagick is not the highest item on our wishlist). Reporting issues that are no longer relevant and should be closed is also helpful (you may simply post a message on them to say so).
Our inline tests are launched through our common build system (that is, a big Makefile). It would be desirable to be able to launch those tests selectively, for example only the tests concerning a given module, to speed up the develop-compile-test loop. This is discussed in this issue of our bugtracker. If you feel you're the right person for the job, don't hesitate to implement this feature.
We would like all of Batteries features to have tests. This is very helpful in particular to avoid regressions. There are however a lot of functions in Batteries that are not tested, or that are not tested enough: we want to test exceptional cases, and in particular we want to tests exceptions. If the documentation says "in this case, this exception is raised", we should have a test for it:
try ignore (function error_case); false with Expected_exception -> true
You may think writing tests is boring. But it's not ! Actually thinking about the corner cases is quite fun in its own way. And it gets very satisfying when you actually find bugs, which you will invariably do given enough tests.
Finally, there are a lot of desirable byproducts of systematic testing. To test a function, you must begin by reading its documentation. If you spot any mistake/typo here, you can fix them. If there is an example included, check that it actually compiles (it's better if it doesn't require to open the module, that is if the functions are qualified with the module name). If there is no example, you may add one (possibly one of your test that is representative enough of the function use). Finally, you may spot inconsistencies in the documentation or under-specification; in particular, it is very important that every exception that may be raised by a function is documented. If you spot such under-specification, come discuss it on the list (the solution is not always to document it as is: sometimes, the wrong exception is raised, and it's a bug).
Note on writing tests: batteries use both inline tests (that are written in comments, next to the function definition, and are collected and run by a source-mangling script) and a more regular "test suite". Both have their advantages: inline comments allow to write quick unit-test easily, which is probably what we're talking about here, but testsuites allow to test the same aspect of different modules in the same place (for example Map, PMap and Splay are passed through the same torture tests written in a functor).
For inline tests with have a bit of documentation, and for testsuites the best thing is currently to look at the source of existing test suites, such as test_map. If you find this is not as well ordered or documented or factorized as it should be, any improvements are welcome.
Some parts of any standard library do not make a lot of sense to
beginners, because it's unclear how they should be used. For example,
the functorized Map
and Set
module must be instantiated with
a comparison module. For another example, it is often unclear what the
infix operators (eg. (|>)) are for and why this operator was chosen.
In those cases, it is very helpful to write a longer code example to demonstrate the use of a particular module, function, operator or more generally idiom of the library. We warmly welcome such examples. We are also interested in reports on what you yourself found more difficult to understand than necessary.
If you come to write documentation, you may be interested in the description of the ocamldoc comments syntax reference.
Before 1.0, there has been a big change in batteries, mostly to drop the external dependencies that were perceived as a nuisance by potential adopters, and return to a less ambitious and more classic style of library construction. The documentation that had been written before this change is now partly obsolete, but also contains a lot of good things. Due to the lack of manpower, we were not able to restore it to its use, and it has slowly wordrotten in his own directory.
This old documentation would need some care. More precisely:
-
Some parts of it are definitely obsolete and can be removed.
-
Some parts are still valuable for today's batteries, and it should be made accessible to the users.
-
some parts describe things that have been disabled in the current Batteries, but are cool and nice to have, yet not very complex to enable again (I'm thinking of
ocamlfind batteries/ocaml
that would launch a batteries-enable toplevel for example). We're interested in help to have them back.
A note on documentation: David Teller had written complex yet very useful custom ocamldoc-generation modules (yes, ocamldoc has been implemented with extensibility in mind, and it's actually quite simple to add documentation generators plugin). Unfortunately, for reason that we don't fully understand, compiling the documentation with those generators was terribly, terribly slow (slower that what we have now, which is still much too slow). We therefore had to drop them and go back to the plain ocamldoc syntax. You may therefore find small oddities in the old documentation.
One less-known feature of batteries is its "help system" implemented as a toplevel plugin. While we think the underlying idea is very good, the implementation is currently lacking, and the result is not really usable (this is also one of the part that have been shadowed by the Big Change mentioned in the previous item).
If you're interested in improving this help system to make it the best friend of the OCaml hacker, this is the right time to help. You may be interested in the source code, and inspired by this proposal for improvement by Matías Giovannini.
Of course, this is related to the previous task of "reviving old documentation": once this help feature is in good shape again, we need to document it so that users can find it easily.
gasche/bluestorm (this is the same person) has recently begun an effort to make equality, comparison, hashing, serialization, collection traversal etc. available to all Batteries modules under a more-or-less unified discipline roughly similar to Haskell's type class hierarchies, or the great organization of Jane Street's Core library. See the early miling-list thread about it.
This effort is still in an early stage, and is currently located in a branch outside the main development repository. Due to the wide breadth of the desired features, any development help would be appreciated.
This may involve implementing existing interfaces for more modules, defining new interfaces, or more generally participating in the design of this new aspect of Batteries. Please come discuss it on the mailing-list if you're interested.
Remember however that it's still in the trial-and-error stage for now. While the early sign are encouraging and have been relatively well-received on the mailing-list, it may end up not being included upstream. And if it is, it would probably be in under an "experimental" denomination for the next few versions of Batteries, in order not to impose backward-compatibility as long as design changes are still possible.