diff --git a/content/Scratch/en/blog/Haskell-Tutorials--a-tutorial.md b/content/Scratch/en/blog/Haskell-Tutorials--a-tutorial.md index fc4f53a..063549b 100644 --- a/content/Scratch/en/blog/Haskell-Tutorials--a-tutorial.md +++ b/content/Scratch/en/blog/Haskell-Tutorials--a-tutorial.md @@ -1,24 +1,23 @@ --- kind: article published: 2016-05-06 -image: /content/Scratch/img/blog/Haskell-Tutorials--a-tutorial/main.png +image: /content/Scratch/img/blog/Haskell-Tutorials--a-tutorial/main.jpg title: Haskell Tutorials, a tutorial author: Yann Esposito authoruri: yannesposito.com tags: programming, tutorial, haskell, documentation theme: scientific --- -blogimage("main.png","Main image") +blogimage("main.jpg","Main image")
-%tldr Haskell is awesome! But it is not perfect yet. -We can do a better at documenting our libraries. -This document provide some hints to make it happens. +%tldr My hints on how to make great documentation for Haskell libs. -**Tutorial**: +**Step-by-step tutorial/Guides**: 1. Create a `Tutorial` module containing nothing except documentation. +2. Mention the `Tutorial` module in your `cabal` description 2. Use `doctest` to check your documentation is up to date 3. For more complex real world examples, link to the test source. @@ -37,18 +36,17 @@ Great documentation could make the difference between people using your lib with and people not using your lib at all. Documentation can take many different form. -Here is the preferred order (see [What to write](https://jacobian.org/writing/what-to-write/)): -1. **Tutorials** -- write some prose which friendly take a user by hand and help him +1. **Tutorials/Guides** -- write some prose which friendly take a user by hand and help him 2. **Examples** -- how to use each function 3. **Generated API Documentation** -- haddock -## Tutorials +## Tutorials/Guides -1. Create a new module named Tutorial +1. Create a new module named `Tutorial` (or `Guide.GuideTopic`) 2. Create a link to the tutorial in the cabal description 3. Create a link to the tutorial in your README -4. Here is an example of `Tutorial` +4. Here is an example some `Tutorial` module content: ~~~haskell {-# OPTIONS_GHC -fno-warn-unused-imports #-} @@ -56,8 +54,13 @@ Here is the preferred order (see [What to write](https://jacobian.org/writing/wh Use @my-package@ if you want to ... -} module Data.Duration.Tutorial ( + -- * Introduction -- $introduction + + -- ** Subsection + -- $subsection + ) where import Data.Duration @@ -68,17 +71,35 @@ So here how you use it: >>> humanReadableDuration 1002012.002 "11 days 14 hours 20 min 12s 2ms" + +The function is 'humanReadableDuration' and +the you'll be able to click on it to go +to its definition. + +You can add images: <> +and links: . + +-} + +{- $subsection + +This is a chuck of documentation +not attached to any particular Haskell +declaration with an untested code block: + +> answer = 42 + -} ~~~ To prevent obsolescence of your tutorial, use `doctest`. That way when you'll do a `stack test` or `cabal test` -you'll get errors if the Tutorial examples doesn't work anymore. +you'll get errors if some example doesn't work anymore. ## Examples (doctest) -`doctest` is a great way to provide examples in your code documenation. +`doctest` is a great way to provide examples in your code documentation. These example will then be used as tests. Apparently it comes from Python community. @@ -94,7 +115,7 @@ myFunction = (+) ~~~ And to make it works simply verify you have a `test` bloc in your -`.cabal` file and in the main simply use +`.cabal` file and in `test/Main.hs` simply use ~~~haskell module Main where @@ -106,121 +127,194 @@ main = docTest [ "src/MyModule/MyFile.hs" ] ~~~ -## Generated +Now `stack test` or `cabal test` will check the validity of your documentation. -So even if you do nothing, haddock should generate some API documentation for you for free. -But it will be far better if you help haddock. +## Bonuses + +### Verifying documentation coverage + +1. Install haddock `stack install haddock` or `cabal install haddock` +2. Launch haddock without output format: ~~~ --- | My function description -myFunction :: Type of function -myFunction arg1 -- ^ arg1 description - arg2 -- ^ arg2 description - = ... +> haddock src/**/*.hs +Haddock coverage: + 100% ( 15 / 15) in 'Data.Duration' + 100% ( 3 / 3) in 'Data.Duration.Tutorial' ~~~ -and for data +### Continuous Integration + +There are plenty of alternative solution. +I provide the one I believe would be used by most people. +So if you use `github` simply create an account on [`travis`](http://travis-ci.org). +Add a `.travis.yml` file in your repo containing: + +~~~.yaml +language: haskell ~~~ -data MyData = X Int -instance Function MyData where - ... +If you want to use `stack` instead of just `cabal`: + +~~~.yaml +sudo: false + +addons: + apt: + packages: + - libgmp-dev + +# Caching so the next build will be fast too. +cache: + directories: + - $HOME/.stack + +before_install: +# Download and unpack the stack executable +- mkdir -p ~/.local/bin +- export PATH=$HOME/.local/bin:$PATH +- travis_retry curl -L https://www.stackage.org/stack/linux-x86_64 | tar xz --wildcards --strip-components=1 -C ~/.local/bin '*/stack' + +script: + - stack setup && stack --no-terminal --skip-ghc-check test ~~~ -Also, please launch haddock manually to see which symbols lack documentation. +Don't forget to activate your repo in travis. + +For some bonus points add the build status badge in your `README.md` file: + +~~~.markdown +[![Build Status](https://travis-ci.org/user-name/project-name.svg?branch=master)](https://travis-ci.org/user-name/project-name) +~~~ -## Prelude +Congratulation! +Now if you break your documentation examples, you'll get prompted. -> Who are you who are so wise in the way of science? +### Badges -So I am myself largely subject to criticism. -This article isn't intented to be a bible. -More like a tour of what I feel is the most appreciated way to consume documentation. -So please, no arsh feeling. +You could add badges to your `README.md` file. -I wouldn't want this article to be used as a pretext to -start an Holy War about the different Haskell coding style. +Here is a list of some: [`shields.io`](http://shields.io) -For example, I don't see anything wrong relative to the documentation of using +#### Hackage -~~~ haskell -import Prelude hiding ((.)) -(.) f g x = g (f x) +~~~.markdown +[![Hackage](https://img.shields.io/hackage/v/packagename)](https://hackage.haskell.org/package/packagename) ~~~ -Is this an abomination because you consider it will break -Haskellers habit? Yes. -Does it have something to do with clarity? Yes. -Is it documentation? No. +#### Stackage -For absolute Haskell beginner using `(f (g (h x)))` -might seems more readable than `f $ g $ h x` or `f . g . h $ x`. -But this is not about documentation. -This is a question of code clarity and readability. +If you didn't declared your package to `stackage`, please do it. +It isn't much work. +Just edit a file to add your package. +And you'll could be able to add another badge: -## Other communities +~~~.markdown +[![packagename on Stackage LTS](http://stackage.org/package/packagename/badge/lts-3)](http://stackage.org/lts/package/packagename) +~~~ -While Haskell is great, some other languages have in my humble opinion -a far better habit concerning documentation. -Documentation shouldn't be felt like a punishment. -On the contrary it is a way of proving by example how your work -is great! +See [Stackage Badges](https://www.fpcomplete.com/blog/2015/10/stackage-badges) +for more informations. -I don't want to dive in the details of the other communities -but I was slightly inspired by: -- [Elm](http://elm-lang.org) → [`guide.elm-lang.org`](http://guide.elm-lang.org) & [`docs`](http://package.elm-lang.org/packages/elm-lang/core/4.0.0) -- [Clojure](http://clojure.org) → [`clojuredocs.org`](http://clojuredocs.org) +## Generated Documentation -There are a lot of thing to say about how the documentation is handled in these communities. -I don't believe I could tell everything I would want to. -But there are some big princples: +So even if you do nothing, haddock should generate some API documentation for you for free. +But it will be far better if you add some manual annotation. -A lot of functions are accompagnied with some code example: +**Functions**: -- [JSON decode](http://package.elm-lang.org/packages/elm-lang/core/4.0.0/Json-Decode) -- [Random list](http://package.elm-lang.org/packages/elm-lang/core/4.0.0/Random#list) +~~~ +{-hi-}-- | My function description{-/hi-} +myFunction :: Type of function +myFunction arg1 {-hi-}-- ^ arg1 description{-/hi-} + arg2 {-hi-}-- ^ arg2 description{-/hi-} + = ... +~~~ -[^1]: **RANT**: Compare this documentation of core to the documentation of the `Prelude` module in `hackage`; [`Prelude`](https://hackage.haskell.org/package/base-4.8.2.0/docs/Prelude.html) +**Data**: -### Clojure +~~~ +data MyData a b + = C1 a b -- ^ doc for constructor C1 + | C2 a b -- ^ doc for constructor C2 + +data MyData a b + = C { a :: TypeA {-hi-}-- ^ field a description{-/hi-} + , b :: TypeB {-hi-}-- ^ field b description{-/hi-} + } +~~~ -In clojure when you create a new project using `lein new my-project` -a directory `doc` is created for you. It contains a file with a link -to this blog post: +**Module**: -- [What to write](https://jacobian.org/writing/what-to-write/) +~~~ +{-| +Module : MyModule +Description: Short description +Copyright : (c) +License : MIT -A great deal is made about *tutorials*. +Here is a longer description of this module. +With some code symbol @MyType@. +And also a block of code: -Because this is generally what most first users of your library will search for. -They just want to pass from zero to something in the minimal amount of time. +@ +data MyData = C Int Int -In Haskell we already have API generated documentation for free. -Hackage and Stackage both do a great job at generating your documentation. +myFunction :: MyData -> Int +@ +-} +~~~ -So now the best students in class in my humble opinion: +**Documentation Structure**: + +~~~ +module MyModule ( + -- * Classes + C(..), + -- * Types + -- ** A data type + T, + -- ** A record + R, + -- * Some functions + f, g + ) where +~~~ + +That will generate headings. -- [`turtle`](https://www.stackage.org/package/turtle) -- [`lens`](https://www.stackage.org/package/lens) -Both library are not only aweseme for different reasons. -Their documentation contains examples, and a tutorial. -You can go deeper if you need to. +## Other Random Ideas -To make them even better. +In Haskell we have great tools like +[`hayoo!`](http://hayoo.fh-wedel.de) +and [`hoogle`](https://www.haskell.org/hoogle/). -1. Use `doctest` that way you will be able to *test* your tutorial and fix it - if your API break or change. You'll be able to check it using travis CI for - example. -2. One advantage of providing a `MyPackage.Tutorial` file is the ability to use `doctest`. +And `hackage` and `stackage` provide also a lot of informations. -## Good Ideas +But generally we lack a lot of Tutorials and Guides. +This post was an attempt to help people making more of them. -- [`clojuredocs.org`](http://clojuredocs.org) +But there are other good ideas to help improve the situation. + +### create a doc with link to best practices + +In clojure when you create a new project using `lein new my-project` +a directory `doc` is created for you. It contains a file with a link +to this blog post: + +- [What to write](https://jacobian.org/writing/what-to-write/) + +### Having a page by function/symbol with comments + +If you try to search for some clojure function on a search engine +there is a big chance the first result will link to: + +- [`clojuredocs.org`](http://clojuredocs.org): try to search for `reduce`, `update-in` or `index` for example For each symbol necessiting a documentation. You don't only have the details and standard documentation. @@ -234,60 +328,30 @@ You'll also get: Clojuredocs is an independant website from the official Clojure website. Most of the time, if you google the function you search -you end up on clojredocs for wich there are many contributions. - -Imagine if we had the same functionalities in hackage/stackage. - -Today a lot of information is lost on IRC or mailing list. -I know you could always find the information in the archives -but, as an end-user, it is always better to have a centralized -source of information. +you end up on [clojuredocs](http://clojuredocs.org) for wich there are many contributions. -Differences with existing: +Currently stackage is closer to these feature than hackage. +Because on stack you have access to the README and also some comments by package. -- hackage has haddock -- stackage has haddock + per package comment +I believe it would be more efficient to have at least a page +by module and why not a page by *symbol* (data, functions, typeclasses...). -I believe he would be more efficient to have at least a page -by module and why not a page by *symbol*. -I mean: +For example, we could provide details about `foldl` for example. +Also as there would be less information to display, it will make the design cleaner. -- for data type definition with all their class instances -- for functions -- for typeclasses - -Why? - -- far less informations per page. -- Let's keep the pages we have. -- But let's just also focus more. - So we could provide details about `foldl` for example. - And make the design cleaner. - As a matter of design, think about the 4 of 5 most - important information someone want to have - as fast as possible and provide them. - The rest should be at the bottom, or very small in - the navigation bar. - -- function: - 1. type - 2. Documentation string - 3. Examples - 4. the version / who really care? - -## How to help - -There are 20k Haskell readers. -If only 1% of them pass 10 minutes adding a bit of -documentation it will certainly change a lot of -things in the percieved documenation quality. - -Not too much work: +To help in documenting today you need to make a PR to some library. +While if we had an equivalent to clojuredocs for Haskell, +adding documentation would simply be a few clicks away: 1. login 2. add/edit some example, comments, see-also section -If you pass only the next 10 minutes in adding a bit of -documentation it will certainly change a lot of things. +There are >23k people on `/r/haskell`. +If only 1% of them would take 10 minutes adding a bit of +documentation it will certainly change a lot of +things in the percieved documentation quality. +---- +So have you any pointer, better idea on how to improve +the situation of Haskell documentation? diff --git a/content/Scratch/fr/blog/Haskell-Tutorials--a-tutorial.md b/content/Scratch/fr/blog/Haskell-Tutorials--a-tutorial.md index fc4f53a..063549b 100644 --- a/content/Scratch/fr/blog/Haskell-Tutorials--a-tutorial.md +++ b/content/Scratch/fr/blog/Haskell-Tutorials--a-tutorial.md @@ -1,24 +1,23 @@ --- kind: article published: 2016-05-06 -image: /content/Scratch/img/blog/Haskell-Tutorials--a-tutorial/main.png +image: /content/Scratch/img/blog/Haskell-Tutorials--a-tutorial/main.jpg title: Haskell Tutorials, a tutorial author: Yann Esposito authoruri: yannesposito.com tags: programming, tutorial, haskell, documentation theme: scientific --- -blogimage("main.png","Main image") +blogimage("main.jpg","Main image")
-%tldr Haskell is awesome! But it is not perfect yet. -We can do a better at documenting our libraries. -This document provide some hints to make it happens. +%tldr My hints on how to make great documentation for Haskell libs. -**Tutorial**: +**Step-by-step tutorial/Guides**: 1. Create a `Tutorial` module containing nothing except documentation. +2. Mention the `Tutorial` module in your `cabal` description 2. Use `doctest` to check your documentation is up to date 3. For more complex real world examples, link to the test source. @@ -37,18 +36,17 @@ Great documentation could make the difference between people using your lib with and people not using your lib at all. Documentation can take many different form. -Here is the preferred order (see [What to write](https://jacobian.org/writing/what-to-write/)): -1. **Tutorials** -- write some prose which friendly take a user by hand and help him +1. **Tutorials/Guides** -- write some prose which friendly take a user by hand and help him 2. **Examples** -- how to use each function 3. **Generated API Documentation** -- haddock -## Tutorials +## Tutorials/Guides -1. Create a new module named Tutorial +1. Create a new module named `Tutorial` (or `Guide.GuideTopic`) 2. Create a link to the tutorial in the cabal description 3. Create a link to the tutorial in your README -4. Here is an example of `Tutorial` +4. Here is an example some `Tutorial` module content: ~~~haskell {-# OPTIONS_GHC -fno-warn-unused-imports #-} @@ -56,8 +54,13 @@ Here is the preferred order (see [What to write](https://jacobian.org/writing/wh Use @my-package@ if you want to ... -} module Data.Duration.Tutorial ( + -- * Introduction -- $introduction + + -- ** Subsection + -- $subsection + ) where import Data.Duration @@ -68,17 +71,35 @@ So here how you use it: >>> humanReadableDuration 1002012.002 "11 days 14 hours 20 min 12s 2ms" + +The function is 'humanReadableDuration' and +the you'll be able to click on it to go +to its definition. + +You can add images: <> +and links: . + +-} + +{- $subsection + +This is a chuck of documentation +not attached to any particular Haskell +declaration with an untested code block: + +> answer = 42 + -} ~~~ To prevent obsolescence of your tutorial, use `doctest`. That way when you'll do a `stack test` or `cabal test` -you'll get errors if the Tutorial examples doesn't work anymore. +you'll get errors if some example doesn't work anymore. ## Examples (doctest) -`doctest` is a great way to provide examples in your code documenation. +`doctest` is a great way to provide examples in your code documentation. These example will then be used as tests. Apparently it comes from Python community. @@ -94,7 +115,7 @@ myFunction = (+) ~~~ And to make it works simply verify you have a `test` bloc in your -`.cabal` file and in the main simply use +`.cabal` file and in `test/Main.hs` simply use ~~~haskell module Main where @@ -106,121 +127,194 @@ main = docTest [ "src/MyModule/MyFile.hs" ] ~~~ -## Generated +Now `stack test` or `cabal test` will check the validity of your documentation. -So even if you do nothing, haddock should generate some API documentation for you for free. -But it will be far better if you help haddock. +## Bonuses + +### Verifying documentation coverage + +1. Install haddock `stack install haddock` or `cabal install haddock` +2. Launch haddock without output format: ~~~ --- | My function description -myFunction :: Type of function -myFunction arg1 -- ^ arg1 description - arg2 -- ^ arg2 description - = ... +> haddock src/**/*.hs +Haddock coverage: + 100% ( 15 / 15) in 'Data.Duration' + 100% ( 3 / 3) in 'Data.Duration.Tutorial' ~~~ -and for data +### Continuous Integration + +There are plenty of alternative solution. +I provide the one I believe would be used by most people. +So if you use `github` simply create an account on [`travis`](http://travis-ci.org). +Add a `.travis.yml` file in your repo containing: + +~~~.yaml +language: haskell ~~~ -data MyData = X Int -instance Function MyData where - ... +If you want to use `stack` instead of just `cabal`: + +~~~.yaml +sudo: false + +addons: + apt: + packages: + - libgmp-dev + +# Caching so the next build will be fast too. +cache: + directories: + - $HOME/.stack + +before_install: +# Download and unpack the stack executable +- mkdir -p ~/.local/bin +- export PATH=$HOME/.local/bin:$PATH +- travis_retry curl -L https://www.stackage.org/stack/linux-x86_64 | tar xz --wildcards --strip-components=1 -C ~/.local/bin '*/stack' + +script: + - stack setup && stack --no-terminal --skip-ghc-check test ~~~ -Also, please launch haddock manually to see which symbols lack documentation. +Don't forget to activate your repo in travis. + +For some bonus points add the build status badge in your `README.md` file: + +~~~.markdown +[![Build Status](https://travis-ci.org/user-name/project-name.svg?branch=master)](https://travis-ci.org/user-name/project-name) +~~~ -## Prelude +Congratulation! +Now if you break your documentation examples, you'll get prompted. -> Who are you who are so wise in the way of science? +### Badges -So I am myself largely subject to criticism. -This article isn't intented to be a bible. -More like a tour of what I feel is the most appreciated way to consume documentation. -So please, no arsh feeling. +You could add badges to your `README.md` file. -I wouldn't want this article to be used as a pretext to -start an Holy War about the different Haskell coding style. +Here is a list of some: [`shields.io`](http://shields.io) -For example, I don't see anything wrong relative to the documentation of using +#### Hackage -~~~ haskell -import Prelude hiding ((.)) -(.) f g x = g (f x) +~~~.markdown +[![Hackage](https://img.shields.io/hackage/v/packagename)](https://hackage.haskell.org/package/packagename) ~~~ -Is this an abomination because you consider it will break -Haskellers habit? Yes. -Does it have something to do with clarity? Yes. -Is it documentation? No. +#### Stackage -For absolute Haskell beginner using `(f (g (h x)))` -might seems more readable than `f $ g $ h x` or `f . g . h $ x`. -But this is not about documentation. -This is a question of code clarity and readability. +If you didn't declared your package to `stackage`, please do it. +It isn't much work. +Just edit a file to add your package. +And you'll could be able to add another badge: -## Other communities +~~~.markdown +[![packagename on Stackage LTS](http://stackage.org/package/packagename/badge/lts-3)](http://stackage.org/lts/package/packagename) +~~~ -While Haskell is great, some other languages have in my humble opinion -a far better habit concerning documentation. -Documentation shouldn't be felt like a punishment. -On the contrary it is a way of proving by example how your work -is great! +See [Stackage Badges](https://www.fpcomplete.com/blog/2015/10/stackage-badges) +for more informations. -I don't want to dive in the details of the other communities -but I was slightly inspired by: -- [Elm](http://elm-lang.org) → [`guide.elm-lang.org`](http://guide.elm-lang.org) & [`docs`](http://package.elm-lang.org/packages/elm-lang/core/4.0.0) -- [Clojure](http://clojure.org) → [`clojuredocs.org`](http://clojuredocs.org) +## Generated Documentation -There are a lot of thing to say about how the documentation is handled in these communities. -I don't believe I could tell everything I would want to. -But there are some big princples: +So even if you do nothing, haddock should generate some API documentation for you for free. +But it will be far better if you add some manual annotation. -A lot of functions are accompagnied with some code example: +**Functions**: -- [JSON decode](http://package.elm-lang.org/packages/elm-lang/core/4.0.0/Json-Decode) -- [Random list](http://package.elm-lang.org/packages/elm-lang/core/4.0.0/Random#list) +~~~ +{-hi-}-- | My function description{-/hi-} +myFunction :: Type of function +myFunction arg1 {-hi-}-- ^ arg1 description{-/hi-} + arg2 {-hi-}-- ^ arg2 description{-/hi-} + = ... +~~~ -[^1]: **RANT**: Compare this documentation of core to the documentation of the `Prelude` module in `hackage`; [`Prelude`](https://hackage.haskell.org/package/base-4.8.2.0/docs/Prelude.html) +**Data**: -### Clojure +~~~ +data MyData a b + = C1 a b -- ^ doc for constructor C1 + | C2 a b -- ^ doc for constructor C2 + +data MyData a b + = C { a :: TypeA {-hi-}-- ^ field a description{-/hi-} + , b :: TypeB {-hi-}-- ^ field b description{-/hi-} + } +~~~ -In clojure when you create a new project using `lein new my-project` -a directory `doc` is created for you. It contains a file with a link -to this blog post: +**Module**: -- [What to write](https://jacobian.org/writing/what-to-write/) +~~~ +{-| +Module : MyModule +Description: Short description +Copyright : (c) +License : MIT -A great deal is made about *tutorials*. +Here is a longer description of this module. +With some code symbol @MyType@. +And also a block of code: -Because this is generally what most first users of your library will search for. -They just want to pass from zero to something in the minimal amount of time. +@ +data MyData = C Int Int -In Haskell we already have API generated documentation for free. -Hackage and Stackage both do a great job at generating your documentation. +myFunction :: MyData -> Int +@ +-} +~~~ -So now the best students in class in my humble opinion: +**Documentation Structure**: + +~~~ +module MyModule ( + -- * Classes + C(..), + -- * Types + -- ** A data type + T, + -- ** A record + R, + -- * Some functions + f, g + ) where +~~~ + +That will generate headings. -- [`turtle`](https://www.stackage.org/package/turtle) -- [`lens`](https://www.stackage.org/package/lens) -Both library are not only aweseme for different reasons. -Their documentation contains examples, and a tutorial. -You can go deeper if you need to. +## Other Random Ideas -To make them even better. +In Haskell we have great tools like +[`hayoo!`](http://hayoo.fh-wedel.de) +and [`hoogle`](https://www.haskell.org/hoogle/). -1. Use `doctest` that way you will be able to *test* your tutorial and fix it - if your API break or change. You'll be able to check it using travis CI for - example. -2. One advantage of providing a `MyPackage.Tutorial` file is the ability to use `doctest`. +And `hackage` and `stackage` provide also a lot of informations. -## Good Ideas +But generally we lack a lot of Tutorials and Guides. +This post was an attempt to help people making more of them. -- [`clojuredocs.org`](http://clojuredocs.org) +But there are other good ideas to help improve the situation. + +### create a doc with link to best practices + +In clojure when you create a new project using `lein new my-project` +a directory `doc` is created for you. It contains a file with a link +to this blog post: + +- [What to write](https://jacobian.org/writing/what-to-write/) + +### Having a page by function/symbol with comments + +If you try to search for some clojure function on a search engine +there is a big chance the first result will link to: + +- [`clojuredocs.org`](http://clojuredocs.org): try to search for `reduce`, `update-in` or `index` for example For each symbol necessiting a documentation. You don't only have the details and standard documentation. @@ -234,60 +328,30 @@ You'll also get: Clojuredocs is an independant website from the official Clojure website. Most of the time, if you google the function you search -you end up on clojredocs for wich there are many contributions. - -Imagine if we had the same functionalities in hackage/stackage. - -Today a lot of information is lost on IRC or mailing list. -I know you could always find the information in the archives -but, as an end-user, it is always better to have a centralized -source of information. +you end up on [clojuredocs](http://clojuredocs.org) for wich there are many contributions. -Differences with existing: +Currently stackage is closer to these feature than hackage. +Because on stack you have access to the README and also some comments by package. -- hackage has haddock -- stackage has haddock + per package comment +I believe it would be more efficient to have at least a page +by module and why not a page by *symbol* (data, functions, typeclasses...). -I believe he would be more efficient to have at least a page -by module and why not a page by *symbol*. -I mean: +For example, we could provide details about `foldl` for example. +Also as there would be less information to display, it will make the design cleaner. -- for data type definition with all their class instances -- for functions -- for typeclasses - -Why? - -- far less informations per page. -- Let's keep the pages we have. -- But let's just also focus more. - So we could provide details about `foldl` for example. - And make the design cleaner. - As a matter of design, think about the 4 of 5 most - important information someone want to have - as fast as possible and provide them. - The rest should be at the bottom, or very small in - the navigation bar. - -- function: - 1. type - 2. Documentation string - 3. Examples - 4. the version / who really care? - -## How to help - -There are 20k Haskell readers. -If only 1% of them pass 10 minutes adding a bit of -documentation it will certainly change a lot of -things in the percieved documenation quality. - -Not too much work: +To help in documenting today you need to make a PR to some library. +While if we had an equivalent to clojuredocs for Haskell, +adding documentation would simply be a few clicks away: 1. login 2. add/edit some example, comments, see-also section -If you pass only the next 10 minutes in adding a bit of -documentation it will certainly change a lot of things. +There are >23k people on `/r/haskell`. +If only 1% of them would take 10 minutes adding a bit of +documentation it will certainly change a lot of +things in the percieved documentation quality. +---- +So have you any pointer, better idea on how to improve +the situation of Haskell documentation? diff --git a/content/Scratch/img/blog/Haskell-Tutorials--a-tutorial/main.jpg b/content/Scratch/img/blog/Haskell-Tutorials--a-tutorial/main.jpg new file mode 100644 index 0000000..1497530 Binary files /dev/null and b/content/Scratch/img/blog/Haskell-Tutorials--a-tutorial/main.jpg differ diff --git a/content/Scratch/img/blog/Haskell-Tutorials--a-tutorial/main.jpg.old b/content/Scratch/img/blog/Haskell-Tutorials--a-tutorial/main.jpg.old new file mode 100644 index 0000000..0bea632 Binary files /dev/null and b/content/Scratch/img/blog/Haskell-Tutorials--a-tutorial/main.jpg.old differ diff --git a/multi/blog/Haskell-Tutorials--a-tutorial.md b/multi/blog/Haskell-Tutorials--a-tutorial.md index 5c0a2d2..063549b 100644 --- a/multi/blog/Haskell-Tutorials--a-tutorial.md +++ b/multi/blog/Haskell-Tutorials--a-tutorial.md @@ -1,24 +1,23 @@ --- kind: article published: 2016-05-06 -image: /content/Scratch/img/blog/Haskell-Tutorials--a-tutorial/main.png +image: /content/Scratch/img/blog/Haskell-Tutorials--a-tutorial/main.jpg title: Haskell Tutorials, a tutorial author: Yann Esposito authoruri: yannesposito.com tags: programming, tutorial, haskell, documentation theme: scientific --- -blogimage("main.png","Main image") +blogimage("main.jpg","Main image")
-%tldr Haskell is awesome! But it is not perfect yet. -We can do a better at documenting our libraries. -This document provide some hints to make it happens. +%tldr My hints on how to make great documentation for Haskell libs. -**Tutorial**: +**Step-by-step tutorial/Guides**: 1. Create a `Tutorial` module containing nothing except documentation. +2. Mention the `Tutorial` module in your `cabal` description 2. Use `doctest` to check your documentation is up to date 3. For more complex real world examples, link to the test source. @@ -37,18 +36,17 @@ Great documentation could make the difference between people using your lib with and people not using your lib at all. Documentation can take many different form. -Here is the preferred order (see [What to write](https://jacobian.org/writing/what-to-write/)): -1. **Tutorials** -- write some prose which friendly take a user by hand and help him +1. **Tutorials/Guides** -- write some prose which friendly take a user by hand and help him 2. **Examples** -- how to use each function 3. **Generated API Documentation** -- haddock -## Tutorials +## Tutorials/Guides -1. Create a new module named Tutorial +1. Create a new module named `Tutorial` (or `Guide.GuideTopic`) 2. Create a link to the tutorial in the cabal description 3. Create a link to the tutorial in your README -4. Here is an example of `Tutorial` +4. Here is an example some `Tutorial` module content: ~~~haskell {-# OPTIONS_GHC -fno-warn-unused-imports #-} @@ -56,8 +54,13 @@ Here is the preferred order (see [What to write](https://jacobian.org/writing/wh Use @my-package@ if you want to ... -} module Data.Duration.Tutorial ( + -- * Introduction -- $introduction + + -- ** Subsection + -- $subsection + ) where import Data.Duration @@ -68,17 +71,35 @@ So here how you use it: >>> humanReadableDuration 1002012.002 "11 days 14 hours 20 min 12s 2ms" + +The function is 'humanReadableDuration' and +the you'll be able to click on it to go +to its definition. + +You can add images: <> +and links: . + +-} + +{- $subsection + +This is a chuck of documentation +not attached to any particular Haskell +declaration with an untested code block: + +> answer = 42 + -} ~~~ To prevent obsolescence of your tutorial, use `doctest`. That way when you'll do a `stack test` or `cabal test` -you'll get errors if the Tutorial examples doesn't work anymore. +you'll get errors if some example doesn't work anymore. ## Examples (doctest) -`doctest` is a great way to provide examples in your code documenation. +`doctest` is a great way to provide examples in your code documentation. These example will then be used as tests. Apparently it comes from Python community. @@ -94,7 +115,7 @@ myFunction = (+) ~~~ And to make it works simply verify you have a `test` bloc in your -`.cabal` file and in the main simply use +`.cabal` file and in `test/Main.hs` simply use ~~~haskell module Main where @@ -106,10 +127,23 @@ main = docTest [ "src/MyModule/MyFile.hs" ] ~~~ -And now to check the validity of your documentation -you simply need to run `stack test` or `cabal test`. +Now `stack test` or `cabal test` will check the validity of your documentation. + +## Bonuses + +### Verifying documentation coverage + +1. Install haddock `stack install haddock` or `cabal install haddock` +2. Launch haddock without output format: + +~~~ +> haddock src/**/*.hs +Haddock coverage: + 100% ( 15 / 15) in 'Data.Duration' + 100% ( 3 / 3) in 'Data.Duration.Tutorial' +~~~ -### CI +### Continuous Integration There are plenty of alternative solution. I provide the one I believe would be used by most people. @@ -159,6 +193,18 @@ Now if you break your documentation examples, you'll get prompted. ### Badges +You could add badges to your `README.md` file. + +Here is a list of some: [`shields.io`](http://shields.io) + +#### Hackage + +~~~.markdown +[![Hackage](https://img.shields.io/hackage/v/packagename)](https://hackage.haskell.org/package/packagename) +~~~ + +#### Stackage + If you didn't declared your package to `stackage`, please do it. It isn't much work. Just edit a file to add your package. @@ -168,87 +214,94 @@ And you'll could be able to add another badge: [![packagename on Stackage LTS](http://stackage.org/package/packagename/badge/lts-3)](http://stackage.org/lts/package/packagename) ~~~ +See [Stackage Badges](https://www.fpcomplete.com/blog/2015/10/stackage-badges) +for more informations. -## Generated + +## Generated Documentation So even if you do nothing, haddock should generate some API documentation for you for free. -But it will be far better if you help haddock. +But it will be far better if you add some manual annotation. + +**Functions**: ~~~ --- | My function description +{-hi-}-- | My function description{-/hi-} myFunction :: Type of function -myFunction arg1 -- ^ arg1 description - arg2 -- ^ arg2 description +myFunction arg1 {-hi-}-- ^ arg1 description{-/hi-} + arg2 {-hi-}-- ^ arg2 description{-/hi-} = ... ~~~ -and for data -~~~ -data MyData = X Int +**Data**: -instance Function MyData where - ... +~~~ +data MyData a b + = C1 a b -- ^ doc for constructor C1 + | C2 a b -- ^ doc for constructor C2 + +data MyData a b + = C { a :: TypeA {-hi-}-- ^ field a description{-/hi-} + , b :: TypeB {-hi-}-- ^ field b description{-/hi-} + } ~~~ -Also, please launch haddock manually to see which symbols lack documentation. - -## Prelude +**Module**: -> Who are you who are so wise in the way of science? +~~~ +{-| +Module : MyModule +Description: Short description +Copyright : (c) +License : MIT -So I am myself largely subject to criticism. -This article isn't intented to be a bible. -More like a tour of what I feel is the most appreciated way to consume documentation. -So please, no arsh feeling. +Here is a longer description of this module. +With some code symbol @MyType@. +And also a block of code: -I wouldn't want this article to be used as a pretext to -start an Holy War about the different Haskell coding style. +@ +data MyData = C Int Int -For example, I don't see anything wrong relative to the documentation of using +myFunction :: MyData -> Int +@ -~~~ haskell -import Prelude hiding ((.)) -(.) f g x = g (f x) +-} ~~~ -Is this an abomination because you consider it will break -Haskellers habit? Yes. -Does it have something to do with clarity? Yes. -Is it documentation? No. +**Documentation Structure**: -For absolute Haskell beginner using `(f (g (h x)))` -might seems more readable than `f $ g $ h x` or `f . g . h $ x`. -But this is not about documentation. -This is a question of code clarity and readability. - -## Other communities - -While Haskell is great, some other languages have in my humble opinion -a far better habit concerning documentation. -Documentation shouldn't be felt like a punishment. -On the contrary it is a way of proving by example how your work -is great! +~~~ +module MyModule ( + -- * Classes + C(..), + -- * Types + -- ** A data type + T, + -- ** A record + R, + -- * Some functions + f, g + ) where +~~~ -I don't want to dive in the details of the other communities -but I was slightly inspired by: +That will generate headings. -- [Elm](http://elm-lang.org) → [`guide.elm-lang.org`](http://guide.elm-lang.org) & [`docs`](http://package.elm-lang.org/packages/elm-lang/core/4.0.0) -- [Clojure](http://clojure.org) → [`clojuredocs.org`](http://clojuredocs.org) -There are a lot of thing to say about how the documentation is handled in these communities. -I don't believe I could tell everything I would want to. -But there are some big princples: +## Other Random Ideas -A lot of functions are accompagnied with some code example: +In Haskell we have great tools like +[`hayoo!`](http://hayoo.fh-wedel.de) +and [`hoogle`](https://www.haskell.org/hoogle/). -- [JSON decode](http://package.elm-lang.org/packages/elm-lang/core/4.0.0/Json-Decode) -- [Random list](http://package.elm-lang.org/packages/elm-lang/core/4.0.0/Random#list) +And `hackage` and `stackage` provide also a lot of informations. +But generally we lack a lot of Tutorials and Guides. +This post was an attempt to help people making more of them. -[^1]: **RANT**: Compare this documentation of core to the documentation of the `Prelude` module in `hackage`; [`Prelude`](https://hackage.haskell.org/package/base-4.8.2.0/docs/Prelude.html) +But there are other good ideas to help improve the situation. -### Clojure +### create a doc with link to best practices In clojure when you create a new project using `lein new my-project` a directory `doc` is created for you. It contains a file with a link @@ -256,34 +309,12 @@ to this blog post: - [What to write](https://jacobian.org/writing/what-to-write/) -A great deal is made about *tutorials*. - -Because this is generally what most first users of your library will search for. -They just want to pass from zero to something in the minimal amount of time. - -In Haskell we already have API generated documentation for free. -Hackage and Stackage both do a great job at generating your documentation. - - -So now the best students in class in my humble opinion: - -- [`turtle`](https://www.stackage.org/package/turtle) -- [`lens`](https://www.stackage.org/package/lens) +### Having a page by function/symbol with comments -Both library are not only aweseme for different reasons. -Their documentation contains examples, and a tutorial. -You can go deeper if you need to. +If you try to search for some clojure function on a search engine +there is a big chance the first result will link to: -To make them even better. - -1. Use `doctest` that way you will be able to *test* your tutorial and fix it - if your API break or change. You'll be able to check it using travis CI for - example. -2. One advantage of providing a `MyPackage.Tutorial` file is the ability to use `doctest`. - -## Good Ideas - -- [`clojuredocs.org`](http://clojuredocs.org) +- [`clojuredocs.org`](http://clojuredocs.org): try to search for `reduce`, `update-in` or `index` for example For each symbol necessiting a documentation. You don't only have the details and standard documentation. @@ -297,60 +328,30 @@ You'll also get: Clojuredocs is an independant website from the official Clojure website. Most of the time, if you google the function you search -you end up on clojredocs for wich there are many contributions. - -Imagine if we had the same functionalities in hackage/stackage. - -Today a lot of information is lost on IRC or mailing list. -I know you could always find the information in the archives -but, as an end-user, it is always better to have a centralized -source of information. - -Differences with existing: - -- hackage has haddock -- stackage has haddock + per package comment +you end up on [clojuredocs](http://clojuredocs.org) for wich there are many contributions. -I believe he would be more efficient to have at least a page -by module and why not a page by *symbol*. -I mean: +Currently stackage is closer to these feature than hackage. +Because on stack you have access to the README and also some comments by package. -- for data type definition with all their class instances -- for functions -- for typeclasses +I believe it would be more efficient to have at least a page +by module and why not a page by *symbol* (data, functions, typeclasses...). -Why? +For example, we could provide details about `foldl` for example. +Also as there would be less information to display, it will make the design cleaner. -- far less informations per page. -- Let's keep the pages we have. -- But let's just also focus more. - So we could provide details about `foldl` for example. - And make the design cleaner. - As a matter of design, think about the 4 of 5 most - important information someone want to have - as fast as possible and provide them. - The rest should be at the bottom, or very small in - the navigation bar. - -- function: - 1. type - 2. Documentation string - 3. Examples - 4. the version / who really care? - -## How to help - -There are 20k Haskell readers. -If only 1% of them pass 10 minutes adding a bit of -documentation it will certainly change a lot of -things in the percieved documenation quality. - -Not too much work: +To help in documenting today you need to make a PR to some library. +While if we had an equivalent to clojuredocs for Haskell, +adding documentation would simply be a few clicks away: 1. login 2. add/edit some example, comments, see-also section -If you pass only the next 10 minutes in adding a bit of -documentation it will certainly change a lot of things. +There are >23k people on `/r/haskell`. +If only 1% of them would take 10 minutes adding a bit of +documentation it will certainly change a lot of +things in the percieved documentation quality. +---- +So have you any pointer, better idea on how to improve +the situation of Haskell documentation? diff --git a/tools/auto-update b/tools/auto-update index 0629314..fcefb79 100755 --- a/tools/auto-update +++ b/tools/auto-update @@ -1,16 +1,21 @@ #!/usr/bin/env zsh +error(){print -- $* >&2; exit 1} curdir=$PWD -[[ -e .last_multi_watched ]] && { - "Kill old processes" - kill $(<.last_multi_watched) -} +checkfile=".last_multi_watched" cd $curdir ONCE=0 for functionality in $@; do case $functionality in + -h|--help|help) + print -- "Usage: ${0:t} [command ...]" + print -- "where command can be:" + print -- "css\tWatch and update sass files" + print -- "once\tOnly build once" + exit 0 + ;; css) # sass sass -I . --watch Scratch/css:_site/Scratch/css & sasspid=$! @@ -19,10 +24,6 @@ for functionality in $@; do esac done -checkfile=".last_multi_watched" - -error(){print -- $* >&2; exit 1} - ((ONCE == 0)) && \ [[ -e $checkfile ]] && \ { @@ -32,11 +33,10 @@ case $(uname) in Linux) checkfilemodifiedtime=$(stat --printf %Y $checkfile);; *) checkfilemodifiedtime=$(stat --printf %Y $checkfile);; esac -(( $currenttime - $checkfilemodifiedtime < 5)) && error "watching in progress (wait at least 5 seconds if you killed it)" +(( $currenttime - $checkfilemodifiedtime < 5)) && \ + error "watching in progress (wait at least 5 seconds if you killed it)" } -echo $serverpid $sasspid > .last_multi_watched - cd content stack exec yblog watch &