Certain STYLE rules governing the conjure project: OPTIMIZE FOR FUN! ================= ABOVE ANYTHING ELSE: This project is about having fun coding a haskell implementation of the bittorrent protocol. The reason for this is to test Haskell in the environment of heavily threaded network applications and prove it to be a feasible thing. We might learn a bit about Haskell in the process and find it to be a cool programming language. If we are lucky, we might even gather some new cool tricks for programming client/server applications. We are also doing this as a defensive measure. Without this project, we might be lured into Alcohol, Amphetamine, Hashish, Cocaine, C, C++, Java, PHP and other designer drugs. We are hacking code to avoid this though some of the projects members have admitted to the before-mentioned drug abuse. For example, 2 authors are currently sedated by the use of Perl. Targets are to have well-documented code under 10k lines providing the bare bones of a bittorrent client. We are going to throw the beast at a 100 Megabit line and test the sustain rate as well as the CPU load. Under these assumptions, there are 100 100-line blocks to be written. I have begun by providing the first 4.5 blocks, so you can still join in, we still have 95.5 blocks to do ;) [2005-12-18 Update:] Sam and ADEpT went insane. 34% code, and we are extremely close to seeding! Not going to write more, because I have to code to keep up with our speed demons. [2005-12-08 Update:] Beginning taking courses at the university really hurts your productivity when the course puts out exercises to do. Combined with a bit of problems in my work-life made me be very unproductive on Conjure for the last 14 days or so. On the other hand, we have had SamB and Adept working on the code so much they have their own repositories now. I am hopefully able to get a lot of code done around the holidays, since I can use most of my time coding on this. My last count of the code was 29%, which means we are nearly 1/3 through hitting the number of code lines that the original bittorrent had when this project was started. Do you want to join in? Get in contact with one of us! [2005-11-20 Update:] Code generation has fallen a bit the last 10 days. This is due to the fact I have been researching on building thread primitives. But my ideas were in vain and did not really gain the code anything but needless abstraction. We have 24% of the code now! SamB keeps writing patches and kolmodin is a cool newcomer to the project writing QuickCheck tests. I am planning on using his QC framework as the base for a more general QC framework. [2005-11-10 Update:] We are /still/ writing code like mad! I am shocked at the amount of patches I can produce myself, and people are really helping me out here. SamB is doing a tremendous piece of work, attacking the project from one side, while I am working on primitives behind the curtains. We are up to 19% of the code now. We have the first idea of a Thread primitive based on STM.TChans, Communication with the Tracker client begins to fall into place. We have a complete Type checker for the B-code, we can keep track of which pieces to download. But most importantly: I've not had that much fun in a long time hacking on a project. Join us! Read code! Find my bugs! Give us hints on papers or articles to read! [2005-11-08 Update:] SamB is currently providing code like mad! I am hacking away on BType and making the HoldTimer actually work. 14.8% of the code done. Expectations at this speed is a working client before X-mas. [2005-11-06 Update:] Sudden coding frenzy on the project! 11.0% And I do not even know how much other people have worked on the project. Rather cool! [2005-11-04 Update:] Code goes on: 8.2 blocks of code. Join in while you can! There are numerous odd things you can attack in the TODO list. [2005-11-03 Update:] We now have 6.7 blocks of code. If I sustain this writing rate, we have the whole client in 50 days. Join hackers! Join! Let us poke fun at the ICFP contestants for being lazy slackers not able to code fast! Get people to join! =================== Instead of working 10 people on one-man-army projects, it is much better to join up, team together and kick some serious butt. Patches are encouraged. I accept the most outrageous nitpicks. Especially because I currently work in ``Ram-mode'' on the project: I ram the way for others by spewing out code faster than good is. Like all good warfare, you need to have a leap-frog team coming in and covering your back while you press on. BSD Licensing preferred over GPL ================================ If you wish to provide code, please provide it on BSD licensing terms. We may adopt GPL code, but it will reside in the GNU subdirectory of the project. However, the project must not be bogged down by mere licensing. If you goddammit want to supply code in GPL, talk to jlouis. We might be able to figure something out. Simple things ============= We strive for complete documentation. All functions and everything must be documented. If you read through the source code and find you can document a non-documented function, you are officially a hero and god if you provide me with a patch. I will personally announce `` is an extremely cool Haskell hacker'' to #haskell whenever one provides documentation for the project (However, there might be a timer in between announcements as to not spam #haskell completely by eager programmers). We strive for haddock(1) style documentation before each function call. Provide documentation, please! Iterative development ===================== If you have anything to provide, do so! The quality of the provided is not that important as we can always rewrite code that does not click anymore. Therefore, heed ``Perfect is the enemy of done''. We will rather have 8k lines of source code with opportunity for polishing than 500 lines of perfect code. The development model is strictly iterative. To keep flexibility, it is important to think modular when writing code. Either build modularity by ``pipelining'' one module after another or by ``layering'' where modules stack on top of each other to provide successively more functionality. If you have this in mind, modularity will prevail and we can exchange stuff in a later iteration. Repository layout ================= If you take a look at the repository layout, you will see it attempts to mimick the hierachy of the Haskell libraries. Things are placed in Control/*, Data/*, etc. However, there are some special directories for Conjure: * GNU -- GNU licensed software in the project. * FS -- Filesystem modules * Conjure -- Everything related to Conjure * BEncode -- Modules related to the B-coding Coding style ============ The aim is absolute hackery. Absolute hackery is achieved when the speed-of-change in the code goes below that of all other languages. To achieve this goal, we will need to have clean code above anything else. If you provide performance-patches, please bear in mind that others should be able to read them as well. Documentation of performance hacks are needed when they are nontrivial to figure out. Aim for code readability. If the code is more readable and easier to understand, we get more hackers than if it is totally incomprehensible. We also get fewer bugs, maintainability etc. Performance should always be governed by profiling. I'd rather have the cost-centre optimized to Hades than have all the code being a complete mess. Premature optimizers will be served one pint of Styx-wash! Commit policy ============= We use Darcs as a Configuration Management system. This encourages highly decentralized development. jlouis does his best to incoporate patches from everyone into the source code tree. If you want to be sure to get your patch into the tree, send the patch to jlouis@mongers.org. I might take a bit to answer though, as I do not currently have an internet connection at my home. Rest assured however, that in a few days, I will commit your patch to the repository. I try to answer everyone who sends me patches. As long as I can manage it, I prefer to thank people for their work on the project. Your attempts at curing my insanity are greatly appreciated. When writing commit messages, try to think about what you write. What you should keep in mind is, that we might want to locate exactly that patch in 4 months of time and then it helps tremendously with a good commit log. jlouis is not always good at this - so please gently tell him when his commit messages are non-understandable. A good commit message contains a title describing the change in general and possibly an elaboration if the change isn't of the simple kind. This is especially important when fixing bugs, changing semantics, APIs etc. We should strive for a commit log verbosity where the interested reader can figure out what is going on in the source by reading commit messages alone. Code reviews ============ Try to get source code patches to be read by at least 2 people. I, jlouis, currently look at all source code patches, but I would love to have volunteers to hand off source code to if the pressure at some point gets too big. The reason is to make cool patches even cooler. Each source code contribution is very valuable and I hope to highen the standards of the source code by encouraging people to read other peoples source code. You might even learn a trick or 2 by doing this. Remember that execution of code on a computer is a by-product. The important part is having the code read by another human and understood (paraphrasing from SICP, I believe). Attempt to provide signatures first =================================== This is one thing I suddenly realised when discussing with Dmitry Astapov: If you intend to build something bigger which the rest of the code should interact with, start by defining a signature (*) -- a rough skeleton -- defining the API of your parts of the code. That way you have a framework to build on and others are able to see what they can use the finished product for. (*) The word signature is something I've stolen from SML. In SML a signature is a collection of identifiers accompanied by types which a module must adhere to. You then constrain your module (called a structure in SML) to a given signature, encapsulating everything in the module, but the definitions in the signature. Compiler options ================ Code should pass a ghc -Wall at all times. Helper functions ================ Helper functions should be put in a where clause or let..in block whenever possible. Of course, if more than one function uses them, they should be lifted. Function naming =============== lowerThenUpperCase. Variable naming =============== all_lowercase_seperated_by_underscores. Imports ======= jlouis Tends to use qualified imports for most of what he does to separate name spaces as much as possible. However, there is no restriction on the imports at all. You may import directly into a name-space, but try to limit the amount of things you import to make it easier to change the code later, do new imports etc without having naming collisions. I attempt to put local imports first, then foreign library imports and at last system library imports. Each section is ordered alphabetically. Spotting one miss makes you an extremely cool code scout! SamB, on the other hand, likes to have a section for things from this project, followed by a section for things from the library, ordered approximately Text -> Data -> Control -> System -> Network. The idea is high-level things first, then lower level stuff, and then finally things external to the Haskell system.