From 3ee5aca85b60152a8e75ad66ce0781f77a6fe3ee Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 1 Mar 2019 11:07:38 -0800 Subject: [PATCH 001/133] Make Context/Narrative its own folder with ReadMe file --- 02-Context-or-Narrative.md => 02-Context-or-Narrative/ReadMe.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename 02-Context-or-Narrative.md => 02-Context-or-Narrative/ReadMe.md (100%) diff --git a/02-Context-or-Narrative.md b/02-Context-or-Narrative/ReadMe.md similarity index 100% rename from 02-Context-or-Narrative.md rename to 02-Context-or-Narrative/ReadMe.md From 3f8dee84f77264b00d53b4c929d496e93bef29c8 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 1 Mar 2019 14:39:38 -0800 Subject: [PATCH 002/133] Define file outline and make initial go at defining 'good documentation' --- .../State-of-PureScript-Documentation-2019.md | 139 ++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md new file mode 100644 index 0000000..b269ae9 --- /dev/null +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -0,0 +1,139 @@ +# State of PureScript Documentation: 2019 + +## Why Read This Document? + +This document is not meant to convince you to use PureScript. We assume that readers already believe in using PureScript instead of alternatives. + +It is well-known among the PureScript community that its documentation is lacking in some critical areas. As a result, @chexxor started the [PureScript documentation efforts in 2019](https://discourse.purescript.org/t/purescript-documentation-efforts-in-2019/524) discourse thread to answer one question: +> How can we improve the PureScript documentation in 2019? + +(Purpose) The following document tries to do two things: +1. Provide an answer to @chexxor's above question +2. Answer other related questions that various audiences will have: + - new learners (regardless of language background) + - PureScript documentation writers + - Core Contributors + +Outline +- Explain what is "good" documentation to define a criteria +- Evaluate PureScript's documentation using that criteria +- Explain why PureScript's documentation is lacking and what is being done to improve it +- Address various audience's possible concerns or questions centered on these themes: + - New learners - How should I learn PureScript? + - PureScript documentation writers - How should I write good maintainable documentation for others? + - Core Contributors - + +## What is "Good" Documentation Anyway? + +Did someone ever teach you how to write "good" documentation? No, you likely just wrote what came to mind and hoped it was good enough. + +So, it helps to understand what is "good" documentation and why. + +Essentially, there are 3 dimensions for documentation. +1. The type of documentation +2. The intended audience +3. How up-to-date the documentation is + +### The Types of Documentation + +First, there are 5 types of documentation that target specific phases of a learner's experience (as explained in [What Nobody Tells You About Documentation](https://www.divio.com/blog/documentation/) and [Teach, Don't Tell](http://stevelosh.com/blog/2013/09/teach-dont-tell/)) + +| Type | Analogy | Characteristics +| -- | -- | -- | +| The Hook | Selling a product to a potential customer | +| Getting Started | Teaching a child how to cook | +| How-To Guides | Following a cook book's recipe | +| Explanation | Listening to a CEO answer questions about his company | +| Reference | Reading an encyclopedia | + +Moreover, there are clear examples of "bad" documentation (as explained in [Teach, Don't Tell](http://stevelosh.com/blog/2013/09/teach-dont-tell/)): + +| Statement | Why it's bad | +| -- | -- | +| Read the Source Code | Only useful once you are already familiar with it +| Read the Test Code | While it uses the code, it tends to focus on edge cases, not normal cases, and may not use all possible options/configurations. +| Read the API docs | One must know the name of the function/value to be able to read its documentation. Most won't know the name until you teach it to them. Likewise, people don't learn by reading alphabetized lists of disconnected information +| Read the Wiki | Content is usually not written by the code's authors, but by multiple 3rd-party people. There are often multiple disconnected voices throughout the material. It's like asking a student to write his own lesson plan. + +### The Documentation's Intended Audience + +Second, the number of intended audiences can vary greatly. For example, here are different ways of categorizing them: +- The language/paradigms they primarily use and think in (e.g. JavaScript, Ruby, Haskell; lazy, strict; OO, FP; etc.) +- The amount of experience they have (e.g. never coded before, junior, senior, etc.) +- The programs they are looking to create (e.g. games, financial applications, cryptography, etc.) + +Writing documentation that targets JavaScript-background junior developers who want to write games will focus on some things, exclude others, and order its content in a way that makes most sense to that purpose. + +As a result, others who read the resulting documentation will consider it "poor" in some aspect: +- If one comes from a non-JavaScript language, one might find references to features in JavaScript confusing: "They used the concept of 'prototypes' to explain something, but that left me even more confused..." ~ a Java developer +- If one comes from a different experience level, one might have unanswered questions: "They didn't even mention what the performance trade-offs for specific libraries were..." ~ a senior developer +- If one has a different goal in mind, some crucial libraries might never be covered: "They didn't explain how I can make my Bitcoin client cryptographically secure..." + +### The Documentation's Accuracy + +Third, documentation becomes inaccurate in two ways when breaking changes occur: usefulness (depends on 'size' of breaking change) and coherence (depends on 'frequency' of breaking change). + +When **large** breaking changes occur, documentation can immediately become useless because: +- none of its examples work anymore +- old terms might mean something different now +- the order of explanations should appear in a different way now +- some explanations are no longer relevant + +When breaking changes occur **frequently**, documentation can appear more like loosely-coupled snippets of ideas rather than a coherent explanation + +In short, it is impossible to write "good" documentation for everyone that is up-to-date all the time. There's simply not enough manpower, time, and incentives to do that. Rather, it will be "good", "horrible", or "somewhere in-between" for diffent kinds of people and at different times/seasons. + +### The Mediums of Documentation + +Fourth, documentation can appear in a few mediums/formats: + +| Code | Explanation | Example +| -- | -- | -- | +| Syntax-highlighted snippets | Long Essay | Blog Posts +| Intermixed | Intermixed | Literate Programming +| Actual code | Comments | Working Examples +| Actual code | Slides / Explanation | Walking through someone in a video + +### Criteria for "Good" Documentation + +Still, we can define our criteria for "good" documentation using these four dimensions: +- [Type] + - It defines which type of documentation it is + - If a Hook, then + - If a Getting Started, then + - If a How-To Guide, then + - If a Reference, then + - If a Explanation, then +- [Audience] + - It states who the intended audience is +- [Accuracy] + - It explains which version of the code it documents + - If it's not the most recent version, it explains: + - Where it is outdated + - How to understand the outdated explanation in light of the new changes + - It includes the date it was published and last updated + +A few different audiences +- shared (things we should explain, no matter who reads this) + - Why read this document (capture people's attention in less than 2 paragraphs) + - What is good documentation for new learners? (defining our terminology and criteria) + - How does PureScript fair in that regard? (use that criteria to judge PS' current documentation) + - Why isn't it better? (explain the obstacles that prevent it from being better) +- new learners (address things new learners care about) + - What should your expectations be when learning? (frustration arises when expectations are broken) + - How are people currently trying to improve it? (explain current efforts that people can tag alongside of / help / give feedback on) + - How can you help in this effort? (you are most motivated, so you'll drive the effort or help out in some situations) +- Documentation writers (address things they care about) + - How do I write good documentation for new learners? + - How do I write documentation that does not go out-of-date quickly? + - How do I write maintainable documentation? + - How should I bring awareness to my documentation efforts? +- PS core contributors (things they care about) + - What processes could be automated to save you time / lower the maintenance cost? + - Questions whose answers would be helpful for others to know + - What 'qualifications', if any, would they prefer someone has before delegating a project to them? + +Here's a quick overview of some of its benefits compared to other languages: +- PureScript provides certain guarantees by default that other web languages do not or cannot (e.g. JavaScript, TypeScript) +- PureScript is more powerful than similar alternatives (i.e. Elm) +- PureScript can be used to 'patch' existing code, enabling one to slowly migrate a large application to PureScript one component at a time (unlike Haskell's GHCJS). From 9947e0efa2cdf9792e86b7903bb9116ec11b168e Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 1 Mar 2019 17:16:11 -0800 Subject: [PATCH 003/133] Update number of dimensions to 4 and reword it as 'factors' --- .../State-of-PureScript-Documentation-2019.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index b269ae9..2c841b4 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -29,10 +29,11 @@ Did someone ever teach you how to write "good" documentation? No, you likely jus So, it helps to understand what is "good" documentation and why. -Essentially, there are 3 dimensions for documentation. +Essentially, there are 4 factors that affect whether documentation is "good" or not. 1. The type of documentation 2. The intended audience 3. How up-to-date the documentation is +4. The medium in which the documentation appears ### The Types of Documentation @@ -96,7 +97,7 @@ Fourth, documentation can appear in a few mediums/formats: ### Criteria for "Good" Documentation -Still, we can define our criteria for "good" documentation using these four dimensions: +Still, we can define our criteria for "good" documentation using these four factors: - [Type] - It defines which type of documentation it is - If a Hook, then From 8a645e881578d7e3b5edf5622087b1fcb6e00b03 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 1 Mar 2019 17:17:03 -0800 Subject: [PATCH 004/133] Fix rendering of sentence --- .../State-of-PureScript-Documentation-2019.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 2c841b4..8ff7de9 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -15,7 +15,7 @@ It is well-known among the PureScript community that its documentation is lackin - Core Contributors Outline -- Explain what is "good" documentation to define a criteria +- Explain what "good" documentation is and define a criteria - Evaluate PureScript's documentation using that criteria - Explain why PureScript's documentation is lacking and what is being done to improve it - Address various audience's possible concerns or questions centered on these themes: From d4068159eb69622bfa2cccfc112f00ed0003a6e9 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 1 Mar 2019 17:28:50 -0800 Subject: [PATCH 005/133] Improve 'large' and 'frequent' breaking changes explanation --- .../State-of-PureScript-Documentation-2019.md | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 8ff7de9..32ae807 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -72,15 +72,24 @@ As a result, others who read the resulting documentation will consider it "poor" ### The Documentation's Accuracy -Third, documentation becomes inaccurate in two ways when breaking changes occur: usefulness (depends on 'size' of breaking change) and coherence (depends on 'frequency' of breaking change). +Third, breaking changes makes documentation inaccurate. It does this in two ways: decreasing its usefulness (depends on the 'size' of a breaking change) and decreasing its coherence (depends on the 'frequency' of breaking changes). When **large** breaking changes occur, documentation can immediately become useless because: -- none of its examples work anymore +- none of its code examples work anymore - old terms might mean something different now -- the order of explanations should appear in a different way now -- some explanations are no longer relevant +- lessons/guides/explanations might need to be reordered +- some parts of the documentation might no longer be relevant +- some new parts may need be written -When breaking changes occur **frequently**, documentation can appear more like loosely-coupled snippets of ideas rather than a coherent explanation +Updating documentation in light of "large" breaking changes often requires the most work. + +When breaking changes occur **frequently**, documentation can appear more like loosely-coupled snippets of ideas rather than a coherent explanation because: +- Article A depends on Article B to explain something. Then, Aritcle B becomes outdated. Thus, one "patches" Article A with a quick overview that doesn't fit in with the rest of its content. +- One updates 3 out of 10 articles. One article says `X is true` whereas another says `X is false`. A new learner isn't sure which is correct. + +Updating documentation in light of "frequent" breaking changes often requires less overall work, but is difficult to update unless one is already very familiar with the documentation. + +When **large** breaking changes occur **frequently**, it discourages people from updating the documentation. Why waste time on something that will become outdated soon? In short, it is impossible to write "good" documentation for everyone that is up-to-date all the time. There's simply not enough manpower, time, and incentives to do that. Rather, it will be "good", "horrible", or "somewhere in-between" for diffent kinds of people and at different times/seasons. From cc7ce998c0b7d5c89978f7980b25af4b24f0697e Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 1 Mar 2019 17:42:18 -0800 Subject: [PATCH 006/133] Clean up Mediums of Documentation section --- .../State-of-PureScript-Documentation-2019.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 32ae807..b85f60d 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -97,12 +97,14 @@ In short, it is impossible to write "good" documentation for everyone that is up Fourth, documentation can appear in a few mediums/formats: -| Code | Explanation | Example +| Medium | Type of Code Used | How things are explained | | -- | -- | -- | -| Syntax-highlighted snippets | Long Essay | Blog Posts -| Intermixed | Intermixed | Literate Programming -| Actual code | Comments | Working Examples -| Actual code | Slides / Explanation | Walking through someone in a video +| Blog Posts | Syntax-highlighted snippets | Long essay (and images sometimes) +| Literate Programming | Code intermixed with short explanations | Code intermixed with short explanations +| Commented Code Examples | Full runnable code | Comments +| Walking someone through a video | Actual code | Slides / Long Essay / Quiz + +Many people stated that "heavily-commented code examples" often provide the best form of documentation. They follow the principle of "show, don't tell." People can use them as a model and experiment on them. Each of the above mediums has their place, but the code examples might produce the best documentation in the shortest time possible. ### Criteria for "Good" Documentation From c30cb59027bd5bc162cf93318fc78881a7381334 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 1 Mar 2019 17:43:01 -0800 Subject: [PATCH 007/133] Move conclusion down into proper section --- .../State-of-PureScript-Documentation-2019.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index b85f60d..0df2ef4 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -91,8 +91,6 @@ Updating documentation in light of "frequent" breaking changes often requires le When **large** breaking changes occur **frequently**, it discourages people from updating the documentation. Why waste time on something that will become outdated soon? -In short, it is impossible to write "good" documentation for everyone that is up-to-date all the time. There's simply not enough manpower, time, and incentives to do that. Rather, it will be "good", "horrible", or "somewhere in-between" for diffent kinds of people and at different times/seasons. - ### The Mediums of Documentation Fourth, documentation can appear in a few mediums/formats: @@ -108,6 +106,8 @@ Many people stated that "heavily-commented code examples" often provide the best ### Criteria for "Good" Documentation +In short, it is impossible to write "good" documentation for everyone that is up-to-date all the time. There's simply not enough manpower, time, and incentives to do that. Rather, it will be "good", "horrible", or "somewhere in-between" for diffent kinds of people and at different times/seasons. + Still, we can define our criteria for "good" documentation using these four factors: - [Type] - It defines which type of documentation it is From 4972403b9ae02a0723ff38b6afb05e0c30663277 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 1 Mar 2019 17:52:05 -0800 Subject: [PATCH 008/133] Clean up and further expand criteria for good documentation --- .../State-of-PureScript-Documentation-2019.md | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 0df2ef4..d62c44f 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -106,24 +106,30 @@ Many people stated that "heavily-commented code examples" often provide the best ### Criteria for "Good" Documentation -In short, it is impossible to write "good" documentation for everyone that is up-to-date all the time. There's simply not enough manpower, time, and incentives to do that. Rather, it will be "good", "horrible", or "somewhere in-between" for diffent kinds of people and at different times/seasons. +In short, it is impossible to write "good" documentation for everyone that is always up-to-date. There's simply not enough manpower, time, and incentives to do that. Rather, it will be "good", "horrible", or "somewhere in-between" for diffent kinds of people and at different times/seasons. Still, we can define our criteria for "good" documentation using these four factors: - [Type] - It defines which type of documentation it is - - If a Hook, then + - If a Hook, then it answers these questions clearly: + - What is it? / What problem does it solve? + - Who should care? / Who should not care? / How does it compare to other similar things? + - How long will it take to learn and how difficult is the learning curve? + - Where do I go to get started / learn how to use this? - If a Getting Started, then - If a How-To Guide, then - If a Reference, then - If a Explanation, then - [Audience] - It states who the intended audience is + - For those who aren't the intended audience, it refers to other material that better suits them - [Accuracy] - It explains which version of the code it documents - - If it's not the most recent version, it explains: - - Where it is outdated - - How to understand the outdated explanation in light of the new changes + - If it's not the most recent version, it provides: + - A brief idea of where it is outdated + - Guidelines for how to understand the outdated explanation in light of new changes - It includes the date it was published and last updated + - It indicates whether it will be updated in the future or has been abandoned and no future updates will occur. A few different audiences - shared (things we should explain, no matter who reads this) From eb6cf5a8866448d4d26f54f1e8c5dca9604cf949 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 1 Mar 2019 17:57:39 -0800 Subject: [PATCH 009/133] Move questions to 'The Hook' characteristics & refer to them in criteria --- .../State-of-PureScript-Documentation-2019.md | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index d62c44f..52329ab 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -41,8 +41,8 @@ First, there are 5 types of documentation that target specific phases of a learn | Type | Analogy | Characteristics | -- | -- | -- | -| The Hook | Selling a product to a potential customer |
  • Answers 'What is this thing? / What problem does it solve?'
  • Answers 'Why whould I care? / How is this relevant to me for my purposes?'
  • Answers 'Is learning how to use this thing worth it to me?'
-| Getting Started | Teaching a child how to cook |
  • Focuses on the learner 'doing' stuff, not 'explaining' stuff to the learner
  • Provides a small simple working example
  • New learners experience an 'I can use this now!' moment by the end
  • Focuses on concrete tasks, not abstract concepts
  • Does not use jargon
  • Explains only what is necessary and cuts out all else
  • Avoids explaining deeper concepts or different ways of doing the same thing
+| The Hook | Selling a product to a potential customer | Answers these questions:
  • What is this thing? / What problem does it solve?
  • Why whould I care? / How is this relevant to me for my purposes? / Who should not care?
  • How long will it take to learn it and how difficult is the learning curve?
  • Where do I go to get started / learn how to use this?
+| Getting Started | Teaching a child how to cook |
  • Focuses on the learner 'doing' stuff, not 'explaining' stuff to the learner
  • Provides a small simple working example that teaches the basics
  • New learners experience an 'I can use this now!' moment by the end
  • Focuses on concrete tasks, not abstract concepts
  • Does not use jargon
  • Explains only what is necessary and cuts out all else
  • Avoids explaining deeper concepts or different ways of doing the same thing
| How-To Guides | Following a cook book's recipe |
  • Achieves some goal or solves a problem
  • States the pre-requisites one needs to have before starting (not a Getting Started Guide)
  • The Guide follows a clearly-labeled step-by-step process
  • By following the steps, one reproduces the same results without fail
  • Explains the different ways one can achieve the same goal
  • Explains only what is necessary
| Explanation | Listening to a CEO answer questions about his company |
  • Explains the context/history
  • Explains the significant design decisions made, their alternativees, and the reasons one was chosen over another
  • Implies where things could be improved, expanded, refined, etc.
| Reference | Reading an encyclopedia |
  • Concise explanation of each piece of the code
  • The structure of the reference mirrors the structure of the code it documents
  • Formatting is consistent throughout the material
@@ -111,15 +111,7 @@ In short, it is impossible to write "good" documentation for everyone that is al Still, we can define our criteria for "good" documentation using these four factors: - [Type] - It defines which type of documentation it is - - If a Hook, then it answers these questions clearly: - - What is it? / What problem does it solve? - - Who should care? / Who should not care? / How does it compare to other similar things? - - How long will it take to learn and how difficult is the learning curve? - - Where do I go to get started / learn how to use this? - - If a Getting Started, then - - If a How-To Guide, then - - If a Reference, then - - If a Explanation, then + - It abides by that type's characteristics - [Audience] - It states who the intended audience is - For those who aren't the intended audience, it refers to other material that better suits them From fb96dda4a837f326126842fd3dd3ebe3292229db Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 1 Mar 2019 17:59:17 -0800 Subject: [PATCH 010/133] Add code examples are prioritized over other mediums --- .../State-of-PureScript-Documentation-2019.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 52329ab..45c61c5 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -122,6 +122,8 @@ Still, we can define our criteria for "good" documentation using these four fact - Guidelines for how to understand the outdated explanation in light of new changes - It includes the date it was published and last updated - It indicates whether it will be updated in the future or has been abandoned and no future updates will occur. +- [Medium] + - Prioritize working code examples over other mediums A few different audiences - shared (things we should explain, no matter who reads this) From 2f2e9cfe49ff7fdbf3c9a242ca954264f7b1452d Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 1 Mar 2019 18:01:33 -0800 Subject: [PATCH 011/133] Include TDT's note about being against literate programming as docs --- .../State-of-PureScript-Documentation-2019.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 45c61c5..6ac61ac 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -104,6 +104,8 @@ Fourth, documentation can appear in a few mediums/formats: Many people stated that "heavily-commented code examples" often provide the best form of documentation. They follow the principle of "show, don't tell." People can use them as a model and experiment on them. Each of the above mediums has their place, but the code examples might produce the best documentation in the shortest time possible. +[Teach, Don't Tell](http://stevelosh.com/blog/2013/09/teach-dont-tell/#act-3-literate-programming) argues that Literate Programming isn't a good tool for documentation. + ### Criteria for "Good" Documentation In short, it is impossible to write "good" documentation for everyone that is always up-to-date. There's simply not enough manpower, time, and incentives to do that. Rather, it will be "good", "horrible", or "somewhere in-between" for diffent kinds of people and at different times/seasons. From aa9a68905f81d0f6550ef276e9c1855a8da63958 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 1 Mar 2019 18:05:51 -0800 Subject: [PATCH 012/133] Represent source accurately: "A few people", not "many people" --- .../State-of-PureScript-Documentation-2019.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 6ac61ac..2d851d9 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -102,7 +102,7 @@ Fourth, documentation can appear in a few mediums/formats: | Commented Code Examples | Full runnable code | Comments | Walking someone through a video | Actual code | Slides / Long Essay / Quiz -Many people stated that "heavily-commented code examples" often provide the best form of documentation. They follow the principle of "show, don't tell." People can use them as a model and experiment on them. Each of the above mediums has their place, but the code examples might produce the best documentation in the shortest time possible. +A few people stated that "heavily-commented code examples" often provide the best form of documentation. They follow the principle of "show, don't tell." People can use them as a model and experiment on them. Each of the above mediums has their place, but the code examples might produce the best documentation in the shortest time possible. [Teach, Don't Tell](http://stevelosh.com/blog/2013/09/teach-dont-tell/#act-3-literate-programming) argues that Literate Programming isn't a good tool for documentation. From f90789c36ffa456fc76ce45a1ca30640f397df14 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 1 Mar 2019 18:44:15 -0800 Subject: [PATCH 013/133] Merge Documentation's maintenance and accuracy sections --- .../State-of-PureScript-Documentation-2019.md | 53 ++++++++++--------- 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 2d851d9..a040129 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -29,11 +29,10 @@ Did someone ever teach you how to write "good" documentation? No, you likely jus So, it helps to understand what is "good" documentation and why. -Essentially, there are 4 factors that affect whether documentation is "good" or not. +Essentially, there are 3 factors that affect whether documentation is "good" or not. 1. The type of documentation 2. The intended audience 3. How up-to-date the documentation is -4. The medium in which the documentation appears ### The Types of Documentation @@ -70,41 +69,46 @@ As a result, others who read the resulting documentation will consider it "poor" - If one comes from a different experience level, one might have unanswered questions: "They didn't even mention what the performance trade-offs for specific libraries were..." ~ a senior developer - If one has a different goal in mind, some crucial libraries might never be covered: "They didn't explain how I can make my Bitcoin client cryptographically secure..." -### The Documentation's Accuracy +### Maintaining Documentation's Accuracy -Third, breaking changes makes documentation inaccurate. It does this in two ways: decreasing its usefulness (depends on the 'size' of a breaking change) and decreasing its coherence (depends on the 'frequency' of breaking changes). +Third, documentation becomes outdated/inaccurate due to changes, especially breaking changes. It does this in two ways: decreasing its usefulness (depends on the 'size' of a change) and decreasing its coherence (depends on the 'frequency' of changes). -When **large** breaking changes occur, documentation can immediately become useless because: +| "Size" | Example +| -- | -- | +| Small | A bug fix that affects little else. +| Medium | A new feature +| Large | One or more breaking changes affecting numerous things simultaneously + +When breaking changes occur, documentation can immediately become useless because: - none of its code examples work anymore - old terms might mean something different now -- lessons/guides/explanations might need to be reordered -- some parts of the documentation might no longer be relevant - some new parts may need be written +- some parts of the documentation might no longer be relevant +- one needs to figure out how to integrate new content into old content -Updating documentation in light of "large" breaking changes often requires the most work. +Updating documentation in light of breaking changes often requires the most work to update. -When breaking changes occur **frequently**, documentation can appear more like loosely-coupled snippets of ideas rather than a coherent explanation because: -- Article A depends on Article B to explain something. Then, Aritcle B becomes outdated. Thus, one "patches" Article A with a quick overview that doesn't fit in with the rest of its content. -- One updates 3 out of 10 articles. One article says `X is true` whereas another says `X is false`. A new learner isn't sure which is correct. +| "Frequency" | Example +| -- | -- | +| Rarely | Stable libraries that have exhausted their design space (e.g. core data types) +| Sometimes | Maturing libraries that still have a few things to fix or add +| Frequently | New libraries -Updating documentation in light of "frequent" breaking changes often requires less overall work, but is difficult to update unless one is already very familiar with the documentation. +When changes occur frequently, documentation can appear more like loosely-coupled snippets of ideas rather than a coherent explanation because: +- Article A depends on Article B to explain something. Then, Aritcle B becomes outdated. Thus, one "patches" Article A with a quick overview of Article B that doesn't fit in with the rest of Article A's content. +- One updates 3 out of 10 articles. One article says `X is true` whereas another says `X is false`. A new learner isn't sure which is correct. -When **large** breaking changes occur **frequently**, it discourages people from updating the documentation. Why waste time on something that will become outdated soon? +Updating documentation in light of frequent changes often requires less overall work. -### The Mediums of Documentation +Moreover, when breaking changes occur frequently, it discourages people from updating the documentation. Why waste time on something that will become outdated soon? -Fourth, documentation can appear in a few mediums/formats: +The nature of this problem is not going to change. So, what medium of documentation provides the most "bang for your buck" long-term that is also is easiest to update? -| Medium | Type of Code Used | How things are explained | -| -- | -- | -- | -| Blog Posts | Syntax-highlighted snippets | Long essay (and images sometimes) -| Literate Programming | Code intermixed with short explanations | Code intermixed with short explanations -| Commented Code Examples | Full runnable code | Comments -| Walking someone through a video | Actual code | Slides / Long Essay / Quiz +Heavily-commented code examples. -A few people stated that "heavily-commented code examples" often provide the best form of documentation. They follow the principle of "show, don't tell." People can use them as a model and experiment on them. Each of the above mediums has their place, but the code examples might produce the best documentation in the shortest time possible. +It follows the principle of "show, don't tell." People can use them as a model from which to learn and as a playground on which to experiment. -[Teach, Don't Tell](http://stevelosh.com/blog/2013/09/teach-dont-tell/#act-3-literate-programming) argues that Literate Programming isn't a good tool for documentation. +Other mediums of documentation (e.g. blog posts, literate programming, videos) each have their place. However, the code examples might produce the easiest-to-update documentation in the shortest time possible. ### Criteria for "Good" Documentation @@ -118,14 +122,13 @@ Still, we can define our criteria for "good" documentation using these four fact - It states who the intended audience is - For those who aren't the intended audience, it refers to other material that better suits them - [Accuracy] + - Prioritize working code examples over other mediums - It explains which version of the code it documents - If it's not the most recent version, it provides: - A brief idea of where it is outdated - Guidelines for how to understand the outdated explanation in light of new changes - It includes the date it was published and last updated - It indicates whether it will be updated in the future or has been abandoned and no future updates will occur. -- [Medium] - - Prioritize working code examples over other mediums A few different audiences - shared (things we should explain, no matter who reads this) From 9c7451bc8e1c799d1188660be730333b76ed87d4 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 1 Mar 2019 18:52:03 -0800 Subject: [PATCH 014/133] Clean up criteria section --- .../State-of-PureScript-Documentation-2019.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index a040129..6b2e3f9 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -114,21 +114,21 @@ Other mediums of documentation (e.g. blog posts, literate programming, videos) e In short, it is impossible to write "good" documentation for everyone that is always up-to-date. There's simply not enough manpower, time, and incentives to do that. Rather, it will be "good", "horrible", or "somewhere in-between" for diffent kinds of people and at different times/seasons. -Still, we can define our criteria for "good" documentation using these four factors: +Still, we can define our criteria for "good" documentation using these four factors. Documentation is "good" when: - [Type] - - It defines which type of documentation it is + - It states which type of documentation it is - It abides by that type's characteristics - [Audience] - It states who the intended audience is - For those who aren't the intended audience, it refers to other material that better suits them - [Accuracy] - - Prioritize working code examples over other mediums + - It tends to be heavier on code examples rather than other mediums - It explains which version of the code it documents - If it's not the most recent version, it provides: - A brief idea of where it is outdated - Guidelines for how to understand the outdated explanation in light of new changes - - It includes the date it was published and last updated - - It indicates whether it will be updated in the future or has been abandoned and no future updates will occur. + - It includes the date it was published and when it was last updated + - It indicates whether it will be updated in the future (and when) or has been abandoned and no future updates will occur. A few different audiences - shared (things we should explain, no matter who reads this) From bc5044715f75e7aa9b51709b0b52c7579adf2533 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 1 Mar 2019 19:06:43 -0800 Subject: [PATCH 015/133] Include note about automating tasks; add headers to section --- .../State-of-PureScript-Documentation-2019.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 6b2e3f9..8ad03db 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -73,6 +73,8 @@ As a result, others who read the resulting documentation will consider it "poor" Third, documentation becomes outdated/inaccurate due to changes, especially breaking changes. It does this in two ways: decreasing its usefulness (depends on the 'size' of a change) and decreasing its coherence (depends on the 'frequency' of changes). +#### The "Size" of a Change + | "Size" | Example | -- | -- | | Small | A bug fix that affects little else. @@ -88,6 +90,8 @@ When breaking changes occur, documentation can immediately become useless becaus Updating documentation in light of breaking changes often requires the most work to update. +#### The "Frequency" of a Change + | "Frequency" | Example | -- | -- | | Rarely | Stable libraries that have exhausted their design space (e.g. core data types) @@ -100,6 +104,8 @@ When changes occur frequently, documentation can appear more like loosely-couple Updating documentation in light of frequent changes often requires less overall work. +#### How to Make Maintenance Easier + Moreover, when breaking changes occur frequently, it discourages people from updating the documentation. Why waste time on something that will become outdated soon? The nature of this problem is not going to change. So, what medium of documentation provides the most "bang for your buck" long-term that is also is easiest to update? @@ -110,6 +116,8 @@ It follows the principle of "show, don't tell." People can use them as a model f Other mediums of documentation (e.g. blog posts, literate programming, videos) each have their place. However, the code examples might produce the easiest-to-update documentation in the shortest time possible. +Lastly, some documentations tasks are tedious and consume lots of time. Finding ways to automate them can greatly improve the situation. + ### Criteria for "Good" Documentation In short, it is impossible to write "good" documentation for everyone that is always up-to-date. There's simply not enough manpower, time, and incentives to do that. Rather, it will be "good", "horrible", or "somewhere in-between" for diffent kinds of people and at different times/seasons. From 186e20fa2357a32a86aa8602e71a48ea8507bc21 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 1 Mar 2019 19:32:14 -0800 Subject: [PATCH 016/133] Add list of learning resources and when they appeared --- .../State-of-PureScript-Documentation-2019.md | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 8ad03db..294075b 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -138,6 +138,43 @@ Still, we can define our criteria for "good" documentation using these four fact - It includes the date it was published and when it was last updated - It indicates whether it will be updated in the future (and when) or has been abandoned and no future updates will occur. +### Evaluating PureScript's Documentation + +Here was PureScript's documentation as of July 2018: + +| Name | Type | Audience | Medium | +| -- | -- | -- | -- | +| The Documentation Repository | Getting Started + Explanation | New PS Learners | GitHub Repo +| Pursuit | Reference | All PS developers | API Docs website +| PureScript by Example | Getting Started + How To + Explanation | New PS Learners | Book +| PureScript Resources | Getting Started + Explanation | New PS Learners | Read The Docs +| Lens for the Mere Mortal: PureScript Edition | How To + Explanation | Intermediate PS Learners | Book +| -- | -- | -- | -- | +| Professor Frisby Introduces Composable Functional JavaScript | Getting Started + How to + Explanation | JavaScript developers who want to use JavaScript | Online Course +| An Outsider's Guide to Statically Typed Functional Programming | Hook + Getting Started + How to + Explanation | JavaScript developers who want to learn Elm but are exposed to PureScript at end | Book +| -- | -- | -- | -- | +| Elm to PureScript Cheatsheet | Reference | Elm developers considering PureScript | GitHub Repo +| Differences of PureScript from Elm | Reference | Elm developers consider PureScript (or vice versa) | GitHub Gist +| Documentation Repo's "Differences from Haskell" | Reference | Haskell developers considering PureScript | Markdown file + +Here's what has been added to the above since then: + +| Name | Type | Audience | Medium | +| -- | -- | -- | -- | +| Real World App | How To Guide? Reference? | PureScript developers | Code Example +| MultiPac | Reference? | PureScript developers | Code Example +| PureScript: Jordan's Reference | Hook + Getting Started + How to + Explanation + Reference | New Learners | GitHub Repo +| A Guide to the PureScript Numeric Hierarchy | Explanation | New Learners | Read the Docs +| Make the Leap from JavaScript to PureScript | Getting Started + Explanation | Javascript developers | Blog Post series + +The following + - Evaluate PureScript's documentation using that criteria + - Explain why PureScript's documentation is lacking and what is being done to improve it + - Address various audience's possible concerns or questions centered on these themes: + - New learners - How should I learn PureScript? + - PureScript documentation writers - How should I write good maintainable documentation for others? + - Core Contributors - + A few different audiences - shared (things we should explain, no matter who reads this) - Why read this document (capture people's attention in less than 2 paragraphs) From 04c06d3cf7e87f0f4312e676184084d14c249a54 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 1 Mar 2019 20:08:44 -0800 Subject: [PATCH 017/133] Add headers and outline for next parts of the file --- .../State-of-PureScript-Documentation-2019.md | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 294075b..04f3d83 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -167,6 +167,35 @@ Here's what has been added to the above since then: | A Guide to the PureScript Numeric Hierarchy | Explanation | New Learners | Read the Docs | Make the Leap from JavaScript to PureScript | Getting Started + Explanation | Javascript developers | Blog Post series +## Why is PureScript's Documentation Lacking and How Do We Improve It? + +- Philosophy of the language: + - avoid (success at all costs) + - wrong intepretation: + - right interpretation +- Current priority of core contributors: adding powerful features via breaking changes + - wrong interpretation: they don't care + - right interpretation: want to improve language + - Why a `v1.0` hasn't been released +- Core Contributors are spread thin, so they cannot respond quickly to things + - The '75 libraries' problem + - Entrusting library maintenance to others and supporting them (e.g. the `event-stream` incident) + - Just like reviewing code, reviewing documentation takes a lot of thought + - Hard to keep documentation momentum + - Which libraries are 'core libraries'? +- No clearly-defined mutually-held community-wide goal + - A desire to help exists, but no one is coordinating resources strategically +- What exactly are FP's "Best Practices?" + - They are not well-defined, are assumed, or are habits + - Knowledge silos exist, so it's hard to extract that info +- Slack-based discussions do not persist + +## New Learners: What is the Best Way to Learn PureScript? + +## PureScript Documentation Writers: What is the Best Way to Write Documentation in this Context? + +## Core Contributors: ??? + The following - Evaluate PureScript's documentation using that criteria - Explain why PureScript's documentation is lacking and what is being done to improve it From 98e9e54bedfc2822d8fb0a999d7f38204dda613f Mon Sep 17 00:00:00 2001 From: Alex Berg Date: Sat, 2 Mar 2019 10:49:26 -0600 Subject: [PATCH 018/133] Review and revise context-narrative --- .../State-of-PureScript-Documentation-2019.md | 38 +++++++++---------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 04f3d83..f6a828f 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -17,43 +17,41 @@ It is well-known among the PureScript community that its documentation is lackin Outline - Explain what "good" documentation is and define a criteria - Evaluate PureScript's documentation using that criteria -- Explain why PureScript's documentation is lacking and what is being done to improve it +- Explore where PureScript's documentation is lacking and what can be done to improve it - Address various audience's possible concerns or questions centered on these themes: - New learners - How should I learn PureScript? - PureScript documentation writers - How should I write good maintainable documentation for others? - - Core Contributors - + - Core Contributors - ## What is "Good" Documentation Anyway? -Did someone ever teach you how to write "good" documentation? No, you likely just wrote what came to mind and hoped it was good enough. - -So, it helps to understand what is "good" documentation and why. +Did someone ever teach you how to write "good" documentation? Probably not - you likely just wrote what came to mind and hoped it was good enough. So, it's useful to learn a definition of good documentation and understand why it's defined that way. Essentially, there are 3 factors that affect whether documentation is "good" or not. -1. The type of documentation -2. The intended audience -3. How up-to-date the documentation is +1. The intended audience +2. The type of documentation: the question being answered, targeting a specific subsection of the audience +3. How accurately it reflects the desired version of the thing being documented ### The Types of Documentation First, there are 5 types of documentation that target specific phases of a learner's experience (as explained in [What Nobody Tells You About Documentation](https://www.divio.com/blog/documentation/) and [Teach, Don't Tell](http://stevelosh.com/blog/2013/09/teach-dont-tell/)) -| Type | Analogy | Characteristics -| -- | -- | -- | -| The Hook | Selling a product to a potential customer | Answers these questions:
  • What is this thing? / What problem does it solve?
  • Why whould I care? / How is this relevant to me for my purposes? / Who should not care?
  • How long will it take to learn it and how difficult is the learning curve?
  • Where do I go to get started / learn how to use this?
-| Getting Started | Teaching a child how to cook |
  • Focuses on the learner 'doing' stuff, not 'explaining' stuff to the learner
  • Provides a small simple working example that teaches the basics
  • New learners experience an 'I can use this now!' moment by the end
  • Focuses on concrete tasks, not abstract concepts
  • Does not use jargon
  • Explains only what is necessary and cuts out all else
  • Avoids explaining deeper concepts or different ways of doing the same thing
-| How-To Guides | Following a cook book's recipe |
  • Achieves some goal or solves a problem
  • States the pre-requisites one needs to have before starting (not a Getting Started Guide)
  • The Guide follows a clearly-labeled step-by-step process
  • By following the steps, one reproduces the same results without fail
  • Explains the different ways one can achieve the same goal
  • Explains only what is necessary
-| Explanation | Listening to a CEO answer questions about his company |
  • Explains the context/history
  • Explains the significant design decisions made, their alternativees, and the reasons one was chosen over another
  • Implies where things could be improved, expanded, refined, etc.
-| Reference | Reading an encyclopedia |
  • Concise explanation of each piece of the code
  • The structure of the reference mirrors the structure of the code it documents
  • Formatting is consistent throughout the material
+| Learner's Phase | Type | Analogy | Characteristics +| -- | -- | -- | -- | +| Curious Outsider | The Hook | Selling a product to a potential customer | Answers these questions:
  • What is this thing? / What problem does it solve?
  • Why whould I care? / How is this relevant to me for my purposes? / Who should not care?
  • How long will it take to learn it and how difficult is the learning curve?
  • Where do I go to get started / learn how to use this?
+| Looking and Feeling the Product | Getting Started | Teaching a child how to cook |
  • Focuses on the learner 'doing' stuff, not 'explaining' stuff to the learner
  • Provides a small simple working example that teaches the basics
  • New learners experience an 'I can use this now!' moment by the end
  • Focuses on concrete tasks, not abstract concepts
  • Does not use jargon
  • Explains only what is necessary and cuts out all else
  • Avoids explaining deeper concepts or different ways of doing the same thing
+| Testing the Product | How-To Guides | Following a cookbook's recipe |
  • Achieves some goal or solves a problem
  • States the pre-requisites one needs to have before starting (not a Getting Started Guide)
  • The Guide follows a clearly-labeled step-by-step process
  • By following the steps, one reproduces the same results without fail
  • Explains the different ways one can achieve the same goal
  • Explains only what is necessary
+| Discussing Design Details During Adoption | Explanation | Listening to a CEO answer questions about his company |
  • Explains the context/history
  • Explains the significant design decisions made, their alternativees, and the reasons one was chosen over another
  • Implies where things could be improved, expanded, refined, etc.
+| Consulting Product Vocabulary Dictionary Post-adoption | Reference | Reading an encyclopedia |
  • Concise explanation of each piece of the code
  • The structure of the reference mirrors the structure of the code it documents
  • Formatting is consistent throughout the material
Moreover, there are clear examples of "bad" documentation (as explained in [Teach, Don't Tell](http://stevelosh.com/blog/2013/09/teach-dont-tell/)): -| Statement | Why it's bad | +| Documentation Source | Why it's bad | | -- | -- | -| Read the Source Code | Only useful once you are already familiar with it -| Read the Test Code | While it uses the code, it tends to focus on edge cases, not normal cases, and may not use all possible options/configurations. -| Read the API docs | One must know the name of the function/value to be able to read its documentation. Most won't know the name until you teach it to them. Likewise, people don't learn by reading alphabetized lists of disconnected information -| Read the Wiki | Content is usually not written by the code's authors, but by multiple 3rd-party people. There are often multiple disconnected voices throughout the material. It's like asking a student to write his own lesson plan. +| Source Code | Only useful once you are already familiar with it +| Test Code | While it uses the code, it tends to focus on edge cases, not normal cases, and may not use all possible options/configurations. +| API docs | One must know the name of the function/value to be able to read its documentation. Most won't know the name until you teach it to them. Likewise, people don't learn by reading alphabetized lists of disconnected information +| Wiki | Content is usually not written by the code's authors, but by multiple 3rd-party people. There are often multiple disconnected voices throughout the material. It's like asking a student to write his own lesson plan. ### The Documentation's Intended Audience From a6322222649b76274411deb134e5e05632eb80d0 Mon Sep 17 00:00:00 2001 From: Alex Berg Date: Sat, 2 Mar 2019 13:16:31 -0600 Subject: [PATCH 019/133] Adjust per review --- .../State-of-PureScript-Documentation-2019.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index f6a828f..8e74d22 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -17,7 +17,8 @@ It is well-known among the PureScript community that its documentation is lackin Outline - Explain what "good" documentation is and define a criteria - Evaluate PureScript's documentation using that criteria -- Explore where PureScript's documentation is lacking and what can be done to improve it +- Explain why PureScript's documentation isn't developing as fast as wanted +- Develop plans to improve the current documentation strategy or process - Address various audience's possible concerns or questions centered on these themes: - New learners - How should I learn PureScript? - PureScript documentation writers - How should I write good maintainable documentation for others? @@ -39,10 +40,10 @@ First, there are 5 types of documentation that target specific phases of a learn | Learner's Phase | Type | Analogy | Characteristics | -- | -- | -- | -- | | Curious Outsider | The Hook | Selling a product to a potential customer | Answers these questions:
  • What is this thing? / What problem does it solve?
  • Why whould I care? / How is this relevant to me for my purposes? / Who should not care?
  • How long will it take to learn it and how difficult is the learning curve?
  • Where do I go to get started / learn how to use this?
-| Looking and Feeling the Product | Getting Started | Teaching a child how to cook |
  • Focuses on the learner 'doing' stuff, not 'explaining' stuff to the learner
  • Provides a small simple working example that teaches the basics
  • New learners experience an 'I can use this now!' moment by the end
  • Focuses on concrete tasks, not abstract concepts
  • Does not use jargon
  • Explains only what is necessary and cuts out all else
  • Avoids explaining deeper concepts or different ways of doing the same thing
-| Testing the Product | How-To Guides | Following a cookbook's recipe |
  • Achieves some goal or solves a problem
  • States the pre-requisites one needs to have before starting (not a Getting Started Guide)
  • The Guide follows a clearly-labeled step-by-step process
  • By following the steps, one reproduces the same results without fail
  • Explains the different ways one can achieve the same goal
  • Explains only what is necessary
-| Discussing Design Details During Adoption | Explanation | Listening to a CEO answer questions about his company |
  • Explains the context/history
  • Explains the significant design decisions made, their alternativees, and the reasons one was chosen over another
  • Implies where things could be improved, expanded, refined, etc.
-| Consulting Product Vocabulary Dictionary Post-adoption | Reference | Reading an encyclopedia |
  • Concise explanation of each piece of the code
  • The structure of the reference mirrors the structure of the code it documents
  • Formatting is consistent throughout the material
+| Potential User | Getting Started | Teaching a child how to cook |
  • Focuses on the learner 'doing' stuff, not 'explaining' stuff to the learner
  • Provides a small simple working example that teaches the basics
  • New learners experience an 'I can use this now!' moment by the end
  • Focuses on concrete tasks, not abstract concepts
  • Does not use jargon
  • Explains only what is necessary and cuts out all else
  • Avoids explaining deeper concepts or different ways of doing the same thing
+| New User | How-To Guides | Following a cookbook's recipe |
  • Achieves some goal or solves a problem
  • States the pre-requisites one needs to have before starting (not a Getting Started Guide)
  • The Guide follows a clearly-labeled step-by-step process
  • By following the steps, one reproduces the same results without fail
  • Explains the different ways one can achieve the same goal
  • Explains only what is necessary
+| Active User | Reference | Reading an encyclopedia |
  • Concise explanation of each piece of the code
  • The structure of the reference mirrors the structure of the code it documents
  • Formatting is consistent throughout the material
+| Experienced User | Explanation | Listening to a CEO answer questions about his company |
  • Explains the context/history
  • Explains the significant design decisions made, their alternativees, and the reasons one was chosen over another
  • Implies where things could be improved, expanded, refined, etc.
Moreover, there are clear examples of "bad" documentation (as explained in [Teach, Don't Tell](http://stevelosh.com/blog/2013/09/teach-dont-tell/)): From 056e6e70b43eb4ac5bac5c00225883488f7a3e95 Mon Sep 17 00:00:00 2001 From: Alex Berg Date: Sat, 2 Mar 2019 13:21:36 -0600 Subject: [PATCH 020/133] Adjust the outline part per review --- .../State-of-PureScript-Documentation-2019.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 8e74d22..7f3bad1 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -17,8 +17,8 @@ It is well-known among the PureScript community that its documentation is lackin Outline - Explain what "good" documentation is and define a criteria - Evaluate PureScript's documentation using that criteria -- Explain why PureScript's documentation isn't developing as fast as wanted -- Develop plans to improve the current documentation strategy or process +- Explain why PureScript's documentation is seen as lacking +- Suggest plans to improve the current documentation strategy or process - Address various audience's possible concerns or questions centered on these themes: - New learners - How should I learn PureScript? - PureScript documentation writers - How should I write good maintainable documentation for others? From 9945e6bf1a25e2e556387c97f2284eda413adc4a Mon Sep 17 00:00:00 2001 From: Alex Berg Date: Sat, 2 Mar 2019 13:28:13 -0600 Subject: [PATCH 021/133] Update State-of-PureScript-Documentation-2019.md --- .../State-of-PureScript-Documentation-2019.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 7f3bad1..a1c9253 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -18,7 +18,7 @@ Outline - Explain what "good" documentation is and define a criteria - Evaluate PureScript's documentation using that criteria - Explain why PureScript's documentation is seen as lacking -- Suggest plans to improve the current documentation strategy or process +- Suggest plans to improve the current documentation situation - Address various audience's possible concerns or questions centered on these themes: - New learners - How should I learn PureScript? - PureScript documentation writers - How should I write good maintainable documentation for others? From 2a657c7a877e985215cec38aee113985ebb1229f Mon Sep 17 00:00:00 2001 From: Alex Berg Date: Sat, 2 Mar 2019 13:43:12 -0600 Subject: [PATCH 022/133] Change to use "it" --- .../State-of-PureScript-Documentation-2019.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index a1c9253..5606716 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -29,9 +29,9 @@ Outline Did someone ever teach you how to write "good" documentation? Probably not - you likely just wrote what came to mind and hoped it was good enough. So, it's useful to learn a definition of good documentation and understand why it's defined that way. Essentially, there are 3 factors that affect whether documentation is "good" or not. -1. The intended audience -2. The type of documentation: the question being answered, targeting a specific subsection of the audience -3. How accurately it reflects the desired version of the thing being documented +1. Its intended audience +2. Its type: the question being answered, targeting a specific subsection of the audience +3. How accurately it reflects the desired version of the code/project ### The Types of Documentation From 533d14ad3392909b9c2af6b3a33ca01d7e932c2a Mon Sep 17 00:00:00 2001 From: Alex Berg Date: Sat, 2 Mar 2019 13:44:20 -0600 Subject: [PATCH 023/133] Update State-of-PureScript-Documentation-2019.md --- .../State-of-PureScript-Documentation-2019.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 5606716..88f654e 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -26,7 +26,9 @@ Outline ## What is "Good" Documentation Anyway? -Did someone ever teach you how to write "good" documentation? Probably not - you likely just wrote what came to mind and hoped it was good enough. So, it's useful to learn a definition of good documentation and understand why it's defined that way. +Did someone ever teach you how to write "good" documentation? Probably not - you likely just wrote what came to mind and hoped it was good enough. + +Because of this, it's useful to learn a definition of good documentation and understand why it's defined that way. Essentially, there are 3 factors that affect whether documentation is "good" or not. 1. Its intended audience From d1250323cf31d56addd99306af65f3a9bf02c73c Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 2 Mar 2019 13:32:47 -0800 Subject: [PATCH 024/133] Summarize why PS is lacking; explain "avoid (success at all costs)" --- .../State-of-PureScript-Documentation-2019.md | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 88f654e..2d80cd9 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -170,6 +170,48 @@ Here's what has been added to the above since then: ## Why is PureScript's Documentation Lacking and How Do We Improve It? +These are the reasons. Each wil be covered more in-depth following this: + +- PureScript is not _currently_ trying to be the next "mainstream language". +- Core contributors are spread thin: limited time with too much responsibility +- Core contributors are prioritizing the addition of new powerful language features over other interests +- There is no clearly-defined mutually-held community-wide goal/vision that coordinates efforts +- It's difficult to pin down and define what are Functional Programming's "best practices" +- Questions answered on Slack do not persist, so they get re-asked and re-answered + +### PureScript is not _currently_ trying to be the next "mainstream language" + +Many have wrongly assumed that PureScript is trying to replace [insert your favorite web language here]. That is not the case. Each language has its trade-offs that make it better for some and worse for others. + +Rather, PureScript is _currently_ following the motto of "**avoid (success at all costs)**". + +#### The Wrong Interpretation of 'Avoid (success at all costs)' + +One might understand 'avoid (success at all costs)' as "We don't want to be 'successful.' We don't want everyone to use this language. Therefore, let's make it hard and impractical for people to learn and use this language." + +New learners have likely said or thought, "Stupid language developers! Why didn't they make it easier to learn how to use this language and its abstractions? I thought this was a 'better' language." + +This interpretation is flawed because it focuses on the _wrong core values_: low learning curve and ease of use. PureScript's language developers do value these things, but they value other things more. + +#### The Right Interpretation of 'Avoid (success at all costs)' + +To understand this motto, one must understand the core value behind it: productivity: +- Using the right abstractions to solve a problem is more productive than using a workaround/hack because of a language deficiency. +- Writing code correctly "the first time" is more productive than fixing bugs later (e.g. trading runtime errors for compiler errors) +- Painless refactoring is more productive when reducing technical debt than painful refactoring. +- Creating solutions to problems that "just work" is more productive than solutions that "should work." + +In short, all languages make compromises based on which core values they value more than others. PureScript "bought" power and productivity at the "price" of a higher learning curve and lower ease of use. Other languages made a different "purchase." + +This leaves one conclusion: PureScript might not be the language for you. + +If you can accomplish your goals using a language that "fits" you better than PureScript, why use PureScript? + +Programming exists to solve problems. It's not about proving whether you are clever and disciplined enough to learn something hard. Go use that language instead, and come back if you change your mind. + +If you value the same things that PureScript language developers value, then you are right at home. + + - Philosophy of the language: - avoid (success at all costs) - wrong intepretation: From 7a373b28783e97289df5c204741498c925fff6ca Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 2 Mar 2019 13:44:52 -0800 Subject: [PATCH 025/133] Reword some of the productivity examples --- .../State-of-PureScript-Documentation-2019.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 2d80cd9..d02e560 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -196,10 +196,11 @@ This interpretation is flawed because it focuses on the _wrong core values_: low #### The Right Interpretation of 'Avoid (success at all costs)' To understand this motto, one must understand the core value behind it: productivity: -- Using the right abstractions to solve a problem is more productive than using a workaround/hack because of a language deficiency. -- Writing code correctly "the first time" is more productive than fixing bugs later (e.g. trading runtime errors for compiler errors) +- Using the right abstractions is more productive than using a workaround/hack because of a language deficiency. +- Languages that nag at you to write well-structured programs are more productive than those that don't. +- Fixing bugs before shipping is more productive than fixing bugs after shipping (e.g. trading runtime errors for compiler errors) - Painless refactoring is more productive when reducing technical debt than painful refactoring. -- Creating solutions to problems that "just work" is more productive than solutions that "should work." +- Creating solutions that "just work" is more productive than solutions that "should work." In short, all languages make compromises based on which core values they value more than others. PureScript "bought" power and productivity at the "price" of a higher learning curve and lower ease of use. Other languages made a different "purchase." From 7c5b9ddf94e8f0e4d05e2ac9d53cd1d23f71925c Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 2 Mar 2019 14:47:54 -0800 Subject: [PATCH 026/133] Summarize 'contributors spread thin' issue in why PS is lacking docs --- .../State-of-PureScript-Documentation-2019.md | 47 +++++++++++++++++-- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index d02e560..d7b4f27 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -22,7 +22,7 @@ Outline - Address various audience's possible concerns or questions centered on these themes: - New learners - How should I learn PureScript? - PureScript documentation writers - How should I write good maintainable documentation for others? - - Core Contributors - + - Core Contributors - ## What is "Good" Documentation Anyway? @@ -212,11 +212,48 @@ Programming exists to solve problems. It's not about proving whether you are cle If you value the same things that PureScript language developers value, then you are right at home. +### Core contributors are spread thin: limited time with too much responsibility + +> It’s been 7 months since I announced that I would be taking a long break from PureScript development.... +> In retrospect, I think it’s fair to say that I was quite thoroughly burned out from trying to balance open source work and real life. +> +> ~ Phil Freeman, the creator of the PureScript language [(1st & 2nd paragraph)](https://discourse.purescript.org/t/the-state-of-things/282) + +> Just to wallow for a second, I... +> - contribute to/review stuff on the compiler +> - attempt to keep on top of the issues, discussions, PRs on roughly 75 libraries (some of which are tiny and almost never change, some of which are purescript-dom :grimacing:) +> - engage with people on Twitter, StackOverflow, Reddit, Slack +> - and very occasionally investigate some idea of my own. +> +> So unless I stop doing some of that, there's no chance I can make any meaningful steps to improving the documentation situation. +> +> ~ a core contributor ([2nd paragraph](https://gist.github.com/marick/e8b01375309fafaefb879c4840b6da75#gistcomment-2569261), edits made: content was turned into a list; "..." changed to "," for readability) + +As a result, documentation PRs are either forgotten or reviewed long after their initial submission. It's quite difficult to maintain momentum in such a context. + +Finally, reviewing documentation can be just as difficult as reviewing code. Some people are faster at reviewing things than others. + +#### Why Not Just Delegate? + +> A hypothetical developer says, "If it's so much work, why not just **delegate** the work? This 'somebody' can also be a proxy who's gathering feedback, so that you don't have to be in these discussions." +> The contributor responds sarcastically, "Oh! Delegation, of course! I hadn't thought about that...." +> There's actually an assumption going on here: "If 'free' rice means you can take as much as you want, then 'free' labor implies you can take as much as you want." But that isn't how labor works. If you don't pay for labor, you get less. +> Even if everyone could help, there's still limitations due to coordinating efforts: who does what, when, where, and without affecting someone else's work. +> +> ~ summary of 'Why Not Just... Pattern' part in [The Hard Parts of Open Source](https://youtu.be/o_4EX4dPppA?t=257) + +One shouldn't everyone on the internet. I know, big surprise. For example, consider the `event-stream incident`. The maintainer unknowingly gave write-access to a malicious actor. Practically everyone depends on this code. The actor injected code that could be used to steal bitcoins. ([initial issue](https://github.com/dominictarr/event-stream/issues/116), [injected code explanation](https://github.com/dominictarr/event-stream/issues/116#issuecomment-441759047), [previous maintainer's response](https://github.com/dominictarr/event-stream/issues/116)) + +#### Why Not Fund Language Developers? + +It's already been done via the [PureScript Open Collective]((https://opencollective.com/purescript)). However, someone took it down. I (Jordan) don't know the full reasons. Here's my speculation: +- Since the project and its funds hadn't been claimed for a couple of weeks, it was stopped to prevent anyone on the internet from stealing the funds. +- There was no clear vision as to how the funds would be spent and how it would improve the situation. + +Perhaps this idea could be revisited in the future. For now, we cannot say. + + -- Philosophy of the language: - - avoid (success at all costs) - - wrong intepretation: - - right interpretation - Current priority of core contributors: adding powerful features via breaking changes - wrong interpretation: they don't care - right interpretation: want to improve language From d608f90e302c577e38cedf17aed7d247f68aef9f Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 2 Mar 2019 14:57:13 -0800 Subject: [PATCH 027/133] Convert links into a list of links --- .../State-of-PureScript-Documentation-2019.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index d7b4f27..b85d548 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -242,7 +242,11 @@ Finally, reviewing documentation can be just as difficult as reviewing code. Som > > ~ summary of 'Why Not Just... Pattern' part in [The Hard Parts of Open Source](https://youtu.be/o_4EX4dPppA?t=257) -One shouldn't everyone on the internet. I know, big surprise. For example, consider the `event-stream incident`. The maintainer unknowingly gave write-access to a malicious actor. Practically everyone depends on this code. The actor injected code that could be used to steal bitcoins. ([initial issue](https://github.com/dominictarr/event-stream/issues/116), [injected code explanation](https://github.com/dominictarr/event-stream/issues/116#issuecomment-441759047), [previous maintainer's response](https://github.com/dominictarr/event-stream/issues/116)) +One shouldn't everyone on the internet. I know, big surprise. For example, consider the `event-stream incident`. The maintainer unknowingly gave write-access to a malicious actor. Practically everyone depends on this code. The actor injected code that could be used to steal bitcoins: +- [initial issue](https://github.com/dominictarr/event-stream/issues/116) +- [injected code explanation](https://github.com/dominictarr/event-stream/issues/116#issuecomment-441759047) +- [original maintainer's response](https://github.com/dominictarr/event-stream/issues/116) +- [a sarcastic blog post summarizing this class of attack](https://hackernoon.com/im-harvesting-credit-card-numbers-and-passwords-from-your-site-here-s-how-9a8cb347c5b5) #### Why Not Fund Language Developers? From c794b4a953dcb013788163ea4b43463190cea1cc Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 2 Mar 2019 15:00:28 -0800 Subject: [PATCH 028/133] Fix formatting to make content more readable --- .../State-of-PureScript-Documentation-2019.md | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index b85d548..cf360ea 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -215,6 +215,7 @@ If you value the same things that PureScript language developers value, then you ### Core contributors are spread thin: limited time with too much responsibility > It’s been 7 months since I announced that I would be taking a long break from PureScript development.... +> > In retrospect, I think it’s fair to say that I was quite thoroughly burned out from trying to balance open source work and real life. > > ~ Phil Freeman, the creator of the PureScript language [(1st & 2nd paragraph)](https://discourse.purescript.org/t/the-state-of-things/282) @@ -236,21 +237,28 @@ Finally, reviewing documentation can be just as difficult as reviewing code. Som #### Why Not Just Delegate? > A hypothetical developer says, "If it's so much work, why not just **delegate** the work? This 'somebody' can also be a proxy who's gathering feedback, so that you don't have to be in these discussions." +> > The contributor responds sarcastically, "Oh! Delegation, of course! I hadn't thought about that...." +> > There's actually an assumption going on here: "If 'free' rice means you can take as much as you want, then 'free' labor implies you can take as much as you want." But that isn't how labor works. If you don't pay for labor, you get less. -> Even if everyone could help, there's still limitations due to coordinating efforts: who does what, when, where, and without affecting someone else's work. > -> ~ summary of 'Why Not Just... Pattern' part in [The Hard Parts of Open Source](https://youtu.be/o_4EX4dPppA?t=257) +> Even if everyone could help, there's still limitations due to coordinating efforts: who does what, when, and where, and all without affecting someone else's work. +> +> ~ summary of the 'Why Not Just... Pattern' in [The Hard Parts of Open Source](https://youtu.be/o_4EX4dPppA?t=257) + +One shouldn't trust everyone on the internet. (I know, big surprise.) -One shouldn't everyone on the internet. I know, big surprise. For example, consider the `event-stream incident`. The maintainer unknowingly gave write-access to a malicious actor. Practically everyone depends on this code. The actor injected code that could be used to steal bitcoins: +For example, consider the `event-stream incident`. The maintainer unknowingly gave write-access to a malicious actor. Practically everyone depends on this code. The actor injected code that could be used to steal bitcoins: - [initial issue](https://github.com/dominictarr/event-stream/issues/116) - [injected code explanation](https://github.com/dominictarr/event-stream/issues/116#issuecomment-441759047) - [original maintainer's response](https://github.com/dominictarr/event-stream/issues/116) - [a sarcastic blog post summarizing this class of attack](https://hackernoon.com/im-harvesting-credit-card-numbers-and-passwords-from-your-site-here-s-how-9a8cb347c5b5) -#### Why Not Fund Language Developers? +#### Why Not Fund the Language Developers? + +Been there, done that. Someone took it down. ([PureScript Open Collective]((https://opencollective.com/purescript)) -It's already been done via the [PureScript Open Collective]((https://opencollective.com/purescript)). However, someone took it down. I (Jordan) don't know the full reasons. Here's my speculation: +I (Jordan) don't know why it was taken down. Here's my speculation: - Since the project and its funds hadn't been claimed for a couple of weeks, it was stopped to prevent anyone on the internet from stealing the funds. - There was no clear vision as to how the funds would be spent and how it would improve the situation. From c6a8fcacca18064163c9e790ae670ba5b511c162 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 2 Mar 2019 15:00:55 -0800 Subject: [PATCH 029/133] Keep the 'why not just' pattern going --- .../State-of-PureScript-Documentation-2019.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index cf360ea..0dceba0 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -254,7 +254,7 @@ For example, consider the `event-stream incident`. The maintainer unknowingly ga - [original maintainer's response](https://github.com/dominictarr/event-stream/issues/116) - [a sarcastic blog post summarizing this class of attack](https://hackernoon.com/im-harvesting-credit-card-numbers-and-passwords-from-your-site-here-s-how-9a8cb347c5b5) -#### Why Not Fund the Language Developers? +#### Why Not Just Fund the Language Developers? Been there, done that. Someone took it down. ([PureScript Open Collective]((https://opencollective.com/purescript)) From 24f5acec0409e76080e53a67b1264172213491e8 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 2 Mar 2019 15:23:38 -0800 Subject: [PATCH 030/133] Include note about the cost of supporting new maintainers --- .../State-of-PureScript-Documentation-2019.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 0dceba0..b0533f1 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -254,6 +254,8 @@ For example, consider the `event-stream incident`. The maintainer unknowingly ga - [original maintainer's response](https://github.com/dominictarr/event-stream/issues/116) - [a sarcastic blog post summarizing this class of attack](https://hackernoon.com/im-harvesting-credit-card-numbers-and-passwords-from-your-site-here-s-how-9a8cb347c5b5) +Finally, new maintainers, once found, have to be supported (which takes time and thought), so that they can actually fulfill their role. If they decide to leave soon after starting, then one has wasted time and effort. + #### Why Not Just Fund the Language Developers? Been there, done that. Someone took it down. ([PureScript Open Collective]((https://opencollective.com/purescript)) @@ -266,10 +268,6 @@ Perhaps this idea could be revisited in the future. For now, we cannot say. -- Current priority of core contributors: adding powerful features via breaking changes - - wrong interpretation: they don't care - - right interpretation: want to improve language - - Why a `v1.0` hasn't been released - Core Contributors are spread thin, so they cannot respond quickly to things - The '75 libraries' problem - Entrusting library maintenance to others and supporting them (e.g. the `event-stream` incident) From 66ca272fef3568f6ef09977d7e10fb401a48fd50 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 2 Mar 2019 15:47:59 -0800 Subject: [PATCH 031/133] Explain why a roadmap is lacking --- .../State-of-PureScript-Documentation-2019.md | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index b0533f1..76df38c 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -266,6 +266,38 @@ I (Jordan) don't know why it was taken down. Here's my speculation: Perhaps this idea could be revisited in the future. For now, we cannot say. +### No Clearly-Defined Mutually-Held Community-Wide Roadmap + +This is hard to do. Let's consider why: +- It's easy to disagree on what goals should be pursued +- It's easy to disagree on how to word such goals +- It's easy to do nothing and let someone else contribute + +Creating a "good" roadmap takes significant time and energy. + +PureScript does not currently have such a roadmap. Rather, core contributors seem to have a general direction they are pursuing. + +For example, `garyb` has stated that there are two features that he wants to add, but which will require breaking changes: poly-kinds and something that requires qualified constraints. ([The State of Things, 6th paragraph in his comment](https://discourse.purescript.org/t/the-state-of-things/282/5)) +It's not clear when these features will be added. + +Therefore: +- Those who could help do not know where help is needed +- Those who would help do not know how they can help + +#### Avoiding a `v1.0` PureScript language release + +When people announce "Language X is now '1.0!'", it tends to draw a lot of focus and a lot of traffic. People probably think, "Wow! It's now stable enough to be used to write all my programs." + +In reality, many would misunderstand a `v1.0` PureScript language release. They would likely understand it as a `v1.0` PureScript ecosystem. The language could be considered 'good enough' for a `v1.0`. However, the ecosystem is definitely not. + +What good is a `v1.0` language, if +- the dependency managers are still unfriendly to users? +- the IDE support is still lacking? +- common libraries haven't stabilized yet? +- the ecosystem is incoherent in a number of ways? + +Thus, core contributors might avoid defining a roadmap to prevent people from having a `v1.0` ecosystem connotation. + - Core Contributors are spread thin, so they cannot respond quickly to things From 71f01ad1f094e71205f4a1dbd8d13f32a7d78bd2 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 2 Mar 2019 15:48:52 -0800 Subject: [PATCH 032/133] Update summary of 'why lacking docs' section --- .../State-of-PureScript-Documentation-2019.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 76df38c..901e091 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -174,8 +174,7 @@ These are the reasons. Each wil be covered more in-depth following this: - PureScript is not _currently_ trying to be the next "mainstream language". - Core contributors are spread thin: limited time with too much responsibility -- Core contributors are prioritizing the addition of new powerful language features over other interests -- There is no clearly-defined mutually-held community-wide goal/vision that coordinates efforts +- There is no clearly-defined mutually-held community-wide roadmap that coordinates efforts - It's difficult to pin down and define what are Functional Programming's "best practices" - Questions answered on Slack do not persist, so they get re-asked and re-answered From 1831a73876179396084ce410b290d82d9627c43f Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 2 Mar 2019 15:58:49 -0800 Subject: [PATCH 033/133] Cleanup the roadmap section; address language specification separately --- .../State-of-PureScript-Documentation-2019.md | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 901e091..566dc72 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -270,14 +270,12 @@ Perhaps this idea could be revisited in the future. For now, we cannot say. This is hard to do. Let's consider why: - It's easy to disagree on what goals should be pursued - It's easy to disagree on how to word such goals +- It's easy to disagree on what to include and exclude - It's easy to do nothing and let someone else contribute Creating a "good" roadmap takes significant time and energy. -PureScript does not currently have such a roadmap. Rather, core contributors seem to have a general direction they are pursuing. - -For example, `garyb` has stated that there are two features that he wants to add, but which will require breaking changes: poly-kinds and something that requires qualified constraints. ([The State of Things, 6th paragraph in his comment](https://discourse.purescript.org/t/the-state-of-things/282/5)) -It's not clear when these features will be added. +PureScript does not currently have such a roadmap. Rather, core contributors seem to have a general direction they are pursuing (see next point). Therefore: - Those who could help do not know where help is needed @@ -297,16 +295,18 @@ What good is a `v1.0` language, if Thus, core contributors might avoid defining a roadmap to prevent people from having a `v1.0` ecosystem connotation. +#### Defining a Language Specification + +When should future breaking changes be done: before a `v1.0` or afterwards? + +`garyb`, a core contributor, has resisted efforts to define a language specification. Why? Because he wants to add two features that will require breaking changes: "poly-kinds and something that requires qualified constraints." ([The State of Things, 6th paragraph in his comment](https://discourse.purescript.org/t/the-state-of-things/282/5)) + +If done before a `v1.0`, then the language will likely be stable, documentation will not go out of date, and the ecosystem can flourish. + +If done after a `v1.0`, then many things will need to be updated, the language's reputation might suffer, and people might be forever turned off to it. + -- Core Contributors are spread thin, so they cannot respond quickly to things - - The '75 libraries' problem - - Entrusting library maintenance to others and supporting them (e.g. the `event-stream` incident) - - Just like reviewing code, reviewing documentation takes a lot of thought - - Hard to keep documentation momentum - - Which libraries are 'core libraries'? -- No clearly-defined mutually-held community-wide goal - - A desire to help exists, but no one is coordinating resources strategically - What exactly are FP's "Best Practices?" - They are not well-defined, are assumed, or are habits - Knowledge silos exist, so it's hard to extract that info From 6d7421c5c734b810e5bae707207c68cbeddbaab1 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 2 Mar 2019 16:14:06 -0800 Subject: [PATCH 034/133] Explain Slack issue and FP best practices issue --- .../State-of-PureScript-Documentation-2019.md | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 566dc72..5c13f2e 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -305,12 +305,20 @@ If done before a `v1.0`, then the language will likely be stable, documentation If done after a `v1.0`, then many things will need to be updated, the language's reputation might suffer, and people might be forever turned off to it. +### Slack-Based Questions and Answers Do Not Persist +Because the documentation is lacking, many are encouraged to ask their questions on the `#purescript` channel in the FP Slack. Many have greatly benefited from the quick answers they receive. -- What exactly are FP's "Best Practices?" - - They are not well-defined, are assumed, or are habits - - Knowledge silos exist, so it's hard to extract that info -- Slack-based discussions do not persist +However, these questions and their answers do not persist. After so much time, Slack will delete them. Thus, the same questions get re-answered + +### What Exactly are FP's "Best Practices" + +Coming from an Object-Oriented Paradigm, many have asked, "Why aren't the best practices / design patterns / idioms in Functional Programming explained/documented?" + +FP's "best practices" are +- hard to define +- things people assume everyone does (so why explain them?) +- unconscious habits ("Oh! I didn't realize this was a 'design pattern.'") ## New Learners: What is the Best Way to Learn PureScript? From e6380aaa87ebd3fa1434b7d3c058a7f123247cee Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Mon, 4 Mar 2019 19:15:41 -0800 Subject: [PATCH 035/133] Prevent possible misinterpretations of core contributors' quotes --- .../State-of-PureScript-Documentation-2019.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 5c13f2e..8df1288 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -217,8 +217,12 @@ If you value the same things that PureScript language developers value, then you > > In retrospect, I think it’s fair to say that I was quite thoroughly burned out from trying to balance open source work and real life. > +> I still love to _use_ PureScript, and I’ve been working to increase PureScript adoption at work.... +> > ~ Phil Freeman, the creator of the PureScript language [(1st & 2nd paragraph)](https://discourse.purescript.org/t/the-state-of-things/282) +The following quote is a response to another's "wallowing:" + > Just to wallow for a second, I... > - contribute to/review stuff on the compiler > - attempt to keep on top of the issues, discussions, PRs on roughly 75 libraries (some of which are tiny and almost never change, some of which are purescript-dom :grimacing:) From 1f535021a7cbe8549b79d5e57ceffa9a6cb55174 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Mon, 4 Mar 2019 19:17:15 -0800 Subject: [PATCH 036/133] Emphasize content's idea by no longer using adjectives --- .../State-of-PureScript-Documentation-2019.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 8df1288..2ef9f13 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -174,7 +174,7 @@ These are the reasons. Each wil be covered more in-depth following this: - PureScript is not _currently_ trying to be the next "mainstream language". - Core contributors are spread thin: limited time with too much responsibility -- There is no clearly-defined mutually-held community-wide roadmap that coordinates efforts +- There is no roadmap that coordinates efforts - It's difficult to pin down and define what are Functional Programming's "best practices" - Questions answered on Slack do not persist, so they get re-asked and re-answered @@ -269,7 +269,7 @@ I (Jordan) don't know why it was taken down. Here's my speculation: Perhaps this idea could be revisited in the future. For now, we cannot say. -### No Clearly-Defined Mutually-Held Community-Wide Roadmap +### There Is No Roadmap That Coordinates Efforts This is hard to do. Let's consider why: - It's easy to disagree on what goals should be pursued From 296ba0ee97d6d761b310ac3fbb707519c9b56163 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Mon, 4 Mar 2019 19:20:00 -0800 Subject: [PATCH 037/133] Explain `v1.0` ecosystem problem using less words --- .../State-of-PureScript-Documentation-2019.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 2ef9f13..2eed9c6 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -287,9 +287,9 @@ Therefore: #### Avoiding a `v1.0` PureScript language release -When people announce "Language X is now '1.0!'", it tends to draw a lot of focus and a lot of traffic. People probably think, "Wow! It's now stable enough to be used to write all my programs." +When people announce "Language X is now `1.0`!", it tends to draw a lot of focus and a lot of traffic. People probably think, "Wow! It's now stable enough to be used to write all my programs." -In reality, many would misunderstand a `v1.0` PureScript language release. They would likely understand it as a `v1.0` PureScript ecosystem. The language could be considered 'good enough' for a `v1.0`. However, the ecosystem is definitely not. +In short, one core contributor believes that many would perceive a `v1.0` release as a `v1.0` ecossytem release. The language could be considered 'good enough' for a `v1.0`. However, the ecosystem is definitely not. What good is a `v1.0` language, if - the dependency managers are still unfriendly to users? From bbdeab8e989704ccf32d86dbe2cdafbd88e84795 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Mon, 4 Mar 2019 19:24:02 -0800 Subject: [PATCH 038/133] Reword explanation on why a roadmap is hard to define --- .../State-of-PureScript-Documentation-2019.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 2eed9c6..8bee487 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -271,11 +271,10 @@ Perhaps this idea could be revisited in the future. For now, we cannot say. ### There Is No Roadmap That Coordinates Efforts -This is hard to do. Let's consider why: -- It's easy to disagree on what goals should be pursued -- It's easy to disagree on how to word such goals -- It's easy to disagree on what to include and exclude -- It's easy to do nothing and let someone else contribute +Defining a roadmap is hard. It's easy to... +- ...disagree on which goals should be pursued and which to ignore +- ...disagree on how to word such goals +- ...do nothing and let someone else contribute Creating a "good" roadmap takes significant time and energy. From 166524de11a41063f40d1efc6c3dedbe98c5284f Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Mon, 4 Mar 2019 19:54:47 -0800 Subject: [PATCH 039/133] Add a few questions for core contributors to answer --- .../State-of-PureScript-Documentation-2019.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 88f654e..89782b6 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -22,7 +22,7 @@ Outline - Address various audience's possible concerns or questions centered on these themes: - New learners - How should I learn PureScript? - PureScript documentation writers - How should I write good maintainable documentation for others? - - Core Contributors - + - Core Contributors - ## What is "Good" Documentation Anyway? @@ -197,6 +197,12 @@ Here's what has been added to the above since then: ## Core Contributors: ??? +- What can the community do to encourage/support you in 2019? +- What are your general goals for the langauge/ecosystem in 2019? +- What kind of help do you want from the community in 2019 (e.g. maintainership, documentation, conbtributions, etc.)? +- What kind of help do you not want from the community in 2019 (e.g. maintainership, documentation, conbtributions, etc.)? +- How much support are you willing to provide and in what form? + The following - Evaluate PureScript's documentation using that criteria - Explain why PureScript's documentation is lacking and what is being done to improve it From 16c6fb00b4b2f5b1829e3c5c45db7e1468a97758 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Tue, 5 Mar 2019 18:18:31 -0800 Subject: [PATCH 040/133] Ask core contributors for non-goals for 2019 --- .../State-of-PureScript-Documentation-2019.md | 1 + 1 file changed, 1 insertion(+) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 89782b6..356b56a 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -199,6 +199,7 @@ Here's what has been added to the above since then: - What can the community do to encourage/support you in 2019? - What are your general goals for the langauge/ecosystem in 2019? +- What are not your goals for the langauge/ecosystem in 2019? (i.e. things you know need additional work, but just don't have a high enough priority right now) - What kind of help do you want from the community in 2019 (e.g. maintainership, documentation, conbtributions, etc.)? - What kind of help do you not want from the community in 2019 (e.g. maintainership, documentation, conbtributions, etc.)? - How much support are you willing to provide and in what form? From a0799b513dc756e22b359eec3c8dbfde9b845ff4 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Tue, 5 Mar 2019 18:23:35 -0800 Subject: [PATCH 041/133] Convert questions into copy-and-pasteable format for conveniency --- .../State-of-PureScript-Documentation-2019.md | 35 +++++++++++++++---- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 356b56a..568f1d5 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -197,12 +197,35 @@ Here's what has been added to the above since then: ## Core Contributors: ??? -- What can the community do to encourage/support you in 2019? -- What are your general goals for the langauge/ecosystem in 2019? -- What are not your goals for the langauge/ecosystem in 2019? (i.e. things you know need additional work, but just don't have a high enough priority right now) -- What kind of help do you want from the community in 2019 (e.g. maintainership, documentation, conbtributions, etc.)? -- What kind of help do you not want from the community in 2019 (e.g. maintainership, documentation, conbtributions, etc.)? -- How much support are you willing to provide and in what form? +Please answer the below questions. + +To help with consistency, copy the below questions and paste them into your comment box. Then, give a reply. +``` +> What can the community do to encourage/support you in 2019? + + + +> What are your general goals for the langauge/ecosystem in 2019? + + + +> What are not your goals for the langauge/ecosystem in 2019? (i.e. things you know need additional work, but just don't have a high enough priority right now) + + + +> What kind of help do you want from the community in 2019 (e.g. maintainership, documentation, conbtributions, etc.)? + + + +> What kind of help do you not want from the community in 2019 (e.g. maintainership, documentation, conbtributions, etc.)? + + + +> How much support are you willing to provide and in what form? + +``` + + The following - Evaluate PureScript's documentation using that criteria From e9f6e21151e0c3a21c0f955517f23ad12771afce Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Tue, 5 Mar 2019 18:24:29 -0800 Subject: [PATCH 042/133] Fix spelling errors --- .../State-of-PureScript-Documentation-2019.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 568f1d5..e0dc6ad 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -205,11 +205,11 @@ To help with consistency, copy the below questions and paste them into your comm -> What are your general goals for the langauge/ecosystem in 2019? +> What are your general goals for the language/ecosystem in 2019? -> What are not your goals for the langauge/ecosystem in 2019? (i.e. things you know need additional work, but just don't have a high enough priority right now) +> What are not your goals for the language/ecosystem in 2019? (i.e. things you know need additional work, but just don't have a high enough priority right now) From 7d076c85f2593bca814adaabb5616c99c37fd4d8 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Tue, 5 Mar 2019 18:24:51 -0800 Subject: [PATCH 043/133] Clarify who gets potential core contributor support --- .../State-of-PureScript-Documentation-2019.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index e0dc6ad..30a00f5 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -221,7 +221,7 @@ To help with consistency, copy the below questions and paste them into your comm -> How much support are you willing to provide and in what form? +> How much support are you willing to provide to those who want to help and in what form? ``` From 1d62632caeba7ca8f456981a69d301e8defaf783 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Tue, 5 Mar 2019 18:54:06 -0800 Subject: [PATCH 044/133] Document learning paths to PureScript visually --- .../State-of-PureScript-Documentation-2019.md | 6 +- .../learner-paths-to-ps.graphml | 314 ++++++++++++++++++ .../learner-paths-to-ps.png | Bin 0 -> 55358 bytes 3 files changed, 319 insertions(+), 1 deletion(-) create mode 100644 02-Context-or-Narrative/learner-paths-to-ps.graphml create mode 100644 02-Context-or-Narrative/learner-paths-to-ps.png diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 88f654e..a449f80 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -22,7 +22,7 @@ Outline - Address various audience's possible concerns or questions centered on these themes: - New learners - How should I learn PureScript? - PureScript documentation writers - How should I write good maintainable documentation for others? - - Core Contributors - + - Core Contributors - ## What is "Good" Documentation Anyway? @@ -193,6 +193,10 @@ Here's what has been added to the above since then: ## New Learners: What is the Best Way to Learn PureScript? +There are likely other learning paths besides the ones covered below, but here's what we found in our research: + +![Learner Paths "Learner Paths"](./learner-paths-to-ps.png) + ## PureScript Documentation Writers: What is the Best Way to Write Documentation in this Context? ## Core Contributors: ??? diff --git a/02-Context-or-Narrative/learner-paths-to-ps.graphml b/02-Context-or-Narrative/learner-paths-to-ps.graphml new file mode 100644 index 0000000..93e740e --- /dev/null +++ b/02-Context-or-Narrative/learner-paths-to-ps.graphml @@ -0,0 +1,314 @@ + + + + + + + + + + + + + + + + + + + + + + + + PureScript + + + + + + + + + + + + + + + + + + Haskell + + + + + + + + + + + + + + + + + + JavaScript + + + + + + + + + + + + + + + + + + Elm + + + + + + + + + + + + + + + + + + + + + Legend + + + + + + + + + + + Folder 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Minor readjustments: +- Functions renamed +- Granular type system + +Major readjustments: +- Lazy -> Strict +- Lose some language features +- NPM and JS ecosystem + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Learn it all at once +and fight against +OO baggage + +Data +- Algebraic Data Types +- Immutable data structures +- Zippers +- Lenses + +Functions +- Recursion & Tail-Call Optimization +- Stack-Safety / Stack Overflows +- Pure functions distinguished from Impure functions +- Curried/Uncurried Functions + +Types +- Polymorphism +- Higher-Kinded Types +- Phantom Types +- Type Classes +- Functional Dependencies +- Type-Level Programming +- Compiler errors + +Control Flow +- Functors, Applicatives, and Monads +- Monad Transformers and Free + +Effects +- Native effects +- Capabilities / side-effects +- No effects + + + + + + + + + + + + + + + + + + + Shorter arrows = easier learning paths + +Longer arrows = harder learning paths + + + + + + + + + + + + + + + + + + + Learn a subset of FP concepts +unconsciously with great +documentation and clear +compiler error messages + + + + + + + + + + + + + + + + + + + Learn FP concepts consciously, +building on a good foundation + + + + + + + + + + + + + + + + diff --git a/02-Context-or-Narrative/learner-paths-to-ps.png b/02-Context-or-Narrative/learner-paths-to-ps.png new file mode 100644 index 0000000000000000000000000000000000000000..0c807ff4be1667f0487123ddd73070112c4db4b6 GIT binary patch literal 55358 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 literal 0 HcmV?d00001 From 47836aa3c59fbf4247dc711f65749f6f1ec1eac9 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Tue, 5 Mar 2019 18:57:27 -0800 Subject: [PATCH 045/133] Add initial table of helpful learning resources --- .../State-of-PureScript-Documentation-2019.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index a449f80..69db5bb 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -197,6 +197,12 @@ There are likely other learning paths besides the ones covered below, but here's ![Learner Paths "Learner Paths"](./learner-paths-to-ps.png) +| If your language background is... | ... then try these learning resources... | ... and these PureScript libraries | +| -- | -- | -- | +| JavaScript / OO languages | [Make the Leap from JavaScript to PureScript (Tutorial Series)](https://medium.com/@kelleyalex/index-make-the-leap-from-javascript-to-purescript-a1566d657e9c)

[An Outsider's Guide to Statically Typed Functional Programming (Book)](https://leanpub.com/outsidefp)

[Haskell: From First Principles](http://haskellbook.com/) | -- +| Elm | [An Outsider's Guide to Statically Typed Functional Programming (Book)](https://leanpub.com/outsidefp) | -- +| Haskell | [Introduction to PureScript (PDF)](http://code.adriansieber.com/adrian/adriansieber-com/src/branch/master/posts/_2018-11-01_introduction_to_purescript_for_haskell_developers/main.pdf)

[Differences from Haskell](https://github.com/purescript/documentation/blob/master/language/Differences-from-Haskell.md) | -- + ## PureScript Documentation Writers: What is the Best Way to Write Documentation in this Context? ## Core Contributors: ??? From 2fe4e61383d40ba4edd179373ef2be9569da8355 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Tue, 5 Mar 2019 19:05:14 -0800 Subject: [PATCH 046/133] Rework learning paths to remove FP concepts from JS->PS path description --- .../learner-paths-to-ps.graphml | 211 +++++++++++++----- .../learner-paths-to-ps.png | Bin 55358 -> 46993 bytes 2 files changed, 156 insertions(+), 55 deletions(-) diff --git a/02-Context-or-Narrative/learner-paths-to-ps.graphml b/02-Context-or-Narrative/learner-paths-to-ps.graphml index 93e740e..5a51b6b 100644 --- a/02-Context-or-Narrative/learner-paths-to-ps.graphml +++ b/02-Context-or-Narrative/learner-paths-to-ps.graphml @@ -15,7 +15,6 @@ - @@ -33,10 +32,9 @@ - - + Haskell @@ -51,7 +49,6 @@ - @@ -69,7 +66,6 @@ - @@ -88,20 +84,19 @@ - - + - Legend + Legend - + @@ -118,10 +113,9 @@ - - + @@ -137,10 +131,9 @@ - - + @@ -157,14 +150,156 @@ + + + + + + + + + + + Core FP Concepts + + + + + + + + + + + Folder 2 + + + + + + + + + + + + + + + + + Control Flow +- Functors, Applicatives, and Monads +- Monad Transformers and Free + + + + + + + + + + + + + + + + + + Data +- Algebraic Data Types +- Immutable data +- Zippers +- Lenses + + + + + + + + + + + + + + + + + + Functions +- Recursion & Tail-Call Optimization +- Stack-Safety / Stack Overflows +- Pure vs Impure Functions +- Curried/Uncurried Functions + + + + + + + + + + + + + + + + + + Types +- Polymorphism +- Higher-Kinded Types +- Phantom Types +- Type Classes +- Functional Dependencies +- Type-Level Programming +- Compiler errors + + + + + + + + + + + + + + + + + + Effects +- Native effects +- Capabilities / side-effects +- No effects + + + + + + + + + + + + - - Minor readjustments: + Minor readjustments: - Functions renamed - Granular type system @@ -175,7 +310,7 @@ Major readjustments: - + @@ -184,7 +319,6 @@ Major readjustments: - @@ -200,43 +334,13 @@ Major readjustments: - Learn it all at once + Learn it all at once and fight against -OO baggage - -Data -- Algebraic Data Types -- Immutable data structures -- Zippers -- Lenses - -Functions -- Recursion & Tail-Call Optimization -- Stack-Safety / Stack Overflows -- Pure functions distinguished from Impure functions -- Curried/Uncurried Functions - -Types -- Polymorphism -- Higher-Kinded Types -- Phantom Types -- Type Classes -- Functional Dependencies -- Type-Level Programming -- Compiler errors - -Control Flow -- Functors, Applicatives, and Monads -- Monad Transformers and Free - -Effects -- Native effects -- Capabilities / side-effects -- No effects +OO baggage - + @@ -245,19 +349,18 @@ Effects - - Shorter arrows = easier learning paths + Shorter arrows = easier learning paths Longer arrows = harder learning paths - + @@ -266,7 +369,6 @@ Longer arrows = harder learning paths - @@ -288,7 +390,6 @@ compiler error messages - diff --git a/02-Context-or-Narrative/learner-paths-to-ps.png b/02-Context-or-Narrative/learner-paths-to-ps.png index 0c807ff4be1667f0487123ddd73070112c4db4b6..0466db04365e40b152b562cb92d55fe761980b6f 100644 GIT binary patch literal 46993 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 From 985edd31fb90200c6f1b9b7bd0e8a9d54a1e3d29 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Wed, 6 Mar 2019 11:14:24 -0800 Subject: [PATCH 047/133] Remove redundancy on header: core contribs spread thin --- .../State-of-PureScript-Documentation-2019.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 8bee487..63c7925 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -173,7 +173,7 @@ Here's what has been added to the above since then: These are the reasons. Each wil be covered more in-depth following this: - PureScript is not _currently_ trying to be the next "mainstream language". -- Core contributors are spread thin: limited time with too much responsibility +- Core contributors are spread thin - There is no roadmap that coordinates efforts - It's difficult to pin down and define what are Functional Programming's "best practices" - Questions answered on Slack do not persist, so they get re-asked and re-answered @@ -211,7 +211,7 @@ Programming exists to solve problems. It's not about proving whether you are cle If you value the same things that PureScript language developers value, then you are right at home. -### Core contributors are spread thin: limited time with too much responsibility +### Core contributors are spread thin > It’s been 7 months since I announced that I would be taking a long break from PureScript development.... > From 8e78c18b03a8fe498d77f9136d786475dd3c8ff2 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Wed, 6 Mar 2019 11:55:09 -0800 Subject: [PATCH 048/133] Rewrite 'not the next mainstream language' section --- .../State-of-PureScript-Documentation-2019.md | 41 ++++++++----------- 1 file changed, 16 insertions(+), 25 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 63c7925..7b7b04e 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -180,36 +180,27 @@ These are the reasons. Each wil be covered more in-depth following this: ### PureScript is not _currently_ trying to be the next "mainstream language" -Many have wrongly assumed that PureScript is trying to replace [insert your favorite web language here]. That is not the case. Each language has its trade-offs that make it better for some and worse for others. +Many have wrongly assumed that PureScript is trying to replace [insert your favorite web language here]. That is not the case. -Rather, PureScript is _currently_ following the motto of "**avoid (success at all costs)**". +In short, PureScript might not be the language for you. -#### The Wrong Interpretation of 'Avoid (success at all costs)' - -One might understand 'avoid (success at all costs)' as "We don't want to be 'successful.' We don't want everyone to use this language. Therefore, let's make it hard and impractical for people to learn and use this language." - -New learners have likely said or thought, "Stupid language developers! Why didn't they make it easier to learn how to use this language and its abstractions? I thought this was a 'better' language." - -This interpretation is flawed because it focuses on the _wrong core values_: low learning curve and ease of use. PureScript's language developers do value these things, but they value other things more. - -#### The Right Interpretation of 'Avoid (success at all costs)' - -To understand this motto, one must understand the core value behind it: productivity: -- Using the right abstractions is more productive than using a workaround/hack because of a language deficiency. -- Languages that nag at you to write well-structured programs are more productive than those that don't. -- Fixing bugs before shipping is more productive than fixing bugs after shipping (e.g. trading runtime errors for compiler errors) -- Painless refactoring is more productive when reducing technical debt than painful refactoring. -- Creating solutions that "just work" is more productive than solutions that "should work." - -In short, all languages make compromises based on which core values they value more than others. PureScript "bought" power and productivity at the "price" of a higher learning curve and lower ease of use. Other languages made a different "purchase." - -This leaves one conclusion: PureScript might not be the language for you. +PureScript has the following philosophy: +> Making a language "successful" (e.g. popular, industry-standard, taught in universities' curriculums, etc.) is not a justification for paying for "costs" that ruin the language, such as limiting the language's expressiveness, making it less safe, less secure, etc. +> +> Making the language easier to use and learn by improving it is good and supported. +> Making the language easier to use and learn by crippling, downgrading, or dumbing down the language is rejected. Users will either learn it properly or use something else. +> +> Plenty of languages chose to sacrifice safety, security, efficiency, etc. to gain the benefits of "success." +> +> PureScript will not be another such language. Rather, it will try to progress in "the right way," even when it's inconvenient, makes it harder to learn, etc. +> +> ~ Summary of [A Response that Explains the Motto: 'Avoid (Success at All Costs)'](https://news.ycombinator.com/item?id=12056169) (edits made: replaced 'Haskell' with 'PureScript'; removed "research-related concepts") -If you can accomplish your goals using a language that "fits" you better than PureScript, why use PureScript? +This philosophy is summarized as "avoid (success at all costs)" -Programming exists to solve problems. It's not about proving whether you are clever and disciplined enough to learn something hard. Go use that language instead, and come back if you change your mind. +If you value 'success' over 'costs,' use a different language. -If you value the same things that PureScript language developers value, then you are right at home. +If you value 'costs' over 'success', use this language. ### Core contributors are spread thin From b75fa4505810230d475b7f8e987fb8159e7ad572 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Wed, 6 Mar 2019 13:07:34 -0800 Subject: [PATCH 049/133] Include question about automating some of the maintenance work --- .../State-of-PureScript-Documentation-2019.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 30a00f5..0d0d81e 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -213,6 +213,10 @@ To help with consistency, copy the below questions and paste them into your comm +> What processes that are not automated could be automated to save you time / lower the maintenance cost? + + + > What kind of help do you want from the community in 2019 (e.g. maintainership, documentation, conbtributions, etc.)? From 251e745c9073515ff979531add0d52297ab9b100 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Wed, 6 Mar 2019 13:16:51 -0800 Subject: [PATCH 050/133] Change 'many' to 'few'; briefly explain docs aren't current focus --- .../State-of-PureScript-Documentation-2019.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 7b7b04e..f18bdd7 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -180,9 +180,7 @@ These are the reasons. Each wil be covered more in-depth following this: ### PureScript is not _currently_ trying to be the next "mainstream language" -Many have wrongly assumed that PureScript is trying to replace [insert your favorite web language here]. That is not the case. - -In short, PureScript might not be the language for you. +A few have wrongly assumed that PureScript is trying to replace [insert your favorite web language here]. That is not the case. PureScript has the following philosophy: > Making a language "successful" (e.g. popular, industry-standard, taught in universities' curriculums, etc.) is not a justification for paying for "costs" that ruin the language, such as limiting the language's expressiveness, making it less safe, less secure, etc. @@ -196,11 +194,13 @@ PureScript has the following philosophy: > > ~ Summary of [A Response that Explains the Motto: 'Avoid (Success at All Costs)'](https://news.ycombinator.com/item?id=12056169) (edits made: replaced 'Haskell' with 'PureScript'; removed "research-related concepts") -This philosophy is summarized as "avoid (success at all costs)" +This philosophy is summarized as "avoid (success at all costs)." -If you value 'success' over 'costs,' use a different language. +The current focus (see later point) is not on making documentation great. Rather, it's on implementing the language features that haven't yet been implemented. -If you value 'costs' over 'success', use this language. +Thus, PureScript might not be the language for you: +- If you value 'success' over 'costs,' use a different language. +- If you value 'costs' over 'success' and are determined to learn hard things, use this language. ### Core contributors are spread thin From 32fc63e8bf591082fc874418b923ba8f32c84bb3 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Wed, 6 Mar 2019 13:26:10 -0800 Subject: [PATCH 051/133] Make momentum the focus of issue --- .../State-of-PureScript-Documentation-2019.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index f18bdd7..e35064c 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -224,9 +224,12 @@ The following quote is a response to another's "wallowing:" > > ~ a core contributor ([2nd paragraph](https://gist.github.com/marick/e8b01375309fafaefb879c4840b6da75#gistcomment-2569261), edits made: content was turned into a list; "..." changed to "," for readability) -As a result, documentation PRs are either forgotten or reviewed long after their initial submission. It's quite difficult to maintain momentum in such a context. +Reviewing documentation can be just as difficult as reviewing code. Some people are faster at reviewing things than others. -Finally, reviewing documentation can be just as difficult as reviewing code. Some people are faster at reviewing things than others. +Thus, maintaining momentum when documenting code is difficult: +- Some documentation PRs are missed/forgotten. +- Many do not get a timely response from core contributors (one may wait for weeks) +- Most tend to get merged a week or more after their initial submissions. #### Why Not Just Delegate? From 118e06c5ebcf055e8646f791b801fea15662051a Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Wed, 6 Mar 2019 13:26:54 -0800 Subject: [PATCH 052/133] Fix typo --- .../State-of-PureScript-Documentation-2019.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index e35064c..2c53412 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -282,7 +282,7 @@ Therefore: When people announce "Language X is now `1.0`!", it tends to draw a lot of focus and a lot of traffic. People probably think, "Wow! It's now stable enough to be used to write all my programs." -In short, one core contributor believes that many would perceive a `v1.0` release as a `v1.0` ecossytem release. The language could be considered 'good enough' for a `v1.0`. However, the ecosystem is definitely not. +In short, one core contributor believes that many would perceive a `v1.0` release as a `v1.0` ecosystem release. The language could be considered 'good enough' for a `v1.0`. However, the ecosystem is definitely not. What good is a `v1.0` language, if - the dependency managers are still unfriendly to users? From 85fbfddca3cb0b72da36e3864ec4611f792bfff9 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Wed, 6 Mar 2019 13:28:01 -0800 Subject: [PATCH 053/133] Reorder points explaining v1.0 ecosystem issues; expand one one point --- .../State-of-PureScript-Documentation-2019.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 2c53412..2669331 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -285,10 +285,10 @@ When people announce "Language X is now `1.0`!", it tends to draw a lot of focus In short, one core contributor believes that many would perceive a `v1.0` release as a `v1.0` ecosystem release. The language could be considered 'good enough' for a `v1.0`. However, the ecosystem is definitely not. What good is a `v1.0` language, if +- common libraries haven't stabilized yet or are non-existant? +- the ecosystem is incoherent in a number of ways? - the dependency managers are still unfriendly to users? - the IDE support is still lacking? -- common libraries haven't stabilized yet? -- the ecosystem is incoherent in a number of ways? Thus, core contributors might avoid defining a roadmap to prevent people from having a `v1.0` ecosystem connotation. From 370e9f2a0c14b71bf120eade36180f14b7d97af9 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Wed, 6 Mar 2019 13:41:02 -0800 Subject: [PATCH 054/133] Add breaking changes as another reason for why docs are lacking --- .../State-of-PureScript-Documentation-2019.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 2669331..f6b0cdf 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -174,6 +174,7 @@ These are the reasons. Each wil be covered more in-depth following this: - PureScript is not _currently_ trying to be the next "mainstream language". - Core contributors are spread thin +- Breaking changes outdate documentation and kill documenters' motivation - There is no roadmap that coordinates efforts - It's difficult to pin down and define what are Functional Programming's "best practices" - Questions answered on Slack do not persist, so they get re-asked and re-answered @@ -263,6 +264,18 @@ I (Jordan) don't know why it was taken down. Here's my speculation: Perhaps this idea could be revisited in the future. For now, we cannot say. +### Breaking Changes Outdate Documentation and Kill Documenters' Motivation + +The main 'go-to' documentation resource for PureScript was/is [PureScript By Example](https://leanpub.com/purescript/) by Phil Freeman. This resource documents the `0.11.7` PureScript release. The current PureScript release is `0.12.3` (as of this writing). + +The `0.12.0` was a significant achievement but one that came with a lot of breaking changes. Phil responded to it in this way: + +> [The PureScript by Example book] seems to take longer [to update] with each major compiler update, and honestly, I’m not motivated to update it again without some sort of guarantee that I won’t have to redo everything again in a few months.... +> I would like to write a lot more documentation for PureScript, but I hate the idea that it will become out of date quickly.... +> So without some sort of plan for the future of the language, and some idea of what changes are coming (and just as importantly, which aren’t), I’m not likely to write anything, and I wouldn’t be surprised if others avoided writing for the same reason. +> +> ~ Phil Freeman [The State of Things, point 4](https://discourse.purescript.org/t/the-state-of-things/282) + ### There Is No Roadmap That Coordinates Efforts Defining a roadmap is hard. It's easy to... From 0bfb50f15e501b0bfcaa14cf8d4a87317ddadaac Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Wed, 6 Mar 2019 13:42:23 -0800 Subject: [PATCH 055/133] Convert 'things' to 'libraries and docs' --- .../State-of-PureScript-Documentation-2019.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index f6b0cdf..9b1f82f 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -313,7 +313,7 @@ When should future breaking changes be done: before a `v1.0` or afterwards? If done before a `v1.0`, then the language will likely be stable, documentation will not go out of date, and the ecosystem can flourish. -If done after a `v1.0`, then many things will need to be updated, the language's reputation might suffer, and people might be forever turned off to it. +If done after a `v1.0`, then many libraries and docs will need to be updated, the language's reputation might suffer, and people might be forever turned off to it. ### Slack-Based Questions and Answers Do Not Persist From b1e180640363049af0d44b91552db1a74ac0218d Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 8 Mar 2019 20:41:49 -0800 Subject: [PATCH 056/133] Include note about automation possibly helping; cite interpretations --- .../State-of-PureScript-Documentation-2019.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 9b1f82f..e9a7424 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -225,6 +225,8 @@ The following quote is a response to another's "wallowing:" > > ~ a core contributor ([2nd paragraph](https://gist.github.com/marick/e8b01375309fafaefb879c4840b6da75#gistcomment-2569261), edits made: content was turned into a list; "..." changed to "," for readability) +I (Jordan) don't know whether automating some tasks could be done and whether it would help. + Reviewing documentation can be just as difficult as reviewing code. Some people are faster at reviewing things than others. Thus, maintaining momentum when documenting code is difficult: @@ -232,6 +234,8 @@ Thus, maintaining momentum when documenting code is difficult: - Many do not get a timely response from core contributors (one may wait for weeks) - Most tend to get merged a week or more after their initial submissions. +(Related interpretation sections: [Limited Manpower / Not Enough Automation](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#limited-manpower--not-enough-automation), [Slow submitted-reviewed-merged timeline of documentation kills momentum](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#slow-submitted-reviewed-merged-timeline-of-documentation-prs-kills-documentation-momentum), [Reviewing documentation PRS can be just as difficult as code PRs](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#reviewing-documentation-prs-can-be-just-as-difficult-as-code-prs)) + #### Why Not Just Delegate? > A hypothetical developer says, "If it's so much work, why not just **delegate** the work? This 'somebody' can also be a proxy who's gathering feedback, so that you don't have to be in these discussions." From 3d0bc5e9c7a259563335da2dde84fed025303d8c Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 8 Mar 2019 20:44:29 -0800 Subject: [PATCH 057/133] Focus on unchanging fact that learning FP will always be difficult --- .../State-of-PureScript-Documentation-2019.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index e9a7424..a235c6d 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -199,6 +199,8 @@ This philosophy is summarized as "avoid (success at all costs)." The current focus (see later point) is not on making documentation great. Rather, it's on implementing the language features that haven't yet been implemented. +However, even if great documentation was the focus, one will still have to learn difficult concepts before they can be productive. This fact will never change. + Thus, PureScript might not be the language for you: - If you value 'success' over 'costs,' use a different language. - If you value 'costs' over 'success' and are determined to learn hard things, use this language. From 05f406c20f73f3ef70676ebcdc9f07886c9a48ab Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 8 Mar 2019 20:45:48 -0800 Subject: [PATCH 058/133] Cite 'knowing whom to trust / supporting maintainers' section --- .../State-of-PureScript-Documentation-2019.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index a235c6d..146062c 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -260,6 +260,8 @@ For example, consider the `event-stream incident`. The maintainer unknowingly ga Finally, new maintainers, once found, have to be supported (which takes time and thought), so that they can actually fulfill their role. If they decide to leave soon after starting, then one has wasted time and effort. +(Related interpretations sections: [Knwoing whom to trust with write access, defining best workflow procedures, and providing necessary support](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#knowing-whom-to-trust-with-write-access-defining-best-workflow-procedures-and-providing-necessary-support)) + #### Why Not Just Fund the Language Developers? Been there, done that. Someone took it down. ([PureScript Open Collective]((https://opencollective.com/purescript)) From b3fb96da78558f746c94c1fc1a03d7f51c71ec99 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 8 Mar 2019 20:47:00 -0800 Subject: [PATCH 059/133] Cite 'brekaing changes outdates docs' section --- .../State-of-PureScript-Documentation-2019.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 146062c..6d6a600 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -284,6 +284,8 @@ The `0.12.0` was a significant achievement but one that came with a lot of break > > ~ Phil Freeman [The State of Things, point 4](https://discourse.purescript.org/t/the-state-of-things/282) +(Related interpretation sections: [Breaking Changes Render Documentation Outdated](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#knowing-whom-to-trust-with-write-access-defining-best-workflow-procedures-and-providing-necessary-support)) + ### There Is No Roadmap That Coordinates Efforts Defining a roadmap is hard. It's easy to... From 5176cdd7ac67d6f17a85d647a1d4a30726e96d0b Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 8 Mar 2019 20:47:30 -0800 Subject: [PATCH 060/133] Fix typos --- .../State-of-PureScript-Documentation-2019.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 6d6a600..54fd763 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -260,7 +260,7 @@ For example, consider the `event-stream incident`. The maintainer unknowingly ga Finally, new maintainers, once found, have to be supported (which takes time and thought), so that they can actually fulfill their role. If they decide to leave soon after starting, then one has wasted time and effort. -(Related interpretations sections: [Knwoing whom to trust with write access, defining best workflow procedures, and providing necessary support](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#knowing-whom-to-trust-with-write-access-defining-best-workflow-procedures-and-providing-necessary-support)) +(Related interpretation sections: [Knowing whom to trust with write access, defining best workflow procedures, and providing necessary support](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#knowing-whom-to-trust-with-write-access-defining-best-workflow-procedures-and-providing-necessary-support)) #### Why Not Just Fund the Language Developers? From 7560940daae13950e389e749171e4cb75326850d Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 8 Mar 2019 20:49:43 -0800 Subject: [PATCH 061/133] Cite "why a v1.0 hasn't been made yet" sources --- .../State-of-PureScript-Documentation-2019.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 54fd763..ee60d17 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -325,6 +325,8 @@ If done before a `v1.0`, then the language will likely be stable, documentation If done after a `v1.0`, then many libraries and docs will need to be updated, the language's reputation might suffer, and people might be forever turned off to it. +(Related interpretation sections: [Lack of a clearly-defined communit-wide mutually-held vision/goal](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#knowing-whom-to-trust-with-write-access-defining-best-workflow-procedures-and-providing-necessary-support), [Lack of a clearly-defined core-contributor-wide mutually-held language specification](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#knowing-whom-to-trust-with-write-access-defining-best-workflow-procedures-and-providing-necessary-support), [Fear that people will misinterpret at "v1.0" compiler release for a "v1.0" ecosystem release](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#knowing-whom-to-trust-with-write-access-defining-best-workflow-procedures-and-providing-necessary-support)) + ### Slack-Based Questions and Answers Do Not Persist Because the documentation is lacking, many are encouraged to ask their questions on the `#purescript` channel in the FP Slack. Many have greatly benefited from the quick answers they receive. From 87bd948806aa01ce430eb1f7ee2fb3273ec86c90 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 8 Mar 2019 20:50:53 -0800 Subject: [PATCH 062/133] Cite 'avoid success at all costs' meaning section --- .../State-of-PureScript-Documentation-2019.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index ee60d17..c9d3618 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -205,6 +205,8 @@ Thus, PureScript might not be the language for you: - If you value 'success' over 'costs,' use a different language. - If you value 'costs' over 'success' and are determined to learn hard things, use this language. +(Related interpretation sections: [Keeping the motto of `Avoid "success at all costs"` and understanding its meaning](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#knowing-whom-to-trust-with-write-access-defining-best-workflow-procedures-and-providing-necessary-support)) + ### Core contributors are spread thin > It’s been 7 months since I announced that I would be taking a long break from PureScript development.... From 25a9c96d3db6b66a6297c2a2ec1cef7023be712e Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 8 Mar 2019 21:35:56 -0800 Subject: [PATCH 063/133] Write a summary to 'why docs are lacking'; address Slack issue more --- .../State-of-PureScript-Documentation-2019.md | 36 ++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index c9d3618..6977ab0 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -333,7 +333,16 @@ If done after a `v1.0`, then many libraries and docs will need to be updated, th Because the documentation is lacking, many are encouraged to ask their questions on the `#purescript` channel in the FP Slack. Many have greatly benefited from the quick answers they receive. -However, these questions and their answers do not persist. After so much time, Slack will delete them. Thus, the same questions get re-answered +There are two issues with this approach: +1. Such answers cannot be easily found because they are hidden in a chatroom's length conversation. +2. These questions and their answers do not persist. After so much time, Slack will delete them. + +Thus, people with the same already-answered questions can't find their answers. They ask the same questions and receive the same answers. This takes time away from other contributors and developers. + +@chexxor has made some effort to address these issues by cross-posting such discussions in the Discourse forum. This accounts for the second issue. + +However, the format is poor. One must read through a (sometimes) lengthy conversation to find the answer. +Contrast that with an SO question and answer that appears in a Google search. ### What Exactly are FP's "Best Practices" @@ -344,6 +353,31 @@ FP's "best practices" are - things people assume everyone does (so why explain them?) - unconscious habits ("Oh! I didn't realize this was a 'design pattern.'") +### Summary + +Because core contributors are spread thin, they cannot respond quickly to people's questions or thoughts. With the small amount of time they do have, they are focusing on adding new language features, not improving the documentation situation. The language's development is steady (6-week release cycle) but slow. + +Unfortunately, these language features entail breaking changes. So, those who want to improve the documentation situation are discouraged from improving it. Why invest many hours into something that will be outdated in a few months? Why not invest those hours into something else, like an interesting project or learning something new? + +The longer the core contributors take to implement these breaking changes, the longer such documentation writers will wait, and the longer we'll be in this situation. This is not to blame the core contributors. They're doing great and their pace is just fine. It's only stating the reality of our situation. + +But, there is hope. + +People are making an assumption that has not been tested. **Are all documentation efforts always affected by a breaking change?** I doubt it. Certainly there are some things that need better documentation which won't be affected by breaking changes. Why not identify what those are and start improving them? + +Such efforts will likely need to be "unofficial." We do not want to steal time away from the core contributors by distracting them with documentation PRs. Let them focus on the language's development. Stabilizing the language sooner means an improved documentation situation sooner. + +Rather, we can focus on answering questions like these: +- What are the libraries that need to have their documentation improved? + - If documented, will breaking changes outdate such documentation? + - How hard would it be to write a small code example that shows how to use them? +- What are the "best practices" for writing a good bindings library? + - How should a library author analyze the library to which they want to write bindings? + - What are common problems such people face and their possible solutions? +- What are some of the clearest explanations for FP concepts? + - How hard is it to port their code examples to PureScript? + - Have people written an explanation that "walks one through" an FP paper's ideas in a clear way? + ## New Learners: What is the Best Way to Learn PureScript? ## PureScript Documentation Writers: What is the Best Way to Write Documentation in this Context? From dbe083f5ca526847a76c2e2464dadab6958018f2 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 8 Mar 2019 21:37:26 -0800 Subject: [PATCH 064/133] Cite Slack as docs section --- .../State-of-PureScript-Documentation-2019.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 6977ab0..d50c8d6 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -344,6 +344,8 @@ Thus, people with the same already-answered questions can't find their answers. However, the format is poor. One must read through a (sometimes) lengthy conversation to find the answer. Contrast that with an SO question and answer that appears in a Google search. +(Related interpretation section: [PureScript's Mediums of Communication](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#knowing-whom-to-trust-with-write-access-defining-best-workflow-procedures-and-providing-necessary-support)) + ### What Exactly are FP's "Best Practices" Coming from an Object-Oriented Paradigm, many have asked, "Why aren't the best practices / design patterns / idioms in Functional Programming explained/documented?" From 03554c7e5f7e201a1aac390caf5e7ed59f2a09d4 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 8 Mar 2019 21:40:51 -0800 Subject: [PATCH 065/133] Add question relating to integrating PS with JS build tools --- .../State-of-PureScript-Documentation-2019.md | 1 + 1 file changed, 1 insertion(+) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index d50c8d6..016b644 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -379,6 +379,7 @@ Rather, we can focus on answering questions like these: - What are some of the clearest explanations for FP concepts? - How hard is it to port their code examples to PureScript? - Have people written an explanation that "walks one through" an FP paper's ideas in a clear way? +- Where is a centralized resource that documents the various ways PureScript can integrate with JS build tools (e.g. `parcel`, `webpack`, etc.) and their pros/cons? ## New Learners: What is the Best Way to Learn PureScript? From 8fe78a0c76201f17f449df3e47bd3bbfb763dd74 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 8 Mar 2019 21:55:26 -0800 Subject: [PATCH 066/133] Clean up 'best practices issue' section and cite it --- .../State-of-PureScript-Documentation-2019.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 016b644..51d4f25 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -348,12 +348,24 @@ Contrast that with an SO question and answer that appears in a Google search. ### What Exactly are FP's "Best Practices" -Coming from an Object-Oriented Paradigm, many have asked, "Why aren't the best practices / design patterns / idioms in Functional Programming explained/documented?" +Coming from an Object-Oriented Paradigm, some have asked, "Why aren't the best practices / design patterns / idioms in Functional Programming explained/documented?" + +What are FP's "design patterns" / "idioms" / "best practices" ? How would you define them? FP's "best practices" are - hard to define + - Are `monads` a design pattern? + - Are `lenses` a design pattern? + - What is not a design pattern? - things people assume everyone does (so why explain them?) + - Functions compose. Didn't people realize that type class X and Y are often used together? + - I used a recursive data type to model a domain. How else would I model it? - unconscious habits ("Oh! I didn't realize this was a 'design pattern.'") + - I used a List zipper to efficiently update an item in the list. What else would I use? + +FP languages tend to draw people who are intellectually curious. These people tend not to be good at explaining FP's benefits and concepts. Knowledge get suck in "silos." + +(Related interpretation section: [FP "best practices" are not well-defined, are assumed, or are unconscious habits](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#knowing-whom-to-trust-with-write-access-defining-best-workflow-procedures-and-providing-necessary-support), [FP's culture creates "knowledge silos"](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#knowing-whom-to-trust-with-write-access-defining-best-workflow-procedures-and-providing-necessary-support)) ### Summary From 0596b5d58aff56fbd43395bf9db7047f9e063d0f Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 8 Mar 2019 22:21:46 -0800 Subject: [PATCH 067/133] Include section on PS site privileges; thank core contribs, ask if ok --- .../State-of-PureScript-Documentation-2019.md | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 51d4f25..0a22cb5 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -173,6 +173,7 @@ Here's what has been added to the above since then: These are the reasons. Each wil be covered more in-depth following this: - PureScript is not _currently_ trying to be the next "mainstream language". +- Only core contributors have write/deployment privileges to PureScript websites - Core contributors are spread thin - Breaking changes outdate documentation and kill documenters' motivation - There is no roadmap that coordinates efforts @@ -207,6 +208,18 @@ Thus, PureScript might not be the language for you: (Related interpretation sections: [Keeping the motto of `Avoid "success at all costs"` and understanding its meaning](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#knowing-whom-to-trust-with-write-access-defining-best-workflow-procedures-and-providing-necessary-support)) +### Only core contributors have write / deployment privileges to PureScript websites + +The following PureScript websites either are outdated or could be modified to improve the documentation situation. + +Who can merge PRs into the websites' repositories and redeploy them once these PRs are merged? + +| Site | Write Privilege | Deploy Privelege | Source +| -- | -- | -- | -- | +| PureScript language website | Core Contributors | None. GitHub Pages | - +| Pursuit | Core Contributors | Phil Freeman | [The State of Things, point 2](https://discourse.purescript.org/t/the-state-of-things/282) +| Try PureScript | Core Contributors | Phil Freeman | [The State of Things, point 2](https://discourse.purescript.org/t/the-state-of-things/282) + ### Core contributors are spread thin > It’s been 7 months since I announced that I would be taking a long break from PureScript development.... @@ -229,14 +242,25 @@ The following quote is a response to another's "wallowing:" > > ~ a core contributor ([2nd paragraph](https://gist.github.com/marick/e8b01375309fafaefb879c4840b6da75#gistcomment-2569261), edits made: content was turned into a list; "..." changed to "," for readability) -I (Jordan) don't know whether automating some tasks could be done and whether it would help. +After reading such statements, we can only step back and ask, +- Are the core contributors doing ok? +- Are you getting enough rest? +- Are you still investing in meaningful relationships? +- Is contributing to PureScript still enjoyable to you or has it become burdensome? + +Thank you for the language you have crated, the libraries you wrote and maintain, and all the other things you have done for the benefit of this language and its ecosystem. + +Thank you for putting up with frustrating people, enduring negative and impatient attitudes, and trolls. + + +Continuing with this assessment, I (Jordan) don't know whether automating some tasks could be done and whether it would help. Reviewing documentation can be just as difficult as reviewing code. Some people are faster at reviewing things than others. Thus, maintaining momentum when documenting code is difficult: - Some documentation PRs are missed/forgotten. - Many do not get a timely response from core contributors (one may wait for weeks) -- Most tend to get merged a week or more after their initial submissions. +- Some do not get merged in a timely manner either. (Related interpretation sections: [Limited Manpower / Not Enough Automation](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#limited-manpower--not-enough-automation), [Slow submitted-reviewed-merged timeline of documentation kills momentum](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#slow-submitted-reviewed-merged-timeline-of-documentation-prs-kills-documentation-momentum), [Reviewing documentation PRS can be just as difficult as code PRs](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#reviewing-documentation-prs-can-be-just-as-difficult-as-code-prs)) From 4955490d142ef6413ac8963e9993f2765e7595d4 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 8 Mar 2019 22:37:09 -0800 Subject: [PATCH 068/133] Clarify who 'we' is; provide "code as examples" examples --- .../State-of-PureScript-Documentation-2019.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 0a22cb5..4c592da 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -403,12 +403,15 @@ But, there is hope. People are making an assumption that has not been tested. **Are all documentation efforts always affected by a breaking change?** I doubt it. Certainly there are some things that need better documentation which won't be affected by breaking changes. Why not identify what those are and start improving them? -Such efforts will likely need to be "unofficial." We do not want to steal time away from the core contributors by distracting them with documentation PRs. Let them focus on the language's development. Stabilizing the language sooner means an improved documentation situation sooner. +Such efforts will likely need to be "unofficial." We (non-core-contributors / users of PS) do not want to steal time away from the core contributors by distracting them with documentation PRs. Let them focus on the language's development. Stabilizing the language sooner means an improved documentation situation sooner. -Rather, we can focus on answering questions like these: +Rather, we (non-core-contributors / users of PS) can focus on answering questions like these: - What are the libraries that need to have their documentation improved? - If documented, will breaking changes outdate such documentation? - - How hard would it be to write a small code example that shows how to use them? + - How hard would it be to write a small code example that shows how to use them? For example + - [Jordan's example for how to create a tree via `purescript-tree`](https://github.com/JordanMartinez/purescript-jordans-reference/blob/latestRelease/22-Projects/src/11-Table-of-Contents/04-Tree/01-Syntax.purs#L31-L64) + - [Jordan's example of the "hello world" program via the ReaderT design pattern](https://github.com/JordanMartinez/purescript-jordans-reference/blob/latestRelease/21-Hello-World/08-Application-Structure/src/11-Hello-World/02-ReaderT.purs) + - [Halogen's "basic button component" example](https://github.com/slamdata/purescript-halogen/blob/master/examples/basic/src/Button.purs) - What are the "best practices" for writing a good bindings library? - How should a library author analyze the library to which they want to write bindings? - What are common problems such people face and their possible solutions? @@ -417,6 +420,8 @@ Rather, we can focus on answering questions like these: - Have people written an explanation that "walks one through" an FP paper's ideas in a clear way? - Where is a centralized resource that documents the various ways PureScript can integrate with JS build tools (e.g. `parcel`, `webpack`, etc.) and their pros/cons? +Here's another assumption that hasn't been tested (AFAIK): **all documentation efforts require a lot of work to fix when a breaking change occurs.** + ## New Learners: What is the Best Way to Learn PureScript? ## PureScript Documentation Writers: What is the Best Way to Write Documentation in this Context? From d42329fcc8c8b9a342a2f893aafaa2804f58f7ea Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 8 Mar 2019 22:38:17 -0800 Subject: [PATCH 069/133] Remove other untested assumption (keep it simple) --- .../State-of-PureScript-Documentation-2019.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 4c592da..d2c21da 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -420,8 +420,6 @@ Rather, we (non-core-contributors / users of PS) can focus on answering question - Have people written an explanation that "walks one through" an FP paper's ideas in a clear way? - Where is a centralized resource that documents the various ways PureScript can integrate with JS build tools (e.g. `parcel`, `webpack`, etc.) and their pros/cons? -Here's another assumption that hasn't been tested (AFAIK): **all documentation efforts require a lot of work to fix when a breaking change occurs.** - ## New Learners: What is the Best Way to Learn PureScript? ## PureScript Documentation Writers: What is the Best Way to Write Documentation in this Context? From 2792690d6fd80948d6048cb5df8d84db39577159 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 8 Mar 2019 22:42:35 -0800 Subject: [PATCH 070/133] Encourage people to repost questions on SO after answered --- .../State-of-PureScript-Documentation-2019.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index d2c21da..b3315d5 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -401,6 +401,10 @@ The longer the core contributors take to implement these breaking changes, the l But, there is hope. +This small change will address the FP Slack persistence issue: +- When a question on the `#purescript` Slack channel gets answered, request the person who asked it to post the question on SO and link to the question in the chatroom. +- Then, let someone (whether the answerer or someone who saw it) "answer" that question and give credit it to the answerer. + People are making an assumption that has not been tested. **Are all documentation efforts always affected by a breaking change?** I doubt it. Certainly there are some things that need better documentation which won't be affected by breaking changes. Why not identify what those are and start improving them? Such efforts will likely need to be "unofficial." We (non-core-contributors / users of PS) do not want to steal time away from the core contributors by distracting them with documentation PRs. Let them focus on the language's development. Stabilizing the language sooner means an improved documentation situation sooner. From 925b9128bea43076e23dad2114fc9f4909b3c71e Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Tue, 12 Mar 2019 18:37:43 -0700 Subject: [PATCH 071/133] Fix typo --- .../State-of-PureScript-Documentation-2019.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index b3315d5..f6424e2 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -248,7 +248,7 @@ After reading such statements, we can only step back and ask, - Are you still investing in meaningful relationships? - Is contributing to PureScript still enjoyable to you or has it become burdensome? -Thank you for the language you have crated, the libraries you wrote and maintain, and all the other things you have done for the benefit of this language and its ecosystem. +Thank you for the language you have created, the libraries you wrote and maintain, and all the other things you have done for the benefit of this language and its ecosystem. Thank you for putting up with frustrating people, enduring negative and impatient attitudes, and trolls. From 1173d2aa77d3a030cdb4271baf293dff90a81bbe Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Tue, 12 Mar 2019 18:38:14 -0700 Subject: [PATCH 072/133] Add Gary's full name --- .../State-of-PureScript-Documentation-2019.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index f6424e2..679127f 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -240,7 +240,7 @@ The following quote is a response to another's "wallowing:" > > So unless I stop doing some of that, there's no chance I can make any meaningful steps to improving the documentation situation. > -> ~ a core contributor ([2nd paragraph](https://gist.github.com/marick/e8b01375309fafaefb879c4840b6da75#gistcomment-2569261), edits made: content was turned into a list; "..." changed to "," for readability) +> ~ Gary Burgess, a core contributor ([2nd paragraph](https://gist.github.com/marick/e8b01375309fafaefb879c4840b6da75#gistcomment-2569261), edits made: content was turned into a list; "..." changed to "," for readability) After reading such statements, we can only step back and ask, - Are the core contributors doing ok? From 8451a608da7deae7b8559032962af9cc694e9e06 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Tue, 12 Mar 2019 18:41:00 -0700 Subject: [PATCH 073/133] Add a stronger break to section via header; reorder point --- .../State-of-PureScript-Documentation-2019.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 679127f..744d661 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -252,8 +252,7 @@ Thank you for the language you have created, the libraries you wrote and maintai Thank you for putting up with frustrating people, enduring negative and impatient attitudes, and trolls. - -Continuing with this assessment, I (Jordan) don't know whether automating some tasks could be done and whether it would help. +#### Implications Reviewing documentation can be just as difficult as reviewing code. Some people are faster at reviewing things than others. @@ -262,6 +261,8 @@ Thus, maintaining momentum when documenting code is difficult: - Many do not get a timely response from core contributors (one may wait for weeks) - Some do not get merged in a timely manner either. +Lastly, I (Jordan) don't know whether some tasks could be automated and whether that would help. + (Related interpretation sections: [Limited Manpower / Not Enough Automation](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#limited-manpower--not-enough-automation), [Slow submitted-reviewed-merged timeline of documentation kills momentum](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#slow-submitted-reviewed-merged-timeline-of-documentation-prs-kills-documentation-momentum), [Reviewing documentation PRS can be just as difficult as code PRs](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#reviewing-documentation-prs-can-be-just-as-difficult-as-code-prs)) #### Why Not Just Delegate? From 6e32cd0f292b4d914ac2c7cd73a5490bc9d2a1a5 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Tue, 12 Mar 2019 18:43:16 -0700 Subject: [PATCH 074/133] Reword sentence to include idea of screening possible maintainers --- .../State-of-PureScript-Documentation-2019.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 744d661..a69f8be 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -285,7 +285,7 @@ For example, consider the `event-stream incident`. The maintainer unknowingly ga - [original maintainer's response](https://github.com/dominictarr/event-stream/issues/116) - [a sarcastic blog post summarizing this class of attack](https://hackernoon.com/im-harvesting-credit-card-numbers-and-passwords-from-your-site-here-s-how-9a8cb347c5b5) -Finally, new maintainers, once found, have to be supported (which takes time and thought), so that they can actually fulfill their role. If they decide to leave soon after starting, then one has wasted time and effort. +New maintainers, once found and properly screened, have to be supported (which takes time and thought), so that they can actually fulfill their role. If they decide to leave soon after starting, then one has wasted time and effort. (Related interpretation sections: [Knowing whom to trust with write access, defining best workflow procedures, and providing necessary support](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#knowing-whom-to-trust-with-write-access-defining-best-workflow-procedures-and-providing-necessary-support)) From 8dc679e86deb78300b5357ac36b8c25a6ca6b2a8 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Tue, 12 Mar 2019 19:04:29 -0700 Subject: [PATCH 075/133] Include note about Bower's OOM error stopping doc publishing --- .../State-of-PureScript-Documentation-2019.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index a69f8be..9ffb32b 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -177,6 +177,7 @@ These are the reasons. Each wil be covered more in-depth following this: - Core contributors are spread thin - Breaking changes outdate documentation and kill documenters' motivation - There is no roadmap that coordinates efforts +- `bower` runs out of memory due to transitive dependencies - It's difficult to pin down and define what are Functional Programming's "best practices" - Questions answered on Slack do not persist, so they get re-asked and re-answered @@ -354,6 +355,18 @@ If done after a `v1.0`, then many libraries and docs will need to be updated, th (Related interpretation sections: [Lack of a clearly-defined communit-wide mutually-held vision/goal](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#knowing-whom-to-trust-with-write-access-defining-best-workflow-procedures-and-providing-necessary-support), [Lack of a clearly-defined core-contributor-wide mutually-held language specification](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#knowing-whom-to-trust-with-write-access-defining-best-workflow-procedures-and-providing-necessary-support), [Fear that people will misinterpret at "v1.0" compiler release for a "v1.0" ecosystem release](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#knowing-whom-to-trust-with-write-access-defining-best-workflow-procedures-and-providing-necessary-support)) +### `bower` runs out of memory due to transitive dependencies + +[pulp version runs out of memory (fatal exception) - Issue 351](https://github.com/purescript-contrib/pulp/issues/351)'s core parts: +- Context: Bower is used to produce the "resolutions file" that the compiler expects + - > The compiler expects a “resolutions file” in a similar format to the output of this problematic bower command. We only need a very small portion of the information produced by that command though; for each dependency, if the bower.json specifies anything other than a version range for it, we need to know so that we can produce a warning about that. Otherwise, we need to know which version bower’s solver picked. If I remember correctly that’s everything. Unfortunately I’m not aware of a more sensible variant of bower list which produces all the information we need. [comment in issue, paragraph 2](https://github.com/purescript-contrib/pulp/issues/351#issuecomment-395611759) +- Problem: Bower throws a `RangeError` when attempting to `JSON.stringify` an object that includes a massive dependency tree due to duplicate transitive dependencies: + - > Bower builds a log object, which has our dependency tree. When they try to JSON.stringify this object, it throws RangeError: Invalid string length [comment in issue](https://github.com/purescript-contrib/pulp/issues/351#issuecomment-395605607) +- Solution: Change the compiler's "resolution file" schema. Unfortunately, this is a breaking change: + - > To clarify, the course of action I'm suggesting is that we have `pulp` actually look through the filesystem and collect the resolutions data, and we then pass that information to the compiler. It would make our lives easier if we could also change the compiler so that it accepts this information using a more sensible schema than that of `bower list --offline --json` (and this is what I'm suggesting in that issue ([Simplify `purs publish` resolutions format](https://github.com/purescript/purescript/issues/3499))). + +Thus, a library like `Halogen` cannot publish its `v4.0.0` or `v5.0.0` docs on Pursuit. Unfortunately, there's nothing they can do about it. + ### Slack-Based Questions and Answers Do Not Persist Because the documentation is lacking, many are encouraged to ask their questions on the `#purescript` channel in the FP Slack. Many have greatly benefited from the quick answers they receive. From 41063beebf6b6fab61571035298416ddff6d6e19 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Tue, 12 Mar 2019 19:15:23 -0700 Subject: [PATCH 076/133] Add point: 'breaking changes' waste cc's time by updating ecosystem --- .../State-of-PureScript-Documentation-2019.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 9ffb32b..83b82e5 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -409,9 +409,12 @@ FP languages tend to draw people who are intellectually curious. These people te Because core contributors are spread thin, they cannot respond quickly to people's questions or thoughts. With the small amount of time they do have, they are focusing on adding new language features, not improving the documentation situation. The language's development is steady (6-week release cycle) but slow. -Unfortunately, these language features entail breaking changes. So, those who want to improve the documentation situation are discouraged from improving it. Why invest many hours into something that will be outdated in a few months? Why not invest those hours into something else, like an interesting project or learning something new? +However, it seems they are (wisely) postponing "breaking changes" until all can be done at once. Otherwise, they will ~spend~ waste even more of their time updating the ecosystem to account for the breaking changes. -The longer the core contributors take to implement these breaking changes, the longer such documentation writers will wait, and the longer we'll be in this situation. This is not to blame the core contributors. They're doing great and their pace is just fine. It's only stating the reality of our situation. +Due to the looming "breaking changes," those who want to improve the documentation situation are often discouraged from improving it. Why invest many hours into something that will be outdated in a few months? Why not invest those hours into something else, like an interesting project or learning something new? + +The following statements are not to blame people or point fingers. Rather, it states what is our reality: +> Core contributors are doing great and their pace is just fine. Still, the longer the core contributors take to implement these breaking changes, the longer such documentation writers will wait, and the longer we'll be in this situation. But, there is hope. From c565999ce9fdfc65ac298248eeed412f6d0c5b78 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Tue, 12 Mar 2019 19:22:39 -0700 Subject: [PATCH 077/133] Slightly expand 'non-bc-affected questions non-CC people can answer' - "bc" stands for "breaking changes" --- .../State-of-PureScript-Documentation-2019.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 83b82e5..95ce5e1 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -433,13 +433,17 @@ Rather, we (non-core-contributors / users of PS) can focus on answering question - [Jordan's example for how to create a tree via `purescript-tree`](https://github.com/JordanMartinez/purescript-jordans-reference/blob/latestRelease/22-Projects/src/11-Table-of-Contents/04-Tree/01-Syntax.purs#L31-L64) - [Jordan's example of the "hello world" program via the ReaderT design pattern](https://github.com/JordanMartinez/purescript-jordans-reference/blob/latestRelease/21-Hello-World/08-Application-Structure/src/11-Hello-World/02-ReaderT.purs) - [Halogen's "basic button component" example](https://github.com/slamdata/purescript-halogen/blob/master/examples/basic/src/Button.purs) -- What are the "best practices" for writing a good bindings library? - - How should a library author analyze the library to which they want to write bindings? - - What are common problems such people face and their possible solutions? -- What are some of the clearest explanations for FP concepts? +- What are "best practices" for various topics/areas? For example: + - Guidelines for writing a good bindings library + - How should a library author analyze the library to which they want to write bindings? + - What are common problems such people face and their possible solutions? +- What are some of the clearest explanations of FP concepts? - How hard is it to port their code examples to PureScript? - Have people written an explanation that "walks one through" an FP paper's ideas in a clear way? -- Where is a centralized resource that documents the various ways PureScript can integrate with JS build tools (e.g. `parcel`, `webpack`, etc.) and their pros/cons? +- What are common solutions to build-related problems? Where is a centralized resource that can store all of these? + - Integrating PureScript to work with JS build tools? + - Integrating PureScript with CI (Travis, AppVeyor, etc.)? + - Possible "tree-shaking" approaches to PureScript and their tradeoffs? ## New Learners: What is the Best Way to Learn PureScript? From 03795f408e623111a27d1ac6307b3e75b2de73a4 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Tue, 12 Mar 2019 19:22:49 -0700 Subject: [PATCH 078/133] Fix typo --- .../State-of-PureScript-Documentation-2019.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 95ce5e1..0600568 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -401,7 +401,7 @@ FP's "best practices" are - unconscious habits ("Oh! I didn't realize this was a 'design pattern.'") - I used a List zipper to efficiently update an item in the list. What else would I use? -FP languages tend to draw people who are intellectually curious. These people tend not to be good at explaining FP's benefits and concepts. Knowledge get suck in "silos." +FP languages tend to draw people who are intellectually curious. These people tend not to be good at explaining FP's benefits and concepts. Knowledge get stuck in "silos." (Related interpretation section: [FP "best practices" are not well-defined, are assumed, or are unconscious habits](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#knowing-whom-to-trust-with-write-access-defining-best-workflow-procedures-and-providing-necessary-support), [FP's culture creates "knowledge silos"](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#knowing-whom-to-trust-with-write-access-defining-best-workflow-procedures-and-providing-necessary-support)) From b5d39ce91aa370c3457cc36414892db2709003c8 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Tue, 12 Mar 2019 19:28:34 -0700 Subject: [PATCH 079/133] Handle citations/sources for bower OOM section better --- .../State-of-PureScript-Documentation-2019.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 0600568..e8eaff1 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -357,15 +357,16 @@ If done after a `v1.0`, then many libraries and docs will need to be updated, th ### `bower` runs out of memory due to transitive dependencies -[pulp version runs out of memory (fatal exception) - Issue 351](https://github.com/purescript-contrib/pulp/issues/351)'s core parts: +From [pulp version runs out of memory (fatal exception) - Issue 351](https://github.com/purescript-contrib/pulp/issues/351): - Context: Bower is used to produce the "resolutions file" that the compiler expects - > The compiler expects a “resolutions file” in a similar format to the output of this problematic bower command. We only need a very small portion of the information produced by that command though; for each dependency, if the bower.json specifies anything other than a version range for it, we need to know so that we can produce a warning about that. Otherwise, we need to know which version bower’s solver picked. If I remember correctly that’s everything. Unfortunately I’m not aware of a more sensible variant of bower list which produces all the information we need. [comment in issue, paragraph 2](https://github.com/purescript-contrib/pulp/issues/351#issuecomment-395611759) - Problem: Bower throws a `RangeError` when attempting to `JSON.stringify` an object that includes a massive dependency tree due to duplicate transitive dependencies: - > Bower builds a log object, which has our dependency tree. When they try to JSON.stringify this object, it throws RangeError: Invalid string length [comment in issue](https://github.com/purescript-contrib/pulp/issues/351#issuecomment-395605607) -- Solution: Change the compiler's "resolution file" schema. Unfortunately, this is a breaking change: - - > To clarify, the course of action I'm suggesting is that we have `pulp` actually look through the filesystem and collect the resolutions data, and we then pass that information to the compiler. It would make our lives easier if we could also change the compiler so that it accepts this information using a more sensible schema than that of `bower list --offline --json` (and this is what I'm suggesting in that issue ([Simplify `purs publish` resolutions format](https://github.com/purescript/purescript/issues/3499))). -Thus, a library like `Halogen` cannot publish its `v4.0.0` or `v5.0.0` docs on Pursuit. Unfortunately, there's nothing they can do about it. +The proposed solution: change the compiler's "resolution file" schema. Unfortunately, this is a breaking change (tracking issue: [Simplify `purs publish` resolution format](https://github.com/purescript/purescript/issues/3499)): + - > To clarify, the course of action I'm suggesting is that we have `pulp` actually look through the filesystem and collect the resolutions data, and we then pass that information to the compiler. It would make our lives easier if we could also change the compiler so that it accepts this information using a more sensible schema than that of `bower list --offline --json` (and this is what I'm suggesting in that issue ([comment in issue](https://github.com/purescript-contrib/pulp/issues/351#issuecomment-450465708))). + +Thus, a heavily-used library like `Halogen` cannot publish its `v4.0.0` or `v5.0.0` docs on Pursuit. Unfortunately, there's nothing they can do about it. ### Slack-Based Questions and Answers Do Not Persist From 5253d9120d45cf153d1f61b34ac57a14cae21d1c Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Tue, 12 Mar 2019 19:31:49 -0700 Subject: [PATCH 080/133] Convert SO to StackOverflow --- .../State-of-PureScript-Documentation-2019.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index e8eaff1..66a2b6f 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -381,7 +381,7 @@ Thus, people with the same already-answered questions can't find their answers. @chexxor has made some effort to address these issues by cross-posting such discussions in the Discourse forum. This accounts for the second issue. However, the format is poor. One must read through a (sometimes) lengthy conversation to find the answer. -Contrast that with an SO question and answer that appears in a Google search. +Contrast that with an StackOverflow question and answer that appears in a Google search. (Related interpretation section: [PureScript's Mediums of Communication](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#knowing-whom-to-trust-with-write-access-defining-best-workflow-procedures-and-providing-necessary-support)) @@ -420,7 +420,7 @@ The following statements are not to blame people or point fingers. Rather, it st But, there is hope. This small change will address the FP Slack persistence issue: -- When a question on the `#purescript` Slack channel gets answered, request the person who asked it to post the question on SO and link to the question in the chatroom. +- When a question on the `#purescript` Slack channel gets answered, request the person who asked it to post the question on StackOverflow and link to the question in the chatroom. - Then, let someone (whether the answerer or someone who saw it) "answer" that question and give credit it to the answerer. People are making an assumption that has not been tested. **Are all documentation efforts always affected by a breaking change?** I doubt it. Certainly there are some things that need better documentation which won't be affected by breaking changes. Why not identify what those are and start improving them? From 535f78153a5965a9101ebdf73eee4c4fdb23c408 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Tue, 12 Mar 2019 19:35:33 -0700 Subject: [PATCH 081/133] Include Gary's point about breaking changes occurring less frequently. --- .../State-of-PureScript-Documentation-2019.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 66a2b6f..af1456c 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -312,6 +312,8 @@ The `0.12.0` was a significant achievement but one that came with a lot of break > > ~ Phil Freeman [The State of Things, point 4](https://discourse.purescript.org/t/the-state-of-things/282) +Gary later pointed out that releases with "breaking changes" were occuring less frequently ([source](https://docs.google.com/spreadsheets/d/1MO8siLLSOpkKHJ_eBNRJbipBquFgqlaSS-QSnALDSo8/edit#gid=0)). Still, keep in mind that Phil was likely updating the book each time such a release was made. + (Related interpretation sections: [Breaking Changes Render Documentation Outdated](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#knowing-whom-to-trust-with-write-access-defining-best-workflow-procedures-and-providing-necessary-support)) ### There Is No Roadmap That Coordinates Efforts From e345c044d5d9a2d2e15d6d64ece36aca4a6b7427 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Tue, 12 Mar 2019 19:39:29 -0700 Subject: [PATCH 082/133] Fix numerous citations: cite correct section in All Interpretations file --- .../State-of-PureScript-Documentation-2019.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index af1456c..38a5f5a 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -314,7 +314,7 @@ The `0.12.0` was a significant achievement but one that came with a lot of break Gary later pointed out that releases with "breaking changes" were occuring less frequently ([source](https://docs.google.com/spreadsheets/d/1MO8siLLSOpkKHJ_eBNRJbipBquFgqlaSS-QSnALDSo8/edit#gid=0)). Still, keep in mind that Phil was likely updating the book each time such a release was made. -(Related interpretation sections: [Breaking Changes Render Documentation Outdated](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#knowing-whom-to-trust-with-write-access-defining-best-workflow-procedures-and-providing-necessary-support)) +(Related interpretation sections: [Breaking Changes Render Documentation Outdated](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#breaking-changes-renders-documentation-outdated)) ### There Is No Roadmap That Coordinates Efforts @@ -355,7 +355,7 @@ If done before a `v1.0`, then the language will likely be stable, documentation If done after a `v1.0`, then many libraries and docs will need to be updated, the language's reputation might suffer, and people might be forever turned off to it. -(Related interpretation sections: [Lack of a clearly-defined communit-wide mutually-held vision/goal](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#knowing-whom-to-trust-with-write-access-defining-best-workflow-procedures-and-providing-necessary-support), [Lack of a clearly-defined core-contributor-wide mutually-held language specification](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#knowing-whom-to-trust-with-write-access-defining-best-workflow-procedures-and-providing-necessary-support), [Fear that people will misinterpret at "v1.0" compiler release for a "v1.0" ecosystem release](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#knowing-whom-to-trust-with-write-access-defining-best-workflow-procedures-and-providing-necessary-support)) +(Related interpretation sections: [Lack of a clearly-defined communit-wide mutually-held vision/goal](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#lack-of-a-clearly-defined-community-wide-mutually-held-visiongoal), [Lack of a clearly-defined core-contributor-wide mutually-held language specification](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#lack-of-a-clearly-defined-core-contributor-wide-mutually-held-language-specification), [Fear that people will misinterpret at "v1.0" compiler release for a "v1.0" ecosystem release](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#fear-that-people-will-misinterpret-a-v10-compiler-release-for-a-v10-ecosystem-release)) ### `bower` runs out of memory due to transitive dependencies @@ -385,7 +385,7 @@ Thus, people with the same already-answered questions can't find their answers. However, the format is poor. One must read through a (sometimes) lengthy conversation to find the answer. Contrast that with an StackOverflow question and answer that appears in a Google search. -(Related interpretation section: [PureScript's Mediums of Communication](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#knowing-whom-to-trust-with-write-access-defining-best-workflow-procedures-and-providing-necessary-support)) +(Related interpretation section: [PureScript's Mediums of Communication](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#purescripts-mediums-of-communication)) ### What Exactly are FP's "Best Practices" @@ -406,7 +406,7 @@ FP's "best practices" are FP languages tend to draw people who are intellectually curious. These people tend not to be good at explaining FP's benefits and concepts. Knowledge get stuck in "silos." -(Related interpretation section: [FP "best practices" are not well-defined, are assumed, or are unconscious habits](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#knowing-whom-to-trust-with-write-access-defining-best-workflow-procedures-and-providing-necessary-support), [FP's culture creates "knowledge silos"](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#knowing-whom-to-trust-with-write-access-defining-best-workflow-procedures-and-providing-necessary-support)) +(Related interpretation section: [FP "best practices" are not well-defined, are assumed, or are unconscious habits](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#fp-best-practices-are-not-well-defined-are-assumed-or-are-unconscious-habits), [FP's culture creates "knowledge silos"](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#fps-culture-creates-knowledge-silos)) ### Summary From 690aaebf358ade99a100e20864fa2b5289f44939 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Tue, 12 Mar 2019 19:40:12 -0700 Subject: [PATCH 083/133] Rename header to focus on real issue: documentation publishing --- .../State-of-PureScript-Documentation-2019.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 38a5f5a..0124876 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -177,7 +177,7 @@ These are the reasons. Each wil be covered more in-depth following this: - Core contributors are spread thin - Breaking changes outdate documentation and kill documenters' motivation - There is no roadmap that coordinates efforts -- `bower` runs out of memory due to transitive dependencies +- Some libraries cannot publish their docs due to OOM error - It's difficult to pin down and define what are Functional Programming's "best practices" - Questions answered on Slack do not persist, so they get re-asked and re-answered @@ -357,7 +357,7 @@ If done after a `v1.0`, then many libraries and docs will need to be updated, th (Related interpretation sections: [Lack of a clearly-defined communit-wide mutually-held vision/goal](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#lack-of-a-clearly-defined-community-wide-mutually-held-visiongoal), [Lack of a clearly-defined core-contributor-wide mutually-held language specification](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#lack-of-a-clearly-defined-core-contributor-wide-mutually-held-language-specification), [Fear that people will misinterpret at "v1.0" compiler release for a "v1.0" ecosystem release](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#fear-that-people-will-misinterpret-a-v10-compiler-release-for-a-v10-ecosystem-release)) -### `bower` runs out of memory due to transitive dependencies +### Some libraries cannot publish their docs due to OOM error From [pulp version runs out of memory (fatal exception) - Issue 351](https://github.com/purescript-contrib/pulp/issues/351): - Context: Bower is used to produce the "resolutions file" that the compiler expects From 349af8c465283d86ede5841c9435de88b3e64ef1 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Tue, 12 Mar 2019 19:51:59 -0700 Subject: [PATCH 084/133] Add summary (anchor link) to section's preface --- .../State-of-PureScript-Documentation-2019.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 0124876..e9734d7 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -181,6 +181,8 @@ These are the reasons. Each wil be covered more in-depth following this: - It's difficult to pin down and define what are Functional Programming's "best practices" - Questions answered on Slack do not persist, so they get re-asked and re-answered +This section concludes with a [narrative summary](#summary-of-Why-Docs-are-Lacking). + ### PureScript is not _currently_ trying to be the next "mainstream language" A few have wrongly assumed that PureScript is trying to replace [insert your favorite web language here]. That is not the case. @@ -408,7 +410,7 @@ FP languages tend to draw people who are intellectually curious. These people te (Related interpretation section: [FP "best practices" are not well-defined, are assumed, or are unconscious habits](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#fp-best-practices-are-not-well-defined-are-assumed-or-are-unconscious-habits), [FP's culture creates "knowledge silos"](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#fps-culture-creates-knowledge-silos)) -### Summary +### Summary of 'Why Docs are Lacking' Because core contributors are spread thin, they cannot respond quickly to people's questions or thoughts. With the small amount of time they do have, they are focusing on adding new language features, not improving the documentation situation. The language's development is steady (6-week release cycle) but slow. From 8ccd236b12a9577d4dd0d28e374eeaf202db53c9 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 29 Mar 2019 18:00:07 -0700 Subject: [PATCH 085/133] Forewarn learners that PS is mainly for front-end --- .../State-of-PureScript-Documentation-2019.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 69db5bb..6a84245 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -193,7 +193,9 @@ Here's what has been added to the above since then: ## New Learners: What is the Best Way to Learn PureScript? -There are likely other learning paths besides the ones covered below, but here's what we found in our research: +First, PureScript is mainly used for front-end work, not back-end work. While it is used for the back-end in some situations, most tend to use Haskell or another language, even if PureScript would be a better language in some situations. These languages already have mature libraries with people maintaining them. So, the incentives to improve this situation are not quite there. + +Second, your language background affects how easy or hard it is to learn PureScript. There are likely other learning paths besides the ones covered below, but here's what we found in our research: ![Learner Paths "Learner Paths"](./learner-paths-to-ps.png) From 640f31628352abb9fb3f87b476b690116b4e4ce1 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 29 Mar 2019 18:14:48 -0700 Subject: [PATCH 086/133] Rename header: support system not build structured persistent docs --- .../State-of-PureScript-Documentation-2019.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index e9734d7..1e2ae9f 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -179,7 +179,7 @@ These are the reasons. Each wil be covered more in-depth following this: - There is no roadmap that coordinates efforts - Some libraries cannot publish their docs due to OOM error - It's difficult to pin down and define what are Functional Programming's "best practices" -- Questions answered on Slack do not persist, so they get re-asked and re-answered +- The current support system doesn't build towards structured, persistent documentation This section concludes with a [narrative summary](#summary-of-Why-Docs-are-Lacking). @@ -372,7 +372,7 @@ The proposed solution: change the compiler's "resolution file" schema. Unfortuna Thus, a heavily-used library like `Halogen` cannot publish its `v4.0.0` or `v5.0.0` docs on Pursuit. Unfortunately, there's nothing they can do about it. -### Slack-Based Questions and Answers Do Not Persist +### The current support system doesn't build towards structured, persistent documentation Because the documentation is lacking, many are encouraged to ask their questions on the `#purescript` channel in the FP Slack. Many have greatly benefited from the quick answers they receive. From 338097225c9103af110c54efe0765e9ec398292a Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 29 Mar 2019 18:20:59 -0700 Subject: [PATCH 087/133] Rephrase 'avoid success at all costs' to 'value power over popularity' --- .../State-of-PureScript-Documentation-2019.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 1e2ae9f..f77dc93 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -188,26 +188,26 @@ This section concludes with a [narrative summary](#summary-of-Why-Docs-are-Lacki A few have wrongly assumed that PureScript is trying to replace [insert your favorite web language here]. That is not the case. PureScript has the following philosophy: -> Making a language "successful" (e.g. popular, industry-standard, taught in universities' curriculums, etc.) is not a justification for paying for "costs" that ruin the language, such as limiting the language's expressiveness, making it less safe, less secure, etc. +> Making a language "popular" (e.g. industry-standard, taught in universities' curriculums, etc.) is not a justification for paying for "costs" that ruin the language, such as limiting the language's expressiveness, making it less safe, less secure, etc. > > Making the language easier to use and learn by improving it is good and supported. -> Making the language easier to use and learn by crippling, downgrading, or dumbing down the language is rejected. Users will either learn it properly or use something else. +> Achieving the same goals by crippling, downgrading, or dumbing down the language is rejected. Users will either learn it properly or use something else. > -> Plenty of languages chose to sacrifice safety, security, efficiency, etc. to gain the benefits of "success." +> Plenty of languages chose to sacrifice safety, security, efficiency, etc. to gain the benefits of "popularity." > > PureScript will not be another such language. Rather, it will try to progress in "the right way," even when it's inconvenient, makes it harder to learn, etc. > > ~ Summary of [A Response that Explains the Motto: 'Avoid (Success at All Costs)'](https://news.ycombinator.com/item?id=12056169) (edits made: replaced 'Haskell' with 'PureScript'; removed "research-related concepts") -This philosophy is summarized as "avoid (success at all costs)." +While typically stated differently, one could summarize this philosophy as "value power and expressivity over popularity." The current focus (see later point) is not on making documentation great. Rather, it's on implementing the language features that haven't yet been implemented. However, even if great documentation was the focus, one will still have to learn difficult concepts before they can be productive. This fact will never change. Thus, PureScript might not be the language for you: -- If you value 'success' over 'costs,' use a different language. -- If you value 'costs' over 'success' and are determined to learn hard things, use this language. +- If you value 'popularity' over 'power,' use a different language. +- If you value 'power' over 'popularity' and are determined to learn hard things, use this language. (Related interpretation sections: [Keeping the motto of `Avoid "success at all costs"` and understanding its meaning](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#knowing-whom-to-trust-with-write-access-defining-best-workflow-procedures-and-providing-necessary-support)) From 0be620719f9c1fb57900e8559ceb94d245ec5849 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 29 Mar 2019 18:25:41 -0700 Subject: [PATCH 088/133] Convert notion of 'costs' into notions of 'power' --- .../State-of-PureScript-Documentation-2019.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index f77dc93..ab03381 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -188,7 +188,7 @@ This section concludes with a [narrative summary](#summary-of-Why-Docs-are-Lacki A few have wrongly assumed that PureScript is trying to replace [insert your favorite web language here]. That is not the case. PureScript has the following philosophy: -> Making a language "popular" (e.g. industry-standard, taught in universities' curriculums, etc.) is not a justification for paying for "costs" that ruin the language, such as limiting the language's expressiveness, making it less safe, less secure, etc. +> Making a language "popular" (e.g. industry-standard, taught in universities' curriculums, etc.) is not a justification for decreasing its "power," such as limiting the language's expressiveness, making it less safe, less secure, etc. > > Making the language easier to use and learn by improving it is good and supported. > Achieving the same goals by crippling, downgrading, or dumbing down the language is rejected. Users will either learn it properly or use something else. From 164b36e222ecda1608cf338d4a456b8f0bb21be3 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 29 Mar 2019 18:29:41 -0700 Subject: [PATCH 089/133] Use Alex's view of the OpenCollective situation (I agree) --- .../State-of-PureScript-Documentation-2019.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index ab03381..a4bafb6 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -296,9 +296,13 @@ New maintainers, once found and properly screened, have to be supported (which t Been there, done that. Someone took it down. ([PureScript Open Collective]((https://opencollective.com/purescript)) -I (Jordan) don't know why it was taken down. Here's my speculation: -- Since the project and its funds hadn't been claimed for a couple of weeks, it was stopped to prevent anyone on the internet from stealing the funds. -- There was no clear vision as to how the funds would be spent and how it would improve the situation. +Our viewpoint of this situation: +- Fans of PureScript wanted to throw money at the project. Why? Perhaps because + - they want to help the project and its goals + - they dont have the time or mental capacity to contribute +- Several people used OpenCollective to indicate they'd like to pledge money to the "github.com/purescript/purescript" project. +- Several weeks later, someone claimed that project's corresponding OpenCollective page and turned off the public page. +- We believe this was because there was no clear vision as to how the funds would be spent. Perhaps this idea could be revisited in the future. For now, we cannot say. From 15cd09d689ecd7a311408c23daf0bccc16f44135 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 29 Mar 2019 18:36:15 -0700 Subject: [PATCH 090/133] Port summary of 'why docs are lacking' to start of the section --- .../State-of-PureScript-Documentation-2019.md | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index a4bafb6..c60c81a 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -170,7 +170,18 @@ Here's what has been added to the above since then: ## Why is PureScript's Documentation Lacking and How Do We Improve It? -These are the reasons. Each wil be covered more in-depth following this: +Here's the short version. + +Because core contributors are spread thin, they cannot respond quickly to people's questions or thoughts. With the small amount of time they do have, they are focusing on adding new language features, not improving the documentation situation. The language's development is steady (6-week release cycle) but slow. + +However, it seems they are (wisely) postponing "breaking changes" until all can be done at once. Otherwise, they will ~spend~ waste even more of their time updating the ecosystem to account for the breaking changes. + +Due to the looming "breaking changes," those who want to improve the documentation situation are often discouraged from improving it. Why invest many hours into something that will be outdated in a few months? Why not invest those hours into something else, like an interesting project or learning something new? + +The following statements are not to blame people or point fingers. Rather, it states what is our reality: +> Core contributors are doing great and their pace is just fine. Still, the longer the core contributors take to implement these breaking changes, the longer such documentation writers will wait, and the longer we'll be in this situation. As a result, we're in a sort of catch-22 situation. + +The above summary is explained more fully in each section below: - PureScript is not _currently_ trying to be the next "mainstream language". - Only core contributors have write/deployment privileges to PureScript websites @@ -414,18 +425,7 @@ FP languages tend to draw people who are intellectually curious. These people te (Related interpretation section: [FP "best practices" are not well-defined, are assumed, or are unconscious habits](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#fp-best-practices-are-not-well-defined-are-assumed-or-are-unconscious-habits), [FP's culture creates "knowledge silos"](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#fps-culture-creates-knowledge-silos)) -### Summary of 'Why Docs are Lacking' - -Because core contributors are spread thin, they cannot respond quickly to people's questions or thoughts. With the small amount of time they do have, they are focusing on adding new language features, not improving the documentation situation. The language's development is steady (6-week release cycle) but slow. - -However, it seems they are (wisely) postponing "breaking changes" until all can be done at once. Otherwise, they will ~spend~ waste even more of their time updating the ecosystem to account for the breaking changes. - -Due to the looming "breaking changes," those who want to improve the documentation situation are often discouraged from improving it. Why invest many hours into something that will be outdated in a few months? Why not invest those hours into something else, like an interesting project or learning something new? - -The following statements are not to blame people or point fingers. Rather, it states what is our reality: -> Core contributors are doing great and their pace is just fine. Still, the longer the core contributors take to implement these breaking changes, the longer such documentation writers will wait, and the longer we'll be in this situation. - -But, there is hope. +### But Is There Hope? Yes! This small change will address the FP Slack persistence issue: - When a question on the `#purescript` Slack channel gets answered, request the person who asked it to post the question on StackOverflow and link to the question in the chatroom. From df0f7bcc115451fbeaedcbac35d7f8290316a463 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 29 Mar 2019 18:59:36 -0700 Subject: [PATCH 091/133] Elaborate 'why docs lacking' summary; integrate with links to sections --- .../State-of-PureScript-Documentation-2019.md | 29 +++++++++---------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index c60c81a..3933184 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -170,29 +170,26 @@ Here's what has been added to the above since then: ## Why is PureScript's Documentation Lacking and How Do We Improve It? -Here's the short version. +Here's the short version. Each paragraph will have a link that explains its summary in more detail. -Because core contributors are spread thin, they cannot respond quickly to people's questions or thoughts. With the small amount of time they do have, they are focusing on adding new language features, not improving the documentation situation. The language's development is steady (6-week release cycle) but slow. +PureScript is not _currently_ trying to be the next "mainstream language." Rather, it values "power" over "popularity" and so works towards those ends. [further explained here]() -However, it seems they are (wisely) postponing "breaking changes" until all can be done at once. Otherwise, they will ~spend~ waste even more of their time updating the ecosystem to account for the breaking changes. +While developing the language, core contributors incurred a lot of responsibility (e.g. library maintenance, documentation updates, updating Pursuit and other related sites, etc.). Over time, they became spread thin and one even burned out. [further explained here]() -Due to the looming "breaking changes," those who want to improve the documentation situation are often discouraged from improving it. Why invest many hours into something that will be outdated in a few months? Why not invest those hours into something else, like an interesting project or learning something new? +Thus, they cannot quickly respond to most people's questions or contributions. With the small amount of time they do have, they are focusing on adding new language features, not improving the documentation situation. The language's development is steady (6-week release cycle) but slow. [further explained here]() -The following statements are not to blame people or point fingers. Rather, it states what is our reality: -> Core contributors are doing great and their pace is just fine. Still, the longer the core contributors take to implement these breaking changes, the longer such documentation writers will wait, and the longer we'll be in this situation. As a result, we're in a sort of catch-22 situation. +However, it seems they are (wisely) postponing "breaking changes" until all can be done at once. Otherwise, they will ~spend~ waste even more of their time updating the ecosystem to account for the breaking changes. There is also some disagreement about when those changes should be done. [further explained here]() -The above summary is explained more fully in each section below: +Due to the looming "breaking changes," those who want to improve the documentation situation are often discouraged from improving it. They tend to think, "Why invest many hours into something that will be outdated in a few months? Why not invest those hours into something else, like an interesting project or learning something new?" [further explained here]() -- PureScript is not _currently_ trying to be the next "mainstream language". -- Only core contributors have write/deployment privileges to PureScript websites -- Core contributors are spread thin -- Breaking changes outdate documentation and kill documenters' motivation -- There is no roadmap that coordinates efforts -- Some libraries cannot publish their docs due to OOM error -- It's difficult to pin down and define what are Functional Programming's "best practices" -- The current support system doesn't build towards structured, persistent documentation +The following statement is not to blame people or point fingers. Rather, it summarizes our current reality: +> Core contributors are doing great and their pace is just fine. Still, we're in a sort of catch-22 situation. The longer the core contributors take to implement these breaking changes, the longer most documentation writers will wait to avoid unnecessary updates, and the longer we'll be in this situation. -This section concludes with a [narrative summary](#summary-of-Why-Docs-are-Lacking). +Moreover, there are other factors independent of the "breaking changes" issues. +1. Until recently (it's fixed now), an OOM error was preventing some popular libraries from uploading their API docs. Even those familiar with the language had difficulty knowing how to use some libraries. [further explained here]() +2. The current support system doesn't build towards structured, persistent documentation. In some ways, it's like trying to get out of quicksand. [further explained here]() + +Finally, it is difficult to define what are FP's "best practices / design patterns." This issue won't go away even if the documentation situation improves. [further explained here]() ### PureScript is not _currently_ trying to be the next "mainstream language" From f63b84c02ad2b08525d5d24f64263d931c55ddce Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 29 Mar 2019 19:00:53 -0700 Subject: [PATCH 092/133] Rephrase: breaking changes are the root issue, not doc sitaution --- .../State-of-PureScript-Documentation-2019.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 3933184..d516d3f 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -189,7 +189,7 @@ Moreover, there are other factors independent of the "breaking changes" issues. 1. Until recently (it's fixed now), an OOM error was preventing some popular libraries from uploading their API docs. Even those familiar with the language had difficulty knowing how to use some libraries. [further explained here]() 2. The current support system doesn't build towards structured, persistent documentation. In some ways, it's like trying to get out of quicksand. [further explained here]() -Finally, it is difficult to define what are FP's "best practices / design patterns." This issue won't go away even if the documentation situation improves. [further explained here]() +Finally, it is difficult to define what are FP's "best practices / design patterns." This issue won't go away even if all 'breaking changes' have been implemented. [further explained here]() ### PureScript is not _currently_ trying to be the next "mainstream language" From 60d6612521078d4d3ceb7eb0082d5716fd95bac1 Mon Sep 17 00:00:00 2001 From: Alex Berg Date: Sun, 31 Mar 2019 14:07:50 -0500 Subject: [PATCH 093/133] Clarify the Purpose in the context/narrative (#60) * Clarify the Purpose in the context/narrative * Add ToC, remove Outline. * Clarify "Maintaining Documentation's Accuracy" * Move TOC * Revise 'Purpose' * Put 'size' and 'frequency' into a bullet point list --- .../State-of-PureScript-Documentation-2019.md | 55 ++++++++++++------- 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 5271aeb..681e526 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -1,28 +1,35 @@ # State of PureScript Documentation: 2019 -## Why Read This Document? +This document is not meant to convince you to use PureScript, we assume that readers are already interested in it or using it. -This document is not meant to convince you to use PureScript. We assume that readers already believe in using PureScript instead of alternatives. - -It is well-known among the PureScript community that its documentation is lacking in some critical areas. As a result, @chexxor started the [PureScript documentation efforts in 2019](https://discourse.purescript.org/t/purescript-documentation-efforts-in-2019/524) discourse thread to answer one question: +It is well-known amongst the PureScript community that its documentation is lacking in some critical areas. As a result, @chexxor started the [PureScript documentation efforts in 2019](https://discourse.purescript.org/t/purescript-documentation-efforts-in-2019/524) Discourse thread to answer one question: > How can we improve the PureScript documentation in 2019? -(Purpose) The following document tries to do two things: -1. Provide an answer to @chexxor's above question -2. Answer other related questions that various audiences will have: - - new learners (regardless of language background) +(Purpose) The following document tries to do the following things: +1. Provide a researched narrative of PureScript's documentation development and history. +2. Define the types of audiences of PureScript documentation and their expectations. + - New learners (regardless of language background) - PureScript documentation writers - - Core Contributors - -Outline -- Explain what "good" documentation is and define a criteria -- Evaluate PureScript's documentation using that criteria -- Explain why PureScript's documentation is seen as lacking -- Suggest plans to improve the current documentation situation -- Address various audience's possible concerns or questions centered on these themes: - - New learners - How should I learn PureScript? - - PureScript documentation writers - How should I write good maintainable documentation for others? - - Core Contributors - + - Core contributors +3. Summarize the current opinions of PureScript's documentation audiences. +4. Explore strategies for improving PureScript's documentation for its audiences. + + + +- [What is "Good" Documentation Anyway?](#what-is-good-documentation-anyway) + - [The Types of Documentation](#the-types-of-documentation) + - [The Documentation's Intended Audience](#the-documentations-intended-audience) + - [Maintaining Documentation's Accuracy](#maintaining-documentations-accuracy) + - [The "Size" of a Change](#the-size-of-a-change) + - [The "Frequency" of a Change](#the-frequency-of-a-change) + - [How to Make Maintenance Easier](#how-to-make-maintenance-easier) + - [Criteria for "Good" Documentation](#criteria-for-good-documentation) + - [Evaluating PureScript's Documentation](#evaluating-purescripts-documentation) +- [Why is PureScript's Documentation Lacking and How Do We Improve It?](#why-is-purescripts-documentation-lacking-and-how-do-we-improve-it) +- [New Learners: What is the Best Way to Learn PureScript?](#new-learners-what-is-the-best-way-to-learn-purescript) +- [PureScript Documentation Writers: What is the Best Way to Write Documentation in this Context?](#purescript-documentation-writers-what-is-the-best-way-to-write-documentation-in-this-context) +- [Core Contributors: ???](#core-contributors-) + ## What is "Good" Documentation Anyway? @@ -72,10 +79,14 @@ As a result, others who read the resulting documentation will consider it "poor" ### Maintaining Documentation's Accuracy -Third, documentation becomes outdated/inaccurate due to changes, especially breaking changes. It does this in two ways: decreasing its usefulness (depends on the 'size' of a change) and decreasing its coherence (depends on the 'frequency' of changes). +Third, documentation becomes outdated/inaccurate when the thing being documented changes in two ways: +- the 'size' of a change +- the 'frequency' of changes #### The "Size" of a Change +The 'size' of a change can decrease its usefulness. + | "Size" | Example | -- | -- | | Small | A bug fix that affects little else. @@ -93,6 +104,8 @@ Updating documentation in light of breaking changes often requires the most work #### The "Frequency" of a Change +The 'frequency' of a change can decrease its coherence. + | "Frequency" | Example | -- | -- | | Rarely | Stable libraries that have exhausted their design space (e.g. core data types) @@ -100,7 +113,7 @@ Updating documentation in light of breaking changes often requires the most work | Frequently | New libraries When changes occur frequently, documentation can appear more like loosely-coupled snippets of ideas rather than a coherent explanation because: -- Article A depends on Article B to explain something. Then, Aritcle B becomes outdated. Thus, one "patches" Article A with a quick overview of Article B that doesn't fit in with the rest of Article A's content. +- Article A depends on Article B to explain something. Then, Article B becomes outdated. Thus, one "patches" Article A with a quick overview of Article B that doesn't fit in with the rest of Article A's content. - One updates 3 out of 10 articles. One article says `X is true` whereas another says `X is false`. A new learner isn't sure which is correct. Updating documentation in light of frequent changes often requires less overall work. From 2f4ae26e27d6f518671f2608e3896f689ae359c8 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Mon, 1 Apr 2019 18:25:58 -0700 Subject: [PATCH 094/133] Replace probably offensive/hypocritcal summary statement --- .../State-of-PureScript-Documentation-2019.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 681e526..fadca8f 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -195,8 +195,7 @@ However, it seems they are (wisely) postponing "breaking changes" until all can Due to the looming "breaking changes," those who want to improve the documentation situation are often discouraged from improving it. They tend to think, "Why invest many hours into something that will be outdated in a few months? Why not invest those hours into something else, like an interesting project or learning something new?" [further explained here]() -The following statement is not to blame people or point fingers. Rather, it summarizes our current reality: -> Core contributors are doing great and their pace is just fine. Still, we're in a sort of catch-22 situation. The longer the core contributors take to implement these breaking changes, the longer most documentation writers will wait to avoid unnecessary updates, and the longer we'll be in this situation. +Fixing this situation is not as simple as it sounds. You can't "just delegate" their work to anyone. Others attempted to fund core contributors. However, the effort was likely stopped due to not having a clear idea of how the funds would be spent. [further explained here]() Moreover, there are other factors independent of the "breaking changes" issues. 1. Until recently (it's fixed now), an OOM error was preventing some popular libraries from uploading their API docs. Even those familiar with the language had difficulty knowing how to use some libraries. [further explained here]() From 081bb57df25cd091c545be210fa2a267eb908c53 Mon Sep 17 00:00:00 2001 From: Alex Berg Date: Sat, 13 Apr 2019 12:25:39 -0500 Subject: [PATCH 095/133] Qualify parties who are concerned about PS docs (#64) --- .../State-of-PureScript-Documentation-2019.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index fadca8f..d27e543 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -2,7 +2,7 @@ This document is not meant to convince you to use PureScript, we assume that readers are already interested in it or using it. -It is well-known amongst the PureScript community that its documentation is lacking in some critical areas. As a result, @chexxor started the [PureScript documentation efforts in 2019](https://discourse.purescript.org/t/purescript-documentation-efforts-in-2019/524) Discourse thread to answer one question: +Numerous parties within the PureScript community (e.g. [core contributors](), [users](), [new learners]()) believe that the documentation is lacking in some critical areas. As a result, @chexxor started the [PureScript documentation efforts in 2019](https://discourse.purescript.org/t/purescript-documentation-efforts-in-2019/524) Discourse thread to answer one question: > How can we improve the PureScript documentation in 2019? (Purpose) The following document tries to do the following things: From 4c7b13579b212b70c6626176f80e6d154ed043a2 Mon Sep 17 00:00:00 2001 From: Alex Berg Date: Sat, 13 Apr 2019 12:30:58 -0500 Subject: [PATCH 096/133] Note the few number of sources for "good" docs (#63) Note the few number of sources for "good" docs --- .../State-of-PureScript-Documentation-2019.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index d27e543..a9172f3 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -42,6 +42,8 @@ Essentially, there are 3 factors that affect whether documentation is "good" or 2. Its type: the question being answered, targeting a specific subsection of the audience 3. How accurately it reflects the desired version of the code/project +It's important to note that this section is sourced from only two blog posts, [What Nobody Tells You About Documentation](https://www.divio.com/blog/documentation/) and [Teach, Don't Tell](http://stevelosh.com/blog/2013/09/teach-dont-tell/). As we learn more this section might change in significant ways, so any conclusions we draw should be kept "flexible". + ### The Types of Documentation First, there are 5 types of documentation that target specific phases of a learner's experience (as explained in [What Nobody Tells You About Documentation](https://www.divio.com/blog/documentation/) and [Teach, Don't Tell](http://stevelosh.com/blog/2013/09/teach-dont-tell/)) From 0c798ab1eb386971ca5cb89570618cc47064bea6 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 13 Apr 2019 14:35:20 -0700 Subject: [PATCH 097/133] Port 'what is good docs anyway' section into own file and backlink to it --- 02-Context-or-Narrative/Good-Documentation.md | 124 ++++++++++++++++++ .../State-of-PureScript-Documentation-2019.md | 104 +-------------- 2 files changed, 126 insertions(+), 102 deletions(-) create mode 100644 02-Context-or-Narrative/Good-Documentation.md diff --git a/02-Context-or-Narrative/Good-Documentation.md b/02-Context-or-Narrative/Good-Documentation.md new file mode 100644 index 0000000..796b975 --- /dev/null +++ b/02-Context-or-Narrative/Good-Documentation.md @@ -0,0 +1,124 @@ +# Good Documentation + +## What is "Good" Documentation Anyway? + +Did someone ever teach you how to write "good" documentation? Probably not - you likely just wrote what came to mind and hoped it was good enough. + +Because of this, it's useful to learn a definition of good documentation and understand why it's defined that way. + +Essentially, there are 3 factors that affect whether documentation is "good" or not. +1. Its intended audience +2. Its type: the question being answered, targeting a specific subsection of the audience +3. How accurately it reflects the desired version of the code/project + +It's important to note that this section is sourced from only two blog posts, [What Nobody Tells You About Documentation](https://www.divio.com/blog/documentation/) and [Teach, Don't Tell](http://stevelosh.com/blog/2013/09/teach-dont-tell/). As we learn more this section might change in significant ways, so any conclusions we draw should be kept "flexible". + +### The Types of Documentation + +First, there are 5 types of documentation that target specific phases of a learner's experience (as explained in [What Nobody Tells You About Documentation](https://www.divio.com/blog/documentation/) and [Teach, Don't Tell](http://stevelosh.com/blog/2013/09/teach-dont-tell/)) + +| Learner's Phase | Type | Analogy | Characteristics +| -- | -- | -- | -- | +| Curious Outsider | The Hook | Selling a product to a potential customer | Answers these questions:
  • What is this thing? / What problem does it solve?
  • Why whould I care? / How is this relevant to me for my purposes? / Who should not care?
  • How long will it take to learn it and how difficult is the learning curve?
  • Where do I go to get started / learn how to use this?
+| Potential User | Getting Started | Teaching a child how to cook |
  • Focuses on the learner 'doing' stuff, not 'explaining' stuff to the learner
  • Provides a small simple working example that teaches the basics
  • New learners experience an 'I can use this now!' moment by the end
  • Focuses on concrete tasks, not abstract concepts
  • Does not use jargon
  • Explains only what is necessary and cuts out all else
  • Avoids explaining deeper concepts or different ways of doing the same thing
+| New User | How-To Guides | Following a cookbook's recipe |
  • Achieves some goal or solves a problem
  • States the pre-requisites one needs to have before starting (not a Getting Started Guide)
  • The Guide follows a clearly-labeled step-by-step process
  • By following the steps, one reproduces the same results without fail
  • Explains the different ways one can achieve the same goal
  • Explains only what is necessary
+| Active User | Reference | Reading an encyclopedia |
  • Concise explanation of each piece of the code
  • The structure of the reference mirrors the structure of the code it documents
  • Formatting is consistent throughout the material
+| Experienced User | Explanation | Listening to a CEO answer questions about his company |
  • Explains the context/history
  • Explains the significant design decisions made, their alternativees, and the reasons one was chosen over another
  • Implies where things could be improved, expanded, refined, etc.
+ +Moreover, there are clear examples of "bad" documentation (as explained in [Teach, Don't Tell](http://stevelosh.com/blog/2013/09/teach-dont-tell/)): + +| Documentation Source | Why it's bad | +| -- | -- | +| Source Code | Only useful once you are already familiar with it +| Test Code | While it uses the code, it tends to focus on edge cases, not normal cases, and may not use all possible options/configurations. +| API docs | One must know the name of the function/value to be able to read its documentation. Most won't know the name until you teach it to them. Likewise, people don't learn by reading alphabetized lists of disconnected information +| Wiki | Content is usually not written by the code's authors, but by multiple 3rd-party people. There are often multiple disconnected voices throughout the material. It's like asking a student to write his own lesson plan. + +### The Documentation's Intended Audience + +Second, the number of intended audiences can vary greatly. For example, here are different ways of categorizing them: +- The language/paradigms they primarily use and think in (e.g. JavaScript, Ruby, Haskell; lazy, strict; OO, FP; etc.) +- The amount of experience they have (e.g. never coded before, junior, senior, etc.) +- The programs they are looking to create (e.g. games, financial applications, cryptography, etc.) + +Writing documentation that targets JavaScript-background junior developers who want to write games will focus on some things, exclude others, and order its content in a way that makes most sense to that purpose. + +As a result, others who read the resulting documentation will consider it "poor" in some aspect: +- If one comes from a non-JavaScript language, one might find references to features in JavaScript confusing: "They used the concept of 'prototypes' to explain something, but that left me even more confused..." ~ a Java developer +- If one comes from a different experience level, one might have unanswered questions: "They didn't even mention what the performance trade-offs for specific libraries were..." ~ a senior developer +- If one has a different goal in mind, some crucial libraries might never be covered: "They didn't explain how I can make my Bitcoin client cryptographically secure..." + +### Maintaining Documentation's Accuracy + +Third, documentation becomes outdated/inaccurate when the thing being documented changes in two ways: +- the 'size' of a change +- the 'frequency' of changes + +#### The "Size" of a Change + +The 'size' of a change can decrease its usefulness. + +| "Size" | Example +| -- | -- | +| Small | A bug fix that affects little else. +| Medium | A new feature +| Large | One or more breaking changes affecting numerous things simultaneously + +When breaking changes occur, documentation can immediately become useless because: +- none of its code examples work anymore +- old terms might mean something different now +- some new parts may need be written +- some parts of the documentation might no longer be relevant +- one needs to figure out how to integrate new content into old content + +Updating documentation in light of breaking changes often requires the most work to update. + +#### The "Frequency" of a Change + +The 'frequency' of a change can decrease its coherence. + +| "Frequency" | Example +| -- | -- | +| Rarely | Stable libraries that have exhausted their design space (e.g. core data types) +| Sometimes | Maturing libraries that still have a few things to fix or add +| Frequently | New libraries + +When changes occur frequently, documentation can appear more like loosely-coupled snippets of ideas rather than a coherent explanation because: +- Article A depends on Article B to explain something. Then, Article B becomes outdated. Thus, one "patches" Article A with a quick overview of Article B that doesn't fit in with the rest of Article A's content. +- One updates 3 out of 10 articles. One article says `X is true` whereas another says `X is false`. A new learner isn't sure which is correct. + +Updating documentation in light of frequent changes often requires less overall work. + +#### How to Make Maintenance Easier + +Moreover, when breaking changes occur frequently, it discourages people from updating the documentation. Why waste time on something that will become outdated soon? + +The nature of this problem is not going to change. So, what medium of documentation provides the most "bang for your buck" long-term that is also is easiest to update? + +Heavily-commented code examples. + +It follows the principle of "show, don't tell." People can use them as a model from which to learn and as a playground on which to experiment. + +Other mediums of documentation (e.g. blog posts, literate programming, videos) each have their place. However, the code examples might produce the easiest-to-update documentation in the shortest time possible. + +Lastly, some documentations tasks are tedious and consume lots of time. Finding ways to automate them can greatly improve the situation. + +### Criteria for "Good" Documentation + +In short, it is impossible to write "good" documentation for everyone that is always up-to-date. There's simply not enough manpower, time, and incentives to do that. Rather, it will be "good", "horrible", or "somewhere in-between" for diffent kinds of people and at different times/seasons. + +Still, we can define our criteria for "good" documentation using these four factors. Documentation is "good" when: +- [Type] + - It states which type of documentation it is + - It abides by that type's characteristics +- [Audience] + - It states who the intended audience is + - For those who aren't the intended audience, it refers to other material that better suits them +- [Accuracy] + - It tends to be heavier on code examples rather than other mediums + - It explains which version of the code it documents + - If it's not the most recent version, it provides: + - A brief idea of where it is outdated + - Guidelines for how to understand the outdated explanation in light of new changes + - It includes the date it was published and when it was last updated + - It indicates whether it will be updated in the future (and when) or has been abandoned and no future updates will occur. diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index a9172f3..5e030d5 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -33,20 +33,9 @@ Numerous parties within the PureScript community (e.g. [core contributors](), [u ## What is "Good" Documentation Anyway? -Did someone ever teach you how to write "good" documentation? Probably not - you likely just wrote what came to mind and hoped it was good enough. +This section is sourced from only two blog posts, [What Nobody Tells You About Documentation](https://www.divio.com/blog/documentation/) and [Teach, Don't Tell](http://stevelosh.com/blog/2013/09/teach-dont-tell/). As we learn more this section might change in significant ways, so any conclusions we draw should be kept "flexible". -Because of this, it's useful to learn a definition of good documentation and understand why it's defined that way. - -Essentially, there are 3 factors that affect whether documentation is "good" or not. -1. Its intended audience -2. Its type: the question being answered, targeting a specific subsection of the audience -3. How accurately it reflects the desired version of the code/project - -It's important to note that this section is sourced from only two blog posts, [What Nobody Tells You About Documentation](https://www.divio.com/blog/documentation/) and [Teach, Don't Tell](http://stevelosh.com/blog/2013/09/teach-dont-tell/). As we learn more this section might change in significant ways, so any conclusions we draw should be kept "flexible". - -### The Types of Documentation - -First, there are 5 types of documentation that target specific phases of a learner's experience (as explained in [What Nobody Tells You About Documentation](https://www.divio.com/blog/documentation/) and [Teach, Don't Tell](http://stevelosh.com/blog/2013/09/teach-dont-tell/)) +There are 5 types of documentation that target specific phases of a learner's experience (as explained in [What Nobody Tells You About Documentation](https://www.divio.com/blog/documentation/) and [Teach, Don't Tell](http://stevelosh.com/blog/2013/09/teach-dont-tell/)) | Learner's Phase | Type | Analogy | Characteristics | -- | -- | -- | -- | @@ -65,95 +54,6 @@ Moreover, there are clear examples of "bad" documentation (as explained in [Teac | API docs | One must know the name of the function/value to be able to read its documentation. Most won't know the name until you teach it to them. Likewise, people don't learn by reading alphabetized lists of disconnected information | Wiki | Content is usually not written by the code's authors, but by multiple 3rd-party people. There are often multiple disconnected voices throughout the material. It's like asking a student to write his own lesson plan. -### The Documentation's Intended Audience - -Second, the number of intended audiences can vary greatly. For example, here are different ways of categorizing them: -- The language/paradigms they primarily use and think in (e.g. JavaScript, Ruby, Haskell; lazy, strict; OO, FP; etc.) -- The amount of experience they have (e.g. never coded before, junior, senior, etc.) -- The programs they are looking to create (e.g. games, financial applications, cryptography, etc.) - -Writing documentation that targets JavaScript-background junior developers who want to write games will focus on some things, exclude others, and order its content in a way that makes most sense to that purpose. - -As a result, others who read the resulting documentation will consider it "poor" in some aspect: -- If one comes from a non-JavaScript language, one might find references to features in JavaScript confusing: "They used the concept of 'prototypes' to explain something, but that left me even more confused..." ~ a Java developer -- If one comes from a different experience level, one might have unanswered questions: "They didn't even mention what the performance trade-offs for specific libraries were..." ~ a senior developer -- If one has a different goal in mind, some crucial libraries might never be covered: "They didn't explain how I can make my Bitcoin client cryptographically secure..." - -### Maintaining Documentation's Accuracy - -Third, documentation becomes outdated/inaccurate when the thing being documented changes in two ways: -- the 'size' of a change -- the 'frequency' of changes - -#### The "Size" of a Change - -The 'size' of a change can decrease its usefulness. - -| "Size" | Example -| -- | -- | -| Small | A bug fix that affects little else. -| Medium | A new feature -| Large | One or more breaking changes affecting numerous things simultaneously - -When breaking changes occur, documentation can immediately become useless because: -- none of its code examples work anymore -- old terms might mean something different now -- some new parts may need be written -- some parts of the documentation might no longer be relevant -- one needs to figure out how to integrate new content into old content - -Updating documentation in light of breaking changes often requires the most work to update. - -#### The "Frequency" of a Change - -The 'frequency' of a change can decrease its coherence. - -| "Frequency" | Example -| -- | -- | -| Rarely | Stable libraries that have exhausted their design space (e.g. core data types) -| Sometimes | Maturing libraries that still have a few things to fix or add -| Frequently | New libraries - -When changes occur frequently, documentation can appear more like loosely-coupled snippets of ideas rather than a coherent explanation because: -- Article A depends on Article B to explain something. Then, Article B becomes outdated. Thus, one "patches" Article A with a quick overview of Article B that doesn't fit in with the rest of Article A's content. -- One updates 3 out of 10 articles. One article says `X is true` whereas another says `X is false`. A new learner isn't sure which is correct. - -Updating documentation in light of frequent changes often requires less overall work. - -#### How to Make Maintenance Easier - -Moreover, when breaking changes occur frequently, it discourages people from updating the documentation. Why waste time on something that will become outdated soon? - -The nature of this problem is not going to change. So, what medium of documentation provides the most "bang for your buck" long-term that is also is easiest to update? - -Heavily-commented code examples. - -It follows the principle of "show, don't tell." People can use them as a model from which to learn and as a playground on which to experiment. - -Other mediums of documentation (e.g. blog posts, literate programming, videos) each have their place. However, the code examples might produce the easiest-to-update documentation in the shortest time possible. - -Lastly, some documentations tasks are tedious and consume lots of time. Finding ways to automate them can greatly improve the situation. - -### Criteria for "Good" Documentation - -In short, it is impossible to write "good" documentation for everyone that is always up-to-date. There's simply not enough manpower, time, and incentives to do that. Rather, it will be "good", "horrible", or "somewhere in-between" for diffent kinds of people and at different times/seasons. - -Still, we can define our criteria for "good" documentation using these four factors. Documentation is "good" when: -- [Type] - - It states which type of documentation it is - - It abides by that type's characteristics -- [Audience] - - It states who the intended audience is - - For those who aren't the intended audience, it refers to other material that better suits them -- [Accuracy] - - It tends to be heavier on code examples rather than other mediums - - It explains which version of the code it documents - - If it's not the most recent version, it provides: - - A brief idea of where it is outdated - - Guidelines for how to understand the outdated explanation in light of new changes - - It includes the date it was published and when it was last updated - - It indicates whether it will be updated in the future (and when) or has been abandoned and no future updates will occur. - ### Evaluating PureScript's Documentation Here was PureScript's documentation as of July 2018: From ab2fe590f38c75a8ce8ca7e0a9e7105a858e096b Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 13 Apr 2019 14:36:33 -0700 Subject: [PATCH 098/133] Move less important information to the bottom People who are more inclined to study this can read through the more detailed section and the referenced blog posts. --- .../State-of-PureScript-Documentation-2019.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 5e030d5..8e48d0e 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -33,8 +33,6 @@ Numerous parties within the PureScript community (e.g. [core contributors](), [u ## What is "Good" Documentation Anyway? -This section is sourced from only two blog posts, [What Nobody Tells You About Documentation](https://www.divio.com/blog/documentation/) and [Teach, Don't Tell](http://stevelosh.com/blog/2013/09/teach-dont-tell/). As we learn more this section might change in significant ways, so any conclusions we draw should be kept "flexible". - There are 5 types of documentation that target specific phases of a learner's experience (as explained in [What Nobody Tells You About Documentation](https://www.divio.com/blog/documentation/) and [Teach, Don't Tell](http://stevelosh.com/blog/2013/09/teach-dont-tell/)) | Learner's Phase | Type | Analogy | Characteristics @@ -54,6 +52,8 @@ Moreover, there are clear examples of "bad" documentation (as explained in [Teac | API docs | One must know the name of the function/value to be able to read its documentation. Most won't know the name until you teach it to them. Likewise, people don't learn by reading alphabetized lists of disconnected information | Wiki | Content is usually not written by the code's authors, but by multiple 3rd-party people. There are often multiple disconnected voices throughout the material. It's like asking a student to write his own lesson plan. +Note: this section is sourced from only two blog posts, [What Nobody Tells You About Documentation](https://www.divio.com/blog/documentation/) and [Teach, Don't Tell](http://stevelosh.com/blog/2013/09/teach-dont-tell/). As we learn more this section might change in significant ways, so any conclusions we draw should be kept "flexible". + ### Evaluating PureScript's Documentation Here was PureScript's documentation as of July 2018: From 1db153329cff241647a907c313df898ec14d92a5 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 13 Apr 2019 14:39:44 -0700 Subject: [PATCH 099/133] Rerender the 'only comes from two blog posts' concern --- .../State-of-PureScript-Documentation-2019.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 8e48d0e..f38818a 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -52,7 +52,7 @@ Moreover, there are clear examples of "bad" documentation (as explained in [Teac | API docs | One must know the name of the function/value to be able to read its documentation. Most won't know the name until you teach it to them. Likewise, people don't learn by reading alphabetized lists of disconnected information | Wiki | Content is usually not written by the code's authors, but by multiple 3rd-party people. There are often multiple disconnected voices throughout the material. It's like asking a student to write his own lesson plan. -Note: this section is sourced from only two blog posts, [What Nobody Tells You About Documentation](https://www.divio.com/blog/documentation/) and [Teach, Don't Tell](http://stevelosh.com/blog/2013/09/teach-dont-tell/). As we learn more this section might change in significant ways, so any conclusions we draw should be kept "flexible". +Note: this section is sourced from only two blog posts, [What Nobody Tells You About Documentation](https://www.divio.com/blog/documentation/) and [Teach, Don't Tell](http://stevelosh.com/blog/2013/09/teach-dont-tell/). Understand these as a starting point for defining a criteria for "good" documentation, not a final "there's nothing more to say" conclusion. ### Evaluating PureScript's Documentation From 730dfae929075bc56122e4a0eef3cb64e0f31c58 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 13 Apr 2019 14:55:03 -0700 Subject: [PATCH 100/133] Port 'why docs are lacking' section to own file but keep initial summary --- .../State-of-PureScript-Documentation-2019.md | 182 +----------------- .../Why-Docs-Are-Lacking.md | 181 +++++++++++++++++ 2 files changed, 182 insertions(+), 181 deletions(-) create mode 100644 02-Context-or-Narrative/Why-Docs-Are-Lacking.md diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index f38818a..a55f57a 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -52,7 +52,7 @@ Moreover, there are clear examples of "bad" documentation (as explained in [Teac | API docs | One must know the name of the function/value to be able to read its documentation. Most won't know the name until you teach it to them. Likewise, people don't learn by reading alphabetized lists of disconnected information | Wiki | Content is usually not written by the code's authors, but by multiple 3rd-party people. There are often multiple disconnected voices throughout the material. It's like asking a student to write his own lesson plan. -Note: this section is sourced from only two blog posts, [What Nobody Tells You About Documentation](https://www.divio.com/blog/documentation/) and [Teach, Don't Tell](http://stevelosh.com/blog/2013/09/teach-dont-tell/). Understand these as a starting point for defining a criteria for "good" documentation, not a final "there's nothing more to say" conclusion. +Note: this section is sourced from only two blog posts, [What Nobody Tells You About Documentation](https://www.divio.com/blog/documentation/) and [Teach, Don't Tell](http://stevelosh.com/blog/2013/09/teach-dont-tell/). Understand these as a starting point for defining a criteria for "good" documentation, not a final "there's nothing more to say" conclusion. ### Evaluating PureScript's Documentation @@ -105,186 +105,6 @@ Moreover, there are other factors independent of the "breaking changes" issues. Finally, it is difficult to define what are FP's "best practices / design patterns." This issue won't go away even if all 'breaking changes' have been implemented. [further explained here]() -### PureScript is not _currently_ trying to be the next "mainstream language" - -A few have wrongly assumed that PureScript is trying to replace [insert your favorite web language here]. That is not the case. - -PureScript has the following philosophy: -> Making a language "popular" (e.g. industry-standard, taught in universities' curriculums, etc.) is not a justification for decreasing its "power," such as limiting the language's expressiveness, making it less safe, less secure, etc. -> -> Making the language easier to use and learn by improving it is good and supported. -> Achieving the same goals by crippling, downgrading, or dumbing down the language is rejected. Users will either learn it properly or use something else. -> -> Plenty of languages chose to sacrifice safety, security, efficiency, etc. to gain the benefits of "popularity." -> -> PureScript will not be another such language. Rather, it will try to progress in "the right way," even when it's inconvenient, makes it harder to learn, etc. -> -> ~ Summary of [A Response that Explains the Motto: 'Avoid (Success at All Costs)'](https://news.ycombinator.com/item?id=12056169) (edits made: replaced 'Haskell' with 'PureScript'; removed "research-related concepts") - -While typically stated differently, one could summarize this philosophy as "value power and expressivity over popularity." - -The current focus (see later point) is not on making documentation great. Rather, it's on implementing the language features that haven't yet been implemented. - -However, even if great documentation was the focus, one will still have to learn difficult concepts before they can be productive. This fact will never change. - -Thus, PureScript might not be the language for you: -- If you value 'popularity' over 'power,' use a different language. -- If you value 'power' over 'popularity' and are determined to learn hard things, use this language. - -(Related interpretation sections: [Keeping the motto of `Avoid "success at all costs"` and understanding its meaning](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#knowing-whom-to-trust-with-write-access-defining-best-workflow-procedures-and-providing-necessary-support)) - -### Only core contributors have write / deployment privileges to PureScript websites - -The following PureScript websites either are outdated or could be modified to improve the documentation situation. - -Who can merge PRs into the websites' repositories and redeploy them once these PRs are merged? - -| Site | Write Privilege | Deploy Privelege | Source -| -- | -- | -- | -- | -| PureScript language website | Core Contributors | None. GitHub Pages | - -| Pursuit | Core Contributors | Phil Freeman | [The State of Things, point 2](https://discourse.purescript.org/t/the-state-of-things/282) -| Try PureScript | Core Contributors | Phil Freeman | [The State of Things, point 2](https://discourse.purescript.org/t/the-state-of-things/282) - -### Core contributors are spread thin - -> It’s been 7 months since I announced that I would be taking a long break from PureScript development.... -> -> In retrospect, I think it’s fair to say that I was quite thoroughly burned out from trying to balance open source work and real life. -> -> I still love to _use_ PureScript, and I’ve been working to increase PureScript adoption at work.... -> -> ~ Phil Freeman, the creator of the PureScript language [(1st & 2nd paragraph)](https://discourse.purescript.org/t/the-state-of-things/282) - -The following quote is a response to another's "wallowing:" - -> Just to wallow for a second, I... -> - contribute to/review stuff on the compiler -> - attempt to keep on top of the issues, discussions, PRs on roughly 75 libraries (some of which are tiny and almost never change, some of which are purescript-dom :grimacing:) -> - engage with people on Twitter, StackOverflow, Reddit, Slack -> - and very occasionally investigate some idea of my own. -> -> So unless I stop doing some of that, there's no chance I can make any meaningful steps to improving the documentation situation. -> -> ~ Gary Burgess, a core contributor ([2nd paragraph](https://gist.github.com/marick/e8b01375309fafaefb879c4840b6da75#gistcomment-2569261), edits made: content was turned into a list; "..." changed to "," for readability) - -After reading such statements, we can only step back and ask, -- Are the core contributors doing ok? -- Are you getting enough rest? -- Are you still investing in meaningful relationships? -- Is contributing to PureScript still enjoyable to you or has it become burdensome? - -Thank you for the language you have created, the libraries you wrote and maintain, and all the other things you have done for the benefit of this language and its ecosystem. - -Thank you for putting up with frustrating people, enduring negative and impatient attitudes, and trolls. - -#### Implications - -Reviewing documentation can be just as difficult as reviewing code. Some people are faster at reviewing things than others. - -Thus, maintaining momentum when documenting code is difficult: -- Some documentation PRs are missed/forgotten. -- Many do not get a timely response from core contributors (one may wait for weeks) -- Some do not get merged in a timely manner either. - -Lastly, I (Jordan) don't know whether some tasks could be automated and whether that would help. - -(Related interpretation sections: [Limited Manpower / Not Enough Automation](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#limited-manpower--not-enough-automation), [Slow submitted-reviewed-merged timeline of documentation kills momentum](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#slow-submitted-reviewed-merged-timeline-of-documentation-prs-kills-documentation-momentum), [Reviewing documentation PRS can be just as difficult as code PRs](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#reviewing-documentation-prs-can-be-just-as-difficult-as-code-prs)) - -#### Why Not Just Delegate? - -> A hypothetical developer says, "If it's so much work, why not just **delegate** the work? This 'somebody' can also be a proxy who's gathering feedback, so that you don't have to be in these discussions." -> -> The contributor responds sarcastically, "Oh! Delegation, of course! I hadn't thought about that...." -> -> There's actually an assumption going on here: "If 'free' rice means you can take as much as you want, then 'free' labor implies you can take as much as you want." But that isn't how labor works. If you don't pay for labor, you get less. -> -> Even if everyone could help, there's still limitations due to coordinating efforts: who does what, when, and where, and all without affecting someone else's work. -> -> ~ summary of the 'Why Not Just... Pattern' in [The Hard Parts of Open Source](https://youtu.be/o_4EX4dPppA?t=257) - -One shouldn't trust everyone on the internet. (I know, big surprise.) - -For example, consider the `event-stream incident`. The maintainer unknowingly gave write-access to a malicious actor. Practically everyone depends on this code. The actor injected code that could be used to steal bitcoins: -- [initial issue](https://github.com/dominictarr/event-stream/issues/116) -- [injected code explanation](https://github.com/dominictarr/event-stream/issues/116#issuecomment-441759047) -- [original maintainer's response](https://github.com/dominictarr/event-stream/issues/116) -- [a sarcastic blog post summarizing this class of attack](https://hackernoon.com/im-harvesting-credit-card-numbers-and-passwords-from-your-site-here-s-how-9a8cb347c5b5) - -New maintainers, once found and properly screened, have to be supported (which takes time and thought), so that they can actually fulfill their role. If they decide to leave soon after starting, then one has wasted time and effort. - -(Related interpretation sections: [Knowing whom to trust with write access, defining best workflow procedures, and providing necessary support](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#knowing-whom-to-trust-with-write-access-defining-best-workflow-procedures-and-providing-necessary-support)) - -#### Why Not Just Fund the Language Developers? - -Been there, done that. Someone took it down. ([PureScript Open Collective]((https://opencollective.com/purescript)) - -Our viewpoint of this situation: -- Fans of PureScript wanted to throw money at the project. Why? Perhaps because - - they want to help the project and its goals - - they dont have the time or mental capacity to contribute -- Several people used OpenCollective to indicate they'd like to pledge money to the "github.com/purescript/purescript" project. -- Several weeks later, someone claimed that project's corresponding OpenCollective page and turned off the public page. -- We believe this was because there was no clear vision as to how the funds would be spent. - -Perhaps this idea could be revisited in the future. For now, we cannot say. - -### Breaking Changes Outdate Documentation and Kill Documenters' Motivation - -The main 'go-to' documentation resource for PureScript was/is [PureScript By Example](https://leanpub.com/purescript/) by Phil Freeman. This resource documents the `0.11.7` PureScript release. The current PureScript release is `0.12.3` (as of this writing). - -The `0.12.0` was a significant achievement but one that came with a lot of breaking changes. Phil responded to it in this way: - -> [The PureScript by Example book] seems to take longer [to update] with each major compiler update, and honestly, I’m not motivated to update it again without some sort of guarantee that I won’t have to redo everything again in a few months.... -> I would like to write a lot more documentation for PureScript, but I hate the idea that it will become out of date quickly.... -> So without some sort of plan for the future of the language, and some idea of what changes are coming (and just as importantly, which aren’t), I’m not likely to write anything, and I wouldn’t be surprised if others avoided writing for the same reason. -> -> ~ Phil Freeman [The State of Things, point 4](https://discourse.purescript.org/t/the-state-of-things/282) - -Gary later pointed out that releases with "breaking changes" were occuring less frequently ([source](https://docs.google.com/spreadsheets/d/1MO8siLLSOpkKHJ_eBNRJbipBquFgqlaSS-QSnALDSo8/edit#gid=0)). Still, keep in mind that Phil was likely updating the book each time such a release was made. - -(Related interpretation sections: [Breaking Changes Render Documentation Outdated](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#breaking-changes-renders-documentation-outdated)) - -### There Is No Roadmap That Coordinates Efforts - -Defining a roadmap is hard. It's easy to... -- ...disagree on which goals should be pursued and which to ignore -- ...disagree on how to word such goals -- ...do nothing and let someone else contribute - -Creating a "good" roadmap takes significant time and energy. - -PureScript does not currently have such a roadmap. Rather, core contributors seem to have a general direction they are pursuing (see next point). - -Therefore: -- Those who could help do not know where help is needed -- Those who would help do not know how they can help - -#### Avoiding a `v1.0` PureScript language release - -When people announce "Language X is now `1.0`!", it tends to draw a lot of focus and a lot of traffic. People probably think, "Wow! It's now stable enough to be used to write all my programs." - -In short, one core contributor believes that many would perceive a `v1.0` release as a `v1.0` ecosystem release. The language could be considered 'good enough' for a `v1.0`. However, the ecosystem is definitely not. - -What good is a `v1.0` language, if -- common libraries haven't stabilized yet or are non-existant? -- the ecosystem is incoherent in a number of ways? -- the dependency managers are still unfriendly to users? -- the IDE support is still lacking? - -Thus, core contributors might avoid defining a roadmap to prevent people from having a `v1.0` ecosystem connotation. - -#### Defining a Language Specification - -When should future breaking changes be done: before a `v1.0` or afterwards? - -`garyb`, a core contributor, has resisted efforts to define a language specification. Why? Because he wants to add two features that will require breaking changes: "poly-kinds and something that requires qualified constraints." ([The State of Things, 6th paragraph in his comment](https://discourse.purescript.org/t/the-state-of-things/282/5)) - -If done before a `v1.0`, then the language will likely be stable, documentation will not go out of date, and the ecosystem can flourish. - -If done after a `v1.0`, then many libraries and docs will need to be updated, the language's reputation might suffer, and people might be forever turned off to it. - -(Related interpretation sections: [Lack of a clearly-defined communit-wide mutually-held vision/goal](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#lack-of-a-clearly-defined-community-wide-mutually-held-visiongoal), [Lack of a clearly-defined core-contributor-wide mutually-held language specification](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#lack-of-a-clearly-defined-core-contributor-wide-mutually-held-language-specification), [Fear that people will misinterpret at "v1.0" compiler release for a "v1.0" ecosystem release](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#fear-that-people-will-misinterpret-a-v10-compiler-release-for-a-v10-ecosystem-release)) - ### Some libraries cannot publish their docs due to OOM error From [pulp version runs out of memory (fatal exception) - Issue 351](https://github.com/purescript-contrib/pulp/issues/351): diff --git a/02-Context-or-Narrative/Why-Docs-Are-Lacking.md b/02-Context-or-Narrative/Why-Docs-Are-Lacking.md new file mode 100644 index 0000000..3e3207c --- /dev/null +++ b/02-Context-or-Narrative/Why-Docs-Are-Lacking.md @@ -0,0 +1,181 @@ +# Why Docs Are Lacking + +### PureScript is not _currently_ trying to be the next "mainstream language" + +A few have wrongly assumed that PureScript is trying to replace [insert your favorite web language here]. That is not the case. + +PureScript has the following philosophy: +> Making a language "popular" (e.g. industry-standard, taught in universities' curriculums, etc.) is not a justification for decreasing its "power," such as limiting the language's expressiveness, making it less safe, less secure, etc. +> +> Making the language easier to use and learn by improving it is good and supported. +> Achieving the same goals by crippling, downgrading, or dumbing down the language is rejected. Users will either learn it properly or use something else. +> +> Plenty of languages chose to sacrifice safety, security, efficiency, etc. to gain the benefits of "popularity." +> +> PureScript will not be another such language. Rather, it will try to progress in "the right way," even when it's inconvenient, makes it harder to learn, etc. +> +> ~ Summary of [A Response that Explains the Motto: 'Avoid (Success at All Costs)'](https://news.ycombinator.com/item?id=12056169) (edits made: replaced 'Haskell' with 'PureScript'; removed "research-related concepts") + +While typically stated differently, one could summarize this philosophy as "value power and expressivity over popularity." + +The current focus (see later point) is not on making documentation great. Rather, it's on implementing the language features that haven't yet been implemented. + +However, even if great documentation was the focus, one will still have to learn difficult concepts before they can be productive. This fact will never change. + +Thus, PureScript might not be the language for you: +- If you value 'popularity' over 'power,' use a different language. +- If you value 'power' over 'popularity' and are determined to learn hard things, use this language. + +(Related interpretation sections: [Keeping the motto of `Avoid "success at all costs"` and understanding its meaning](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#knowing-whom-to-trust-with-write-access-defining-best-workflow-procedures-and-providing-necessary-support)) + +### Only core contributors have write / deployment privileges to PureScript websites + +The following PureScript websites either are outdated or could be modified to improve the documentation situation. + +Who can merge PRs into the websites' repositories and redeploy them once these PRs are merged? + +| Site | Write Privilege | Deploy Privelege | Source +| -- | -- | -- | -- | +| PureScript language website | Core Contributors | None. GitHub Pages | - +| Pursuit | Core Contributors | Phil Freeman | [The State of Things, point 2](https://discourse.purescript.org/t/the-state-of-things/282) +| Try PureScript | Core Contributors | Phil Freeman | [The State of Things, point 2](https://discourse.purescript.org/t/the-state-of-things/282) + +### Core contributors are spread thin + +> It’s been 7 months since I announced that I would be taking a long break from PureScript development.... +> +> In retrospect, I think it’s fair to say that I was quite thoroughly burned out from trying to balance open source work and real life. +> +> I still love to _use_ PureScript, and I’ve been working to increase PureScript adoption at work.... +> +> ~ Phil Freeman, the creator of the PureScript language [(1st & 2nd paragraph)](https://discourse.purescript.org/t/the-state-of-things/282) + +The following quote is a response to another's "wallowing:" + +> Just to wallow for a second, I... +> - contribute to/review stuff on the compiler +> - attempt to keep on top of the issues, discussions, PRs on roughly 75 libraries (some of which are tiny and almost never change, some of which are purescript-dom :grimacing:) +> - engage with people on Twitter, StackOverflow, Reddit, Slack +> - and very occasionally investigate some idea of my own. +> +> So unless I stop doing some of that, there's no chance I can make any meaningful steps to improving the documentation situation. +> +> ~ Gary Burgess, a core contributor ([2nd paragraph](https://gist.github.com/marick/e8b01375309fafaefb879c4840b6da75#gistcomment-2569261), edits made: content was turned into a list; "..." changed to "," for readability) + +After reading such statements, we can only step back and ask, +- Are the core contributors doing ok? +- Are you getting enough rest? +- Are you still investing in meaningful relationships? +- Is contributing to PureScript still enjoyable to you or has it become burdensome? + +Thank you for the language you have created, the libraries you wrote and maintain, and all the other things you have done for the benefit of this language and its ecosystem. + +Thank you for putting up with frustrating people, enduring negative and impatient attitudes, and trolls. + +#### Implications + +Reviewing documentation can be just as difficult as reviewing code. Some people are faster at reviewing things than others. + +Thus, maintaining momentum when documenting code is difficult: +- Some documentation PRs are missed/forgotten. +- Many do not get a timely response from core contributors (one may wait for weeks) +- Some do not get merged in a timely manner either. + +Lastly, I (Jordan) don't know whether some tasks could be automated and whether that would help. + +(Related interpretation sections: [Limited Manpower / Not Enough Automation](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#limited-manpower--not-enough-automation), [Slow submitted-reviewed-merged timeline of documentation kills momentum](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#slow-submitted-reviewed-merged-timeline-of-documentation-prs-kills-documentation-momentum), [Reviewing documentation PRS can be just as difficult as code PRs](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#reviewing-documentation-prs-can-be-just-as-difficult-as-code-prs)) + +#### Why Not Just Delegate? + +> A hypothetical developer says, "If it's so much work, why not just **delegate** the work? This 'somebody' can also be a proxy who's gathering feedback, so that you don't have to be in these discussions." +> +> The contributor responds sarcastically, "Oh! Delegation, of course! I hadn't thought about that...." +> +> There's actually an assumption going on here: "If 'free' rice means you can take as much as you want, then 'free' labor implies you can take as much as you want." But that isn't how labor works. If you don't pay for labor, you get less. +> +> Even if everyone could help, there's still limitations due to coordinating efforts: who does what, when, and where, and all without affecting someone else's work. +> +> ~ summary of the 'Why Not Just... Pattern' in [The Hard Parts of Open Source](https://youtu.be/o_4EX4dPppA?t=257) + +One shouldn't trust everyone on the internet. (I know, big surprise.) + +For example, consider the `event-stream incident`. The maintainer unknowingly gave write-access to a malicious actor. Practically everyone depends on this code. The actor injected code that could be used to steal bitcoins: +- [initial issue](https://github.com/dominictarr/event-stream/issues/116) +- [injected code explanation](https://github.com/dominictarr/event-stream/issues/116#issuecomment-441759047) +- [original maintainer's response](https://github.com/dominictarr/event-stream/issues/116) +- [a sarcastic blog post summarizing this class of attack](https://hackernoon.com/im-harvesting-credit-card-numbers-and-passwords-from-your-site-here-s-how-9a8cb347c5b5) + +New maintainers, once found and properly screened, have to be supported (which takes time and thought), so that they can actually fulfill their role. If they decide to leave soon after starting, then one has wasted time and effort. + +(Related interpretation sections: [Knowing whom to trust with write access, defining best workflow procedures, and providing necessary support](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#knowing-whom-to-trust-with-write-access-defining-best-workflow-procedures-and-providing-necessary-support)) + +#### Why Not Just Fund the Language Developers? + +Been there, done that. Someone took it down. ([PureScript Open Collective]((https://opencollective.com/purescript)) + +Our viewpoint of this situation: +- Fans of PureScript wanted to throw money at the project. Why? Perhaps because + - they want to help the project and its goals + - they dont have the time or mental capacity to contribute +- Several people used OpenCollective to indicate they'd like to pledge money to the "github.com/purescript/purescript" project. +- Several weeks later, someone claimed that project's corresponding OpenCollective page and turned off the public page. +- We believe this was because there was no clear vision as to how the funds would be spent. + +Perhaps this idea could be revisited in the future. For now, we cannot say. + +### Breaking Changes Outdate Documentation and Kill Documenters' Motivation + +The main 'go-to' documentation resource for PureScript was/is [PureScript By Example](https://leanpub.com/purescript/) by Phil Freeman. This resource documents the `0.11.7` PureScript release. The current PureScript release is `0.12.3` (as of this writing). + +The `0.12.0` was a significant achievement but one that came with a lot of breaking changes. Phil responded to it in this way: + +> [The PureScript by Example book] seems to take longer [to update] with each major compiler update, and honestly, I’m not motivated to update it again without some sort of guarantee that I won’t have to redo everything again in a few months.... +> I would like to write a lot more documentation for PureScript, but I hate the idea that it will become out of date quickly.... +> So without some sort of plan for the future of the language, and some idea of what changes are coming (and just as importantly, which aren’t), I’m not likely to write anything, and I wouldn’t be surprised if others avoided writing for the same reason. +> +> ~ Phil Freeman [The State of Things, point 4](https://discourse.purescript.org/t/the-state-of-things/282) + +Gary later pointed out that releases with "breaking changes" were occuring less frequently ([source](https://docs.google.com/spreadsheets/d/1MO8siLLSOpkKHJ_eBNRJbipBquFgqlaSS-QSnALDSo8/edit#gid=0)). Still, keep in mind that Phil was likely updating the book each time such a release was made. + +(Related interpretation sections: [Breaking Changes Render Documentation Outdated](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#breaking-changes-renders-documentation-outdated)) + +### There Is No Roadmap That Coordinates Efforts + +Defining a roadmap is hard. It's easy to... +- ...disagree on which goals should be pursued and which to ignore +- ...disagree on how to word such goals +- ...do nothing and let someone else contribute + +Creating a "good" roadmap takes significant time and energy. + +PureScript does not currently have such a roadmap. Rather, core contributors seem to have a general direction they are pursuing (see next point). + +Therefore: +- Those who could help do not know where help is needed +- Those who would help do not know how they can help + +#### Avoiding a `v1.0` PureScript language release + +When people announce "Language X is now `1.0`!", it tends to draw a lot of focus and a lot of traffic. People probably think, "Wow! It's now stable enough to be used to write all my programs." + +In short, one core contributor believes that many would perceive a `v1.0` release as a `v1.0` ecosystem release. The language could be considered 'good enough' for a `v1.0`. However, the ecosystem is definitely not. + +What good is a `v1.0` language, if +- common libraries haven't stabilized yet or are non-existant? +- the ecosystem is incoherent in a number of ways? +- the dependency managers are still unfriendly to users? +- the IDE support is still lacking? + +Thus, core contributors might avoid defining a roadmap to prevent people from having a `v1.0` ecosystem connotation. + +#### Defining a Language Specification + +When should future breaking changes be done: before a `v1.0` or afterwards? + +`garyb`, a core contributor, has resisted efforts to define a language specification. Why? Because he wants to add two features that will require breaking changes: "poly-kinds and something that requires qualified constraints." ([The State of Things, 6th paragraph in his comment](https://discourse.purescript.org/t/the-state-of-things/282/5)) + +If done before a `v1.0`, then the language will likely be stable, documentation will not go out of date, and the ecosystem can flourish. + +If done after a `v1.0`, then many libraries and docs will need to be updated, the language's reputation might suffer, and people might be forever turned off to it. + +(Related interpretation sections: [Lack of a clearly-defined communit-wide mutually-held vision/goal](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#lack-of-a-clearly-defined-community-wide-mutually-held-visiongoal), [Lack of a clearly-defined core-contributor-wide mutually-held language specification](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#lack-of-a-clearly-defined-core-contributor-wide-mutually-held-language-specification), [Fear that people will misinterpret at "v1.0" compiler release for a "v1.0" ecosystem release](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#fear-that-people-will-misinterpret-a-v10-compiler-release-for-a-v10-ecosystem-release)) From dbd796cb4e4a37ba7fd43167c488bf304ad48fef Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 13 Apr 2019 14:55:39 -0700 Subject: [PATCH 101/133] Remove 'solution' aspect of 'why docs are lacking' header It will be added at the end of the file --- .../State-of-PureScript-Documentation-2019.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index a55f57a..d10e74f 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -83,7 +83,7 @@ Here's what has been added to the above since then: | A Guide to the PureScript Numeric Hierarchy | Explanation | New Learners | Read the Docs | Make the Leap from JavaScript to PureScript | Getting Started + Explanation | Javascript developers | Blog Post series -## Why is PureScript's Documentation Lacking and How Do We Improve It? +## Why is PureScript's Documentation Lacking? Here's the short version. Each paragraph will have a link that explains its summary in more detail. From a49c21834a1c54d320ddcd53d9c2be13ab45089f Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 13 Apr 2019 14:58:08 -0700 Subject: [PATCH 102/133] Promote 'FP best practices' summary to top of 'why docs lacking' section --- .../State-of-PureScript-Documentation-2019.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index d10e74f..407130f 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -87,6 +87,8 @@ Here's what has been added to the above since then: Here's the short version. Each paragraph will have a link that explains its summary in more detail. +It is difficult to define what are FP's "best practices / design patterns." The issues explained below are mostly situational; they will improve in time. However, this "best practices" issue is hard to address because it is subjective in nature, requires a lot of expertise, and requires a great communicator. [further explained here]() + PureScript is not _currently_ trying to be the next "mainstream language." Rather, it values "power" over "popularity" and so works towards those ends. [further explained here]() While developing the language, core contributors incurred a lot of responsibility (e.g. library maintenance, documentation updates, updating Pursuit and other related sites, etc.). Over time, they became spread thin and one even burned out. [further explained here]() @@ -103,8 +105,6 @@ Moreover, there are other factors independent of the "breaking changes" issues. 1. Until recently (it's fixed now), an OOM error was preventing some popular libraries from uploading their API docs. Even those familiar with the language had difficulty knowing how to use some libraries. [further explained here]() 2. The current support system doesn't build towards structured, persistent documentation. In some ways, it's like trying to get out of quicksand. [further explained here]() -Finally, it is difficult to define what are FP's "best practices / design patterns." This issue won't go away even if all 'breaking changes' have been implemented. [further explained here]() - ### Some libraries cannot publish their docs due to OOM error From [pulp version runs out of memory (fatal exception) - Issue 351](https://github.com/purescript-contrib/pulp/issues/351): From f9fbd8141b0c70f3a150dfcbe48c8e7620475de7 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 13 Apr 2019 14:58:32 -0700 Subject: [PATCH 103/133] Move 'FP best practices' details section into 'why docs lacking' file --- .../State-of-PureScript-Documentation-2019.md | 21 ------------------- .../Why-Docs-Are-Lacking.md | 21 +++++++++++++++++++ 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 407130f..f6c9fe8 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -135,27 +135,6 @@ Contrast that with an StackOverflow question and answer that appears in a Google (Related interpretation section: [PureScript's Mediums of Communication](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#purescripts-mediums-of-communication)) -### What Exactly are FP's "Best Practices" - -Coming from an Object-Oriented Paradigm, some have asked, "Why aren't the best practices / design patterns / idioms in Functional Programming explained/documented?" - -What are FP's "design patterns" / "idioms" / "best practices" ? How would you define them? - -FP's "best practices" are -- hard to define - - Are `monads` a design pattern? - - Are `lenses` a design pattern? - - What is not a design pattern? -- things people assume everyone does (so why explain them?) - - Functions compose. Didn't people realize that type class X and Y are often used together? - - I used a recursive data type to model a domain. How else would I model it? -- unconscious habits ("Oh! I didn't realize this was a 'design pattern.'") - - I used a List zipper to efficiently update an item in the list. What else would I use? - -FP languages tend to draw people who are intellectually curious. These people tend not to be good at explaining FP's benefits and concepts. Knowledge get stuck in "silos." - -(Related interpretation section: [FP "best practices" are not well-defined, are assumed, or are unconscious habits](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#fp-best-practices-are-not-well-defined-are-assumed-or-are-unconscious-habits), [FP's culture creates "knowledge silos"](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#fps-culture-creates-knowledge-silos)) - ### But Is There Hope? Yes! This small change will address the FP Slack persistence issue: diff --git a/02-Context-or-Narrative/Why-Docs-Are-Lacking.md b/02-Context-or-Narrative/Why-Docs-Are-Lacking.md index 3e3207c..087e3b0 100644 --- a/02-Context-or-Narrative/Why-Docs-Are-Lacking.md +++ b/02-Context-or-Narrative/Why-Docs-Are-Lacking.md @@ -1,5 +1,26 @@ # Why Docs Are Lacking +### What Exactly are FP's "Best Practices" + +Coming from an Object-Oriented Paradigm, some have asked, "Why aren't the best practices / design patterns / idioms in Functional Programming explained/documented?" + +What are FP's "design patterns" / "idioms" / "best practices" ? How would you define them? + +FP's "best practices" are +- hard to define + - Are `monads` a design pattern? + - Are `lenses` a design pattern? + - What is not a design pattern? +- things people assume everyone does (so why explain them?) + - Functions compose. Didn't people realize that type class X and Y are often used together? + - I used a recursive data type to model a domain. How else would I model it? +- unconscious habits ("Oh! I didn't realize this was a 'design pattern.'") + - I used a List zipper to efficiently update an item in the list. What else would I use? + +FP languages tend to draw people who are intellectually curious. These people tend not to be good at explaining FP's benefits and concepts. Knowledge get stuck in "silos." + +(Related interpretation section: [FP "best practices" are not well-defined, are assumed, or are unconscious habits](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#fp-best-practices-are-not-well-defined-are-assumed-or-are-unconscious-habits), [FP's culture creates "knowledge silos"](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#fps-culture-creates-knowledge-silos)) + ### PureScript is not _currently_ trying to be the next "mainstream language" A few have wrongly assumed that PureScript is trying to replace [insert your favorite web language here]. That is not the case. From 59f1d34da3089af90dfc3a70289e7f7cdfebf2b1 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 13 Apr 2019 15:07:15 -0700 Subject: [PATCH 104/133] Move 'OOM error' & 'lack of structured docs' to 'why docs lacking' file --- .../State-of-PureScript-Documentation-2019.md | 30 ------------------- .../Why-Docs-Are-Lacking.md | 30 +++++++++++++++++++ 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index f6c9fe8..fe2c0da 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -105,36 +105,6 @@ Moreover, there are other factors independent of the "breaking changes" issues. 1. Until recently (it's fixed now), an OOM error was preventing some popular libraries from uploading their API docs. Even those familiar with the language had difficulty knowing how to use some libraries. [further explained here]() 2. The current support system doesn't build towards structured, persistent documentation. In some ways, it's like trying to get out of quicksand. [further explained here]() -### Some libraries cannot publish their docs due to OOM error - -From [pulp version runs out of memory (fatal exception) - Issue 351](https://github.com/purescript-contrib/pulp/issues/351): -- Context: Bower is used to produce the "resolutions file" that the compiler expects - - > The compiler expects a “resolutions file” in a similar format to the output of this problematic bower command. We only need a very small portion of the information produced by that command though; for each dependency, if the bower.json specifies anything other than a version range for it, we need to know so that we can produce a warning about that. Otherwise, we need to know which version bower’s solver picked. If I remember correctly that’s everything. Unfortunately I’m not aware of a more sensible variant of bower list which produces all the information we need. [comment in issue, paragraph 2](https://github.com/purescript-contrib/pulp/issues/351#issuecomment-395611759) -- Problem: Bower throws a `RangeError` when attempting to `JSON.stringify` an object that includes a massive dependency tree due to duplicate transitive dependencies: - - > Bower builds a log object, which has our dependency tree. When they try to JSON.stringify this object, it throws RangeError: Invalid string length [comment in issue](https://github.com/purescript-contrib/pulp/issues/351#issuecomment-395605607) - -The proposed solution: change the compiler's "resolution file" schema. Unfortunately, this is a breaking change (tracking issue: [Simplify `purs publish` resolution format](https://github.com/purescript/purescript/issues/3499)): - - > To clarify, the course of action I'm suggesting is that we have `pulp` actually look through the filesystem and collect the resolutions data, and we then pass that information to the compiler. It would make our lives easier if we could also change the compiler so that it accepts this information using a more sensible schema than that of `bower list --offline --json` (and this is what I'm suggesting in that issue ([comment in issue](https://github.com/purescript-contrib/pulp/issues/351#issuecomment-450465708))). - -Thus, a heavily-used library like `Halogen` cannot publish its `v4.0.0` or `v5.0.0` docs on Pursuit. Unfortunately, there's nothing they can do about it. - -### The current support system doesn't build towards structured, persistent documentation - -Because the documentation is lacking, many are encouraged to ask their questions on the `#purescript` channel in the FP Slack. Many have greatly benefited from the quick answers they receive. - -There are two issues with this approach: -1. Such answers cannot be easily found because they are hidden in a chatroom's length conversation. -2. These questions and their answers do not persist. After so much time, Slack will delete them. - -Thus, people with the same already-answered questions can't find their answers. They ask the same questions and receive the same answers. This takes time away from other contributors and developers. - -@chexxor has made some effort to address these issues by cross-posting such discussions in the Discourse forum. This accounts for the second issue. - -However, the format is poor. One must read through a (sometimes) lengthy conversation to find the answer. -Contrast that with an StackOverflow question and answer that appears in a Google search. - -(Related interpretation section: [PureScript's Mediums of Communication](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#purescripts-mediums-of-communication)) - ### But Is There Hope? Yes! This small change will address the FP Slack persistence issue: diff --git a/02-Context-or-Narrative/Why-Docs-Are-Lacking.md b/02-Context-or-Narrative/Why-Docs-Are-Lacking.md index 087e3b0..9455a4b 100644 --- a/02-Context-or-Narrative/Why-Docs-Are-Lacking.md +++ b/02-Context-or-Narrative/Why-Docs-Are-Lacking.md @@ -200,3 +200,33 @@ If done before a `v1.0`, then the language will likely be stable, documentation If done after a `v1.0`, then many libraries and docs will need to be updated, the language's reputation might suffer, and people might be forever turned off to it. (Related interpretation sections: [Lack of a clearly-defined communit-wide mutually-held vision/goal](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#lack-of-a-clearly-defined-community-wide-mutually-held-visiongoal), [Lack of a clearly-defined core-contributor-wide mutually-held language specification](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#lack-of-a-clearly-defined-core-contributor-wide-mutually-held-language-specification), [Fear that people will misinterpret at "v1.0" compiler release for a "v1.0" ecosystem release](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#fear-that-people-will-misinterpret-a-v10-compiler-release-for-a-v10-ecosystem-release)) + +### Some libraries cannot publish their docs due to OOM error + +From [pulp version runs out of memory (fatal exception) - Issue 351](https://github.com/purescript-contrib/pulp/issues/351): +- Context: Bower is used to produce the "resolutions file" that the compiler expects + - > The compiler expects a “resolutions file” in a similar format to the output of this problematic bower command. We only need a very small portion of the information produced by that command though; for each dependency, if the bower.json specifies anything other than a version range for it, we need to know so that we can produce a warning about that. Otherwise, we need to know which version bower’s solver picked. If I remember correctly that’s everything. Unfortunately I’m not aware of a more sensible variant of bower list which produces all the information we need. [comment in issue, paragraph 2](https://github.com/purescript-contrib/pulp/issues/351#issuecomment-395611759) +- Problem: Bower throws a `RangeError` when attempting to `JSON.stringify` an object that includes a massive dependency tree due to duplicate transitive dependencies: + - > Bower builds a log object, which has our dependency tree. When they try to JSON.stringify this object, it throws RangeError: Invalid string length [comment in issue](https://github.com/purescript-contrib/pulp/issues/351#issuecomment-395605607) + +The proposed solution: change the compiler's "resolution file" schema. Unfortunately, this is a breaking change (tracking issue: [Simplify `purs publish` resolution format](https://github.com/purescript/purescript/issues/3499)): + - > To clarify, the course of action I'm suggesting is that we have `pulp` actually look through the filesystem and collect the resolutions data, and we then pass that information to the compiler. It would make our lives easier if we could also change the compiler so that it accepts this information using a more sensible schema than that of `bower list --offline --json` (and this is what I'm suggesting in that issue ([comment in issue](https://github.com/purescript-contrib/pulp/issues/351#issuecomment-450465708))). + +Thus, a heavily-used library like `Halogen` cannot publish its `v4.0.0` or `v5.0.0` docs on Pursuit. Unfortunately, there's nothing they can do about it. + +### The current support system doesn't build towards structured, persistent documentation + +Because the documentation is lacking, many are encouraged to ask their questions on the `#purescript` channel in the FP Slack. Many have greatly benefited from the quick answers they receive. + +There are two issues with this approach: +1. Such answers cannot be easily found because they are hidden in a chatroom's length conversation. +2. These questions and their answers do not persist. After so much time, Slack will delete them. + +Thus, people with the same already-answered questions can't find their answers. They ask the same questions and receive the same answers. This takes time away from other contributors and developers. + +@chexxor has made some effort to address these issues by cross-posting such discussions in the Discourse forum. This accounts for the second issue. + +However, the format is poor. One must read through a (sometimes) lengthy conversation to find the answer. +Contrast that with an StackOverflow question and answer that appears in a Google search. + +(Related interpretation section: [PureScript's Mediums of Communication](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#purescripts-mediums-of-communication)) From d3d051915bc5c327c925ca1d93523b97089113c2 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 13 Apr 2019 15:11:45 -0700 Subject: [PATCH 105/133] Reuse Alex's rendering that highlight missing doc types --- .../State-of-PureScript-Documentation-2019.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index fe2c0da..c9e5581 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -56,6 +56,11 @@ Note: this section is sourced from only two blog posts, [What Nobody Tells You A ### Evaluating PureScript's Documentation +Below, we tagged each documentation effort with its documentation type (if yours isn't listed, notify us). By looking at what exists, we can see that the following types of documentation are lacking: +- Hooks +- How-To Guides +- Explanations + Here was PureScript's documentation as of July 2018: | Name | Type | Audience | Medium | From dd988e35b3fab2cc9c3ed09990233f6da1496857 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 13 Apr 2019 15:17:03 -0700 Subject: [PATCH 106/133] Add infrastructure bottleneck point to summary rather than explain it I don't want people to take that point out of context and then yell at core contributors without having read through the rest of the document --- .../State-of-PureScript-Documentation-2019.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index c9e5581..82a22e4 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -98,7 +98,7 @@ PureScript is not _currently_ trying to be the next "mainstream language." Rathe While developing the language, core contributors incurred a lot of responsibility (e.g. library maintenance, documentation updates, updating Pursuit and other related sites, etc.). Over time, they became spread thin and one even burned out. [further explained here]() -Thus, they cannot quickly respond to most people's questions or contributions. With the small amount of time they do have, they are focusing on adding new language features, not improving the documentation situation. The language's development is steady (6-week release cycle) but slow. [further explained here]() +Thus, they cannot quickly respond to most people's questions or contributions. With the small amount of time they do have, they are focusing on adding new language features, not improving the documentation situation. The language's development is steady (6-week release cycle) but slow. Moreover, only some of them have write/deploy access to key documentation infrastructure (e.g. Pursuit, documentation repo, Try PureScript, etc.) [further explained here]() However, it seems they are (wisely) postponing "breaking changes" until all can be done at once. Otherwise, they will ~spend~ waste even more of their time updating the ecosystem to account for the breaking changes. There is also some disagreement about when those changes should be done. [further explained here]() From 2f9bc27b69b027d98246dd5a73abc48b3cde4b40 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 13 Apr 2019 15:17:49 -0700 Subject: [PATCH 107/133] Remove original outline to help guide documentation structure --- .../State-of-PureScript-Documentation-2019.md | 35 ------------------- 1 file changed, 35 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 82a22e4..a1f8a78 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -188,38 +188,3 @@ To help with consistency, copy the below questions and paste them into your comm > How much support are you willing to provide to those who want to help and in what form? ``` - - - -The following - - Evaluate PureScript's documentation using that criteria - - Explain why PureScript's documentation is lacking and what is being done to improve it - - Address various audience's possible concerns or questions centered on these themes: - - New learners - How should I learn PureScript? - - PureScript documentation writers - How should I write good maintainable documentation for others? - - Core Contributors - - -A few different audiences -- shared (things we should explain, no matter who reads this) - - Why read this document (capture people's attention in less than 2 paragraphs) - - What is good documentation for new learners? (defining our terminology and criteria) - - How does PureScript fair in that regard? (use that criteria to judge PS' current documentation) - - Why isn't it better? (explain the obstacles that prevent it from being better) -- new learners (address things new learners care about) - - What should your expectations be when learning? (frustration arises when expectations are broken) - - How are people currently trying to improve it? (explain current efforts that people can tag alongside of / help / give feedback on) - - How can you help in this effort? (you are most motivated, so you'll drive the effort or help out in some situations) -- Documentation writers (address things they care about) - - How do I write good documentation for new learners? - - How do I write documentation that does not go out-of-date quickly? - - How do I write maintainable documentation? - - How should I bring awareness to my documentation efforts? -- PS core contributors (things they care about) - - What processes could be automated to save you time / lower the maintenance cost? - - Questions whose answers would be helpful for others to know - - What 'qualifications', if any, would they prefer someone has before delegating a project to them? - -Here's a quick overview of some of its benefits compared to other languages: -- PureScript provides certain guarantees by default that other web languages do not or cannot (e.g. JavaScript, TypeScript) -- PureScript is more powerful than similar alternatives (i.e. Elm) -- PureScript can be used to 'patch' existing code, enabling one to slowly migrate a large application to PureScript one component at a time (unlike Haskell's GHCJS). From 462ad293d85479a1f3db0c406306da4c8d0e4a4e Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 13 Apr 2019 15:19:13 -0700 Subject: [PATCH 108/133] Provide subtitle to Core Contributors section --- .../State-of-PureScript-Documentation-2019.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index a1f8a78..1577d9b 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -155,7 +155,7 @@ Second, your language background affects how easy or hard it is to learn PureScr ## PureScript Documentation Writers: What is the Best Way to Write Documentation in this Context? -## Core Contributors: ??? +## Core Contributors: "How Should We Support You?" and Other General Feedback Please answer the below questions. From 708e5439f117380f3ac84910160fcecab60441ef Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 13 Apr 2019 15:20:02 -0700 Subject: [PATCH 109/133] Add another reason for notifying us: wrong doc type --- .../State-of-PureScript-Documentation-2019.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 1577d9b..31e3ab7 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -56,7 +56,7 @@ Note: this section is sourced from only two blog posts, [What Nobody Tells You A ### Evaluating PureScript's Documentation -Below, we tagged each documentation effort with its documentation type (if yours isn't listed, notify us). By looking at what exists, we can see that the following types of documentation are lacking: +Below, we tagged each documentation effort with its documentation type (if yours isn't listed or is incorrect, notify us). By looking at what exists, we can see that the following types of documentation are lacking: - Hooks - How-To Guides - Explanations From 593713d73ecce8014b136778c126b575b1aba39f Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 13 Apr 2019 15:24:01 -0700 Subject: [PATCH 110/133] Backlink to 'Good Documentation.md' file to answer Doc Writers questions --- .../State-of-PureScript-Documentation-2019.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 31e3ab7..790e254 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -155,6 +155,8 @@ Second, your language background affects how easy or hard it is to learn PureScr ## PureScript Documentation Writers: What is the Best Way to Write Documentation in this Context? +Read through the entirety of the [Good Documentation.md]() file. We only listed the 5 types of documentation above to make this document shorter. + ## Core Contributors: "How Should We Support You?" and Other General Feedback Please answer the below questions. From bec564a8a6b277dccc8b11a56e22691716177403 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 13 Apr 2019 15:27:45 -0700 Subject: [PATCH 111/133] Move 'is there hope' section to bottom: will become 'solutions' section --- .../State-of-PureScript-Documentation-2019.md | 58 +++++++++---------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 790e254..4b9ee12 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -110,35 +110,6 @@ Moreover, there are other factors independent of the "breaking changes" issues. 1. Until recently (it's fixed now), an OOM error was preventing some popular libraries from uploading their API docs. Even those familiar with the language had difficulty knowing how to use some libraries. [further explained here]() 2. The current support system doesn't build towards structured, persistent documentation. In some ways, it's like trying to get out of quicksand. [further explained here]() -### But Is There Hope? Yes! - -This small change will address the FP Slack persistence issue: -- When a question on the `#purescript` Slack channel gets answered, request the person who asked it to post the question on StackOverflow and link to the question in the chatroom. -- Then, let someone (whether the answerer or someone who saw it) "answer" that question and give credit it to the answerer. - -People are making an assumption that has not been tested. **Are all documentation efforts always affected by a breaking change?** I doubt it. Certainly there are some things that need better documentation which won't be affected by breaking changes. Why not identify what those are and start improving them? - -Such efforts will likely need to be "unofficial." We (non-core-contributors / users of PS) do not want to steal time away from the core contributors by distracting them with documentation PRs. Let them focus on the language's development. Stabilizing the language sooner means an improved documentation situation sooner. - -Rather, we (non-core-contributors / users of PS) can focus on answering questions like these: -- What are the libraries that need to have their documentation improved? - - If documented, will breaking changes outdate such documentation? - - How hard would it be to write a small code example that shows how to use them? For example - - [Jordan's example for how to create a tree via `purescript-tree`](https://github.com/JordanMartinez/purescript-jordans-reference/blob/latestRelease/22-Projects/src/11-Table-of-Contents/04-Tree/01-Syntax.purs#L31-L64) - - [Jordan's example of the "hello world" program via the ReaderT design pattern](https://github.com/JordanMartinez/purescript-jordans-reference/blob/latestRelease/21-Hello-World/08-Application-Structure/src/11-Hello-World/02-ReaderT.purs) - - [Halogen's "basic button component" example](https://github.com/slamdata/purescript-halogen/blob/master/examples/basic/src/Button.purs) -- What are "best practices" for various topics/areas? For example: - - Guidelines for writing a good bindings library - - How should a library author analyze the library to which they want to write bindings? - - What are common problems such people face and their possible solutions? -- What are some of the clearest explanations of FP concepts? - - How hard is it to port their code examples to PureScript? - - Have people written an explanation that "walks one through" an FP paper's ideas in a clear way? -- What are common solutions to build-related problems? Where is a centralized resource that can store all of these? - - Integrating PureScript to work with JS build tools? - - Integrating PureScript with CI (Travis, AppVeyor, etc.)? - - Possible "tree-shaking" approaches to PureScript and their tradeoffs? - ## New Learners: What is the Best Way to Learn PureScript? First, PureScript is mainly used for front-end work, not back-end work. While it is used for the back-end in some situations, most tend to use Haskell or another language, even if PureScript would be a better language in some situations. These languages already have mature libraries with people maintaining them. So, the incentives to improve this situation are not quite there. @@ -190,3 +161,32 @@ To help with consistency, copy the below questions and paste them into your comm > How much support are you willing to provide to those who want to help and in what form? ``` + +### But Is There Hope? Yes! + +This small change will address the FP Slack persistence issue: +- When a question on the `#purescript` Slack channel gets answered, request the person who asked it to post the question on StackOverflow and link to the question in the chatroom. +- Then, let someone (whether the answerer or someone who saw it) "answer" that question and give credit it to the answerer. + +People are making an assumption that has not been tested. **Are all documentation efforts always affected by a breaking change?** I doubt it. Certainly there are some things that need better documentation which won't be affected by breaking changes. Why not identify what those are and start improving them? + +Such efforts will likely need to be "unofficial." We (non-core-contributors / users of PS) do not want to steal time away from the core contributors by distracting them with documentation PRs. Let them focus on the language's development. Stabilizing the language sooner means an improved documentation situation sooner. + +Rather, we (non-core-contributors / users of PS) can focus on answering questions like these: +- What are the libraries that need to have their documentation improved? + - If documented, will breaking changes outdate such documentation? + - How hard would it be to write a small code example that shows how to use them? For example + - [Jordan's example for how to create a tree via `purescript-tree`](https://github.com/JordanMartinez/purescript-jordans-reference/blob/latestRelease/22-Projects/src/11-Table-of-Contents/04-Tree/01-Syntax.purs#L31-L64) + - [Jordan's example of the "hello world" program via the ReaderT design pattern](https://github.com/JordanMartinez/purescript-jordans-reference/blob/latestRelease/21-Hello-World/08-Application-Structure/src/11-Hello-World/02-ReaderT.purs) + - [Halogen's "basic button component" example](https://github.com/slamdata/purescript-halogen/blob/master/examples/basic/src/Button.purs) +- What are "best practices" for various topics/areas? For example: + - Guidelines for writing a good bindings library + - How should a library author analyze the library to which they want to write bindings? + - What are common problems such people face and their possible solutions? +- What are some of the clearest explanations of FP concepts? + - How hard is it to port their code examples to PureScript? + - Have people written an explanation that "walks one through" an FP paper's ideas in a clear way? +- What are common solutions to build-related problems? Where is a centralized resource that can store all of these? + - Integrating PureScript to work with JS build tools? + - Integrating PureScript with CI (Travis, AppVeyor, etc.)? + - Possible "tree-shaking" approaches to PureScript and their tradeoffs? From 69430853ce78bf43fde4d5013f66c197a00192dc Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 13 Apr 2019 15:28:30 -0700 Subject: [PATCH 112/133] Group related audiences into new section (for ToC purposes) --- .../State-of-PureScript-Documentation-2019.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 4b9ee12..0b12f13 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -110,7 +110,9 @@ Moreover, there are other factors independent of the "breaking changes" issues. 1. Until recently (it's fixed now), an OOM error was preventing some popular libraries from uploading their API docs. Even those familiar with the language had difficulty knowing how to use some libraries. [further explained here]() 2. The current support system doesn't build towards structured, persistent documentation. In some ways, it's like trying to get out of quicksand. [further explained here]() -## New Learners: What is the Best Way to Learn PureScript? +## Addressing Audiences + +### New Learners: What is the Best Way to Learn PureScript? First, PureScript is mainly used for front-end work, not back-end work. While it is used for the back-end in some situations, most tend to use Haskell or another language, even if PureScript would be a better language in some situations. These languages already have mature libraries with people maintaining them. So, the incentives to improve this situation are not quite there. @@ -124,11 +126,11 @@ Second, your language background affects how easy or hard it is to learn PureScr | Elm | [An Outsider's Guide to Statically Typed Functional Programming (Book)](https://leanpub.com/outsidefp) | -- | Haskell | [Introduction to PureScript (PDF)](http://code.adriansieber.com/adrian/adriansieber-com/src/branch/master/posts/_2018-11-01_introduction_to_purescript_for_haskell_developers/main.pdf)

[Differences from Haskell](https://github.com/purescript/documentation/blob/master/language/Differences-from-Haskell.md) | -- -## PureScript Documentation Writers: What is the Best Way to Write Documentation in this Context? +### PureScript Documentation Writers: What is the Best Way to Write Documentation in this Context? -Read through the entirety of the [Good Documentation.md]() file. We only listed the 5 types of documentation above to make this document shorter. +Read through the entirety of the [Good Documentation.md]() file. We only listed the 5 types of documentation above to make this document shorter. -## Core Contributors: "How Should We Support You?" and Other General Feedback +### Core Contributors: "How Should We Support You?" and Other General Feedback Please answer the below questions. From 50def88d2901487facbbdaf7e6c0eab812da6ecf Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 13 Apr 2019 15:50:27 -0700 Subject: [PATCH 113/133] Add "post your solution" section back in; finish summary with hope --- .../State-of-PureScript-Documentation-2019.md | 42 +++++++++++++++++-- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 0b12f13..00d328c 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -110,6 +110,8 @@ Moreover, there are other factors independent of the "breaking changes" issues. 1. Until recently (it's fixed now), an OOM error was preventing some popular libraries from uploading their API docs. Even those familiar with the language had difficulty knowing how to use some libraries. [further explained here]() 2. The current support system doesn't build towards structured, persistent documentation. In some ways, it's like trying to get out of quicksand. [further explained here]() +Finally, Jordan believes that **not all documentation efforts are always affected by breaking changes**. + ## Addressing Audiences ### New Learners: What is the Best Way to Learn PureScript? @@ -164,15 +166,47 @@ To help with consistency, copy the below questions and paste them into your comm ``` -### But Is There Hope? Yes! +## Everyone: What Should Our Documentation Outcomes Be? + +Our purpose is clear: improve the documentation situation + +The above summary shows that we should abide by these principles no matter what we do, nor how we do it: +- **Show, don't tell**: prefer heavily-commented clone-compile-and-play code examples over written explanations +- **Start unofficial documentation efforts**: let's not slow down core contributors by distracting them with things relating to documentation (e.g. PRs). +- **Don't recreate the wheel**: look into helping existing efforts before you consider starting your own +- **Adhere to Good Docs Guidelines**: follow the above "documentation type" guidelines and the other thoughts expressed in the 'Good Documentation.md' file + +The outcomes we are striving to reach have yet to be defined. + +We'd like your help. **To prevent "group think," please don't look at our ideas until you have posted yours.** + +Please share your idea for _what_ the community should achieve (the reality that is true once finished) **before** sharing your idea for _how_ to achieve it (the step-by-step plan for how to get there). + +| Example Type | Comment | Explanation +| - | - | - | +| Bad | We should send documentation PRs to specific libraries | Answers 'how to do something' not 'the reality that will be true when we are finished.' +| Good | **Goal:** The top 30 dependencies used in PS' ecosystem have examples and counterexamples in all of their Pursuit docs.
**How:** We make a version of Justin Woo's "ACME" Spago project ([project](https://github.com/justinwoo/acme-spago) & [resulting docs](https://jusrin.dev/acme-spago/)). For packages that are lacking docs or are maintained by core contributors who won't respond quickly, we could use Spago to override those packages with a version that includes more documentation. Then, via `spago docs`, would could create a local copy that has the updated docs. | States a goal but does not determine how that could be achieved. But a few ideas quicly come to mind for how. + +Copy and paste the below content into your comment box: + +``` +## Goal: + + + +### How: + + +``` + +Prevent group think: once you have finished posting your ideas, [look at ours]() + +### Our Ideas This small change will address the FP Slack persistence issue: - When a question on the `#purescript` Slack channel gets answered, request the person who asked it to post the question on StackOverflow and link to the question in the chatroom. - Then, let someone (whether the answerer or someone who saw it) "answer" that question and give credit it to the answerer. -People are making an assumption that has not been tested. **Are all documentation efforts always affected by a breaking change?** I doubt it. Certainly there are some things that need better documentation which won't be affected by breaking changes. Why not identify what those are and start improving them? - -Such efforts will likely need to be "unofficial." We (non-core-contributors / users of PS) do not want to steal time away from the core contributors by distracting them with documentation PRs. Let them focus on the language's development. Stabilizing the language sooner means an improved documentation situation sooner. Rather, we (non-core-contributors / users of PS) can focus on answering questions like these: - What are the libraries that need to have their documentation improved? From 57f9f37a2abcd261f24a6c15a54349c4e393a289 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 13 Apr 2019 15:52:55 -0700 Subject: [PATCH 114/133] Move 'our ideas' section into own file --- 02-Context-or-Narrative/Our-Outcome-Ideas.md | 25 ++++++++++++++++++ .../State-of-PureScript-Documentation-2019.md | 26 ------------------- 2 files changed, 25 insertions(+), 26 deletions(-) create mode 100644 02-Context-or-Narrative/Our-Outcome-Ideas.md diff --git a/02-Context-or-Narrative/Our-Outcome-Ideas.md b/02-Context-or-Narrative/Our-Outcome-Ideas.md new file mode 100644 index 0000000..da4b358 --- /dev/null +++ b/02-Context-or-Narrative/Our-Outcome-Ideas.md @@ -0,0 +1,25 @@ +# Our Outcome Ideas + +This small change will address the FP Slack persistence issue: +- When a question on the `#purescript` Slack channel gets answered, request the person who asked it to post the question on StackOverflow and link to the question in the chatroom. +- Then, let someone (whether the answerer or someone who saw it) "answer" that question and give credit it to the answerer. + + +Rather, we (non-core-contributors / users of PS) can focus on answering questions like these: +- What are the libraries that need to have their documentation improved? + - If documented, will breaking changes outdate such documentation? + - How hard would it be to write a small code example that shows how to use them? For example + - [Jordan's example for how to create a tree via `purescript-tree`](https://github.com/JordanMartinez/purescript-jordans-reference/blob/latestRelease/22-Projects/src/11-Table-of-Contents/04-Tree/01-Syntax.purs#L31-L64) + - [Jordan's example of the "hello world" program via the ReaderT design pattern](https://github.com/JordanMartinez/purescript-jordans-reference/blob/latestRelease/21-Hello-World/08-Application-Structure/src/11-Hello-World/02-ReaderT.purs) + - [Halogen's "basic button component" example](https://github.com/slamdata/purescript-halogen/blob/master/examples/basic/src/Button.purs) +- What are "best practices" for various topics/areas? For example: + - Guidelines for writing a good bindings library + - How should a library author analyze the library to which they want to write bindings? + - What are common problems such people face and their possible solutions? +- What are some of the clearest explanations of FP concepts? + - How hard is it to port their code examples to PureScript? + - Have people written an explanation that "walks one through" an FP paper's ideas in a clear way? +- What are common solutions to build-related problems? Where is a centralized resource that can store all of these? + - Integrating PureScript to work with JS build tools? + - Integrating PureScript with CI (Travis, AppVeyor, etc.)? + - Possible "tree-shaking" approaches to PureScript and their tradeoffs? diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 00d328c..311bde0 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -200,29 +200,3 @@ Copy and paste the below content into your comment box: ``` Prevent group think: once you have finished posting your ideas, [look at ours]() - -### Our Ideas - -This small change will address the FP Slack persistence issue: -- When a question on the `#purescript` Slack channel gets answered, request the person who asked it to post the question on StackOverflow and link to the question in the chatroom. -- Then, let someone (whether the answerer or someone who saw it) "answer" that question and give credit it to the answerer. - - -Rather, we (non-core-contributors / users of PS) can focus on answering questions like these: -- What are the libraries that need to have their documentation improved? - - If documented, will breaking changes outdate such documentation? - - How hard would it be to write a small code example that shows how to use them? For example - - [Jordan's example for how to create a tree via `purescript-tree`](https://github.com/JordanMartinez/purescript-jordans-reference/blob/latestRelease/22-Projects/src/11-Table-of-Contents/04-Tree/01-Syntax.purs#L31-L64) - - [Jordan's example of the "hello world" program via the ReaderT design pattern](https://github.com/JordanMartinez/purescript-jordans-reference/blob/latestRelease/21-Hello-World/08-Application-Structure/src/11-Hello-World/02-ReaderT.purs) - - [Halogen's "basic button component" example](https://github.com/slamdata/purescript-halogen/blob/master/examples/basic/src/Button.purs) -- What are "best practices" for various topics/areas? For example: - - Guidelines for writing a good bindings library - - How should a library author analyze the library to which they want to write bindings? - - What are common problems such people face and their possible solutions? -- What are some of the clearest explanations of FP concepts? - - How hard is it to port their code examples to PureScript? - - Have people written an explanation that "walks one through" an FP paper's ideas in a clear way? -- What are common solutions to build-related problems? Where is a centralized resource that can store all of these? - - Integrating PureScript to work with JS build tools? - - Integrating PureScript with CI (Travis, AppVeyor, etc.)? - - Possible "tree-shaking" approaches to PureScript and their tradeoffs? From f974b9a51d97b849a52c0f4661600611c9099698 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 13 Apr 2019 16:06:01 -0700 Subject: [PATCH 115/133] Document ACME doc project idea --- 02-Context-or-Narrative/Our-Outcome-Ideas.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/02-Context-or-Narrative/Our-Outcome-Ideas.md b/02-Context-or-Narrative/Our-Outcome-Ideas.md index da4b358..65323cf 100644 --- a/02-Context-or-Narrative/Our-Outcome-Ideas.md +++ b/02-Context-or-Narrative/Our-Outcome-Ideas.md @@ -1,5 +1,13 @@ # Our Outcome Ideas +## Goal: The top 30 dependencies used in PS' ecosystem have examples and counterexamples in all of their Pursuit docs. + +### How: A community-curated "ACME" Spago project + +We make a version of Justin Woo's "ACME" Spago project ([project](https://github.com/justinwoo/acme-spago) & [resulting docs](https://jusrin.dev/acme-spago/)). For packages that are lacking docs or are maintained by core contributors who won't respond quickly, we could use Spago to override those packages with a version supplied by a community member that includes more documentation. + +All changes should be accepted with little questioning. However, the project should heavily warn against people using the resulting package set in production as one could easily introduce malware here. + This small change will address the FP Slack persistence issue: - When a question on the `#purescript` Slack channel gets answered, request the person who asked it to post the question on StackOverflow and link to the question in the chatroom. - Then, let someone (whether the answerer or someone who saw it) "answer" that question and give credit it to the answerer. From dc8531b9ca95de517cf3ea9cd54ab7a266b0d4ba Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 13 Apr 2019 16:06:32 -0700 Subject: [PATCH 116/133] Reformat ideas into new structure --- 02-Context-or-Narrative/Our-Outcome-Ideas.md | 22 +++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/02-Context-or-Narrative/Our-Outcome-Ideas.md b/02-Context-or-Narrative/Our-Outcome-Ideas.md index 65323cf..2f56b05 100644 --- a/02-Context-or-Narrative/Our-Outcome-Ideas.md +++ b/02-Context-or-Narrative/Our-Outcome-Ideas.md @@ -8,6 +8,25 @@ We make a version of Justin Woo's "ACME" Spago project ([project](https://github All changes should be accepted with little questioning. However, the project should heavily warn against people using the resulting package set in production as one could easily introduce malware here. +## Goal: Collect the best and clearest explanations for FP concepts into a central location + +In general, these are the kinds of things I had in mind: +- What are some of the clearest explanations of FP concepts? +- How hard is it to port their code examples to PureScript? +- Have people written an explanation that "walks one through" an FP paper's ideas in a clear way? + +I don't want another 'link farm.' That leads to information overload and decision paralysis. + +Rather, I want the top 1 or 2 explanations on something. + +### How: Add it to Jordan's learning repository + +These links could be added to [Jordan's learning repo](http://www.github.com/jordanmartinez/purescript-jordans-reference) as it exists partly for this purpose. + +While lacking expertise in some areas, he can still sift through them and help determine which are great, good, duplicates, or just downright bad. + +
+ This small change will address the FP Slack persistence issue: - When a question on the `#purescript` Slack channel gets answered, request the person who asked it to post the question on StackOverflow and link to the question in the chatroom. - Then, let someone (whether the answerer or someone who saw it) "answer" that question and give credit it to the answerer. @@ -24,9 +43,6 @@ Rather, we (non-core-contributors / users of PS) can focus on answering question - Guidelines for writing a good bindings library - How should a library author analyze the library to which they want to write bindings? - What are common problems such people face and their possible solutions? -- What are some of the clearest explanations of FP concepts? - - How hard is it to port their code examples to PureScript? - - Have people written an explanation that "walks one through" an FP paper's ideas in a clear way? - What are common solutions to build-related problems? Where is a centralized resource that can store all of these? - Integrating PureScript to work with JS build tools? - Integrating PureScript with CI (Travis, AppVeyor, etc.)? From 052a9ecfe6aa53efe75a6965dacfa594eccb4e36 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 13 Apr 2019 16:09:22 -0700 Subject: [PATCH 117/133] Convert SO reask-reanswer to new outcome structure --- 02-Context-or-Narrative/Our-Outcome-Ideas.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/02-Context-or-Narrative/Our-Outcome-Ideas.md b/02-Context-or-Narrative/Our-Outcome-Ideas.md index 2f56b05..92a1bc4 100644 --- a/02-Context-or-Narrative/Our-Outcome-Ideas.md +++ b/02-Context-or-Narrative/Our-Outcome-Ideas.md @@ -25,11 +25,17 @@ These links could be added to [Jordan's learning repo](http://www.github.com/jor While lacking expertise in some areas, he can still sift through them and help determine which are great, good, duplicates, or just downright bad. -
+## Goal: Convert all answered Slack-based questions into StackOverflow Questions and Answers -This small change will address the FP Slack persistence issue: -- When a question on the `#purescript` Slack channel gets answered, request the person who asked it to post the question on StackOverflow and link to the question in the chatroom. -- Then, let someone (whether the answerer or someone who saw it) "answer" that question and give credit it to the answerer. +Slack is still an ideal place to ask a question. However, it doesn't persist. + +### How: Reask and reanswer it on StackOverflow + +When a question on the `#purescript` or `#purescript-beginner` Slack channel gets answered, request the person who asked it to post the question on StackOverflow and link to the question in the chatroom. + +Then, let someone (whether the answerer or someone who saw it) "answer" that question and give credit it to the answerer. + +We should prioritize persistent docs over crediting who answered the question. Rather, we (non-core-contributors / users of PS) can focus on answering questions like these: From 02917b9d3db829ee96ebb76bd5b864961d4d2615 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 13 Apr 2019 16:12:23 -0700 Subject: [PATCH 118/133] Convert build-related problems & solutions into new outcome format --- 02-Context-or-Narrative/Our-Outcome-Ideas.md | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/02-Context-or-Narrative/Our-Outcome-Ideas.md b/02-Context-or-Narrative/Our-Outcome-Ideas.md index 92a1bc4..d4474f3 100644 --- a/02-Context-or-Narrative/Our-Outcome-Ideas.md +++ b/02-Context-or-Narrative/Our-Outcome-Ideas.md @@ -37,6 +37,17 @@ Then, let someone (whether the answerer or someone who saw it) "answer" that que We should prioritize persistent docs over crediting who answered the question. +## Goal: Collect the best solutions to common build-related problems into a central location + +- Integrating PureScript to work with JS build tools? +- Integrating PureScript with CI (Travis, AppVeyor, etc.)? +- Possible "tree-shaking" approaches to PureScript and their tradeoffs? + +### How: Add it to a special "build" repository + +I would suggest adding it to Jordan's learning repo, but this idea only works well if there are lots of small sample projects to build. Thus, it'd be better kept as its own repository. + +## Unsorted Ideas Rather, we (non-core-contributors / users of PS) can focus on answering questions like these: - What are the libraries that need to have their documentation improved? @@ -49,7 +60,3 @@ Rather, we (non-core-contributors / users of PS) can focus on answering question - Guidelines for writing a good bindings library - How should a library author analyze the library to which they want to write bindings? - What are common problems such people face and their possible solutions? -- What are common solutions to build-related problems? Where is a centralized resource that can store all of these? - - Integrating PureScript to work with JS build tools? - - Integrating PureScript with CI (Travis, AppVeyor, etc.)? - - Possible "tree-shaking" approaches to PureScript and their tradeoffs? From 13b0826fb714a0fdc6d8ebd72413d6557aa3a3bf Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 13 Apr 2019 16:16:19 -0700 Subject: [PATCH 119/133] Convert 'cookbook' idea into new outcome format --- 02-Context-or-Narrative/Our-Outcome-Ideas.md | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/02-Context-or-Narrative/Our-Outcome-Ideas.md b/02-Context-or-Narrative/Our-Outcome-Ideas.md index d4474f3..d56960a 100644 --- a/02-Context-or-Narrative/Our-Outcome-Ideas.md +++ b/02-Context-or-Narrative/Our-Outcome-Ideas.md @@ -47,15 +47,20 @@ We should prioritize persistent docs over crediting who answered the question. I would suggest adding it to Jordan's learning repo, but this idea only works well if there are lots of small sample projects to build. Thus, it'd be better kept as its own repository. +## Goal: Add Syntax Examples for Core Libraries + +Sometimes, Pursuit docs don't help you know how to use something. However, a lot can be gleaned/imitated by looking at an example. For example: +- [Halogen's "basic button component" example](https://github.com/slamdata/purescript-halogen/blob/master/examples/basic/src/Button.purs) +- [Jordan's example for how to create a tree via `purescript-tree`](https://github.com/JordanMartinez/purescript-jordans-reference/blob/latestRelease/22-Projects/src/11-Table-of-Contents/04-Tree/01-Syntax.purs#L31-L64) +- [Jordan's example of the "hello world" program via the ReaderT design pattern](https://github.com/JordanMartinez/purescript-jordans-reference/blob/latestRelease/21-Hello-World/08-Application-Structure/src/11-Hello-World/02-ReaderT.purs) + +### How: Document a syntax example in Jordan's Learning Repo + +I've begun to do this myself [here](https://github.com/JordanMartinez/purescript-jordans-reference/tree/latestRelease/22-Projects/src/01-Libraries) with a few libraries that I've used when building some projects. Perhaps I will later turn this into a separate top-level folder and call it "cookbook" + ## Unsorted Ideas Rather, we (non-core-contributors / users of PS) can focus on answering questions like these: -- What are the libraries that need to have their documentation improved? - - If documented, will breaking changes outdate such documentation? - - How hard would it be to write a small code example that shows how to use them? For example - - [Jordan's example for how to create a tree via `purescript-tree`](https://github.com/JordanMartinez/purescript-jordans-reference/blob/latestRelease/22-Projects/src/11-Table-of-Contents/04-Tree/01-Syntax.purs#L31-L64) - - [Jordan's example of the "hello world" program via the ReaderT design pattern](https://github.com/JordanMartinez/purescript-jordans-reference/blob/latestRelease/21-Hello-World/08-Application-Structure/src/11-Hello-World/02-ReaderT.purs) - - [Halogen's "basic button component" example](https://github.com/slamdata/purescript-halogen/blob/master/examples/basic/src/Button.purs) - What are "best practices" for various topics/areas? For example: - Guidelines for writing a good bindings library - How should a library author analyze the library to which they want to write bindings? From c42bc354d15d935ccf609df43fbba1820e06679f Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 13 Apr 2019 16:20:14 -0700 Subject: [PATCH 120/133] Convert Bindings Library guide to new outcome format --- 02-Context-or-Narrative/Our-Outcome-Ideas.md | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/02-Context-or-Narrative/Our-Outcome-Ideas.md b/02-Context-or-Narrative/Our-Outcome-Ideas.md index d56960a..edbf9a6 100644 --- a/02-Context-or-Narrative/Our-Outcome-Ideas.md +++ b/02-Context-or-Narrative/Our-Outcome-Ideas.md @@ -58,10 +58,16 @@ Sometimes, Pursuit docs don't help you know how to use something. However, a lot I've begun to do this myself [here](https://github.com/JordanMartinez/purescript-jordans-reference/tree/latestRelease/22-Projects/src/01-Libraries) with a few libraries that I've used when building some projects. Perhaps I will later turn this into a separate top-level folder and call it "cookbook" -## Unsorted Ideas +## Goal: Document "best practices" for writing a good bindings library. -Rather, we (non-core-contributors / users of PS) can focus on answering questions like these: -- What are "best practices" for various topics/areas? For example: - - Guidelines for writing a good bindings library - - How should a library author analyze the library to which they want to write bindings? - - What are common problems such people face and their possible solutions? +``` +Worst ---------- Ok ---------------------------- Great +No libraries Bindings to JS library PS library +``` +While JS library bindings aren't ideal, they can still solve a problem quickly. Knowing how to write a good bindings library can help make the PS ecosystem that much more mature. + +Some questions people might ask: +- How should a library author analyze the library to which they want to write bindings? +- What are common problems such people face and their possible solutions? + +### How: ??? From 0c788204d5397610204e70d5eb80d773a50b8310 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 13 Apr 2019 16:23:00 -0700 Subject: [PATCH 121/133] Generate 'our ideas' ToC --- 02-Context-or-Narrative/Our-Outcome-Ideas.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/02-Context-or-Narrative/Our-Outcome-Ideas.md b/02-Context-or-Narrative/Our-Outcome-Ideas.md index edbf9a6..ed43801 100644 --- a/02-Context-or-Narrative/Our-Outcome-Ideas.md +++ b/02-Context-or-Narrative/Our-Outcome-Ideas.md @@ -1,5 +1,20 @@ # Our Outcome Ideas +The below Table of contents was generated by http://tableofcontent.eu + +- [Goal: The top 30 dependencies used in PS' ecosystem have examples and counterexamples in all of their Pursuit docs.](#goal-the-top-30-dependencies-used-in-ps-ecosystem-have-examples-and-counterexamples-in-all-of-their-pursuit-docs) + - [How: A community-curated "ACME" Spago project](#how-a-community-curated-acme-spago-project) +- [Goal: Collect the best and clearest explanations for FP concepts into a central location](#goal-collect-the-best-and-clearest-explanations-for-fp-concepts-into-a-central-location) + - [How: Add it to Jordan's learning repository](#how-add-it-to-jordans-learning-repository) +- [Goal: Convert all answered Slack-based questions into StackOverflow Questions and Answers](#goal-convert-all-answered-slack-based-questions-into-stackoverflow-questions-and-answers) + - [How: Reask and reanswer it on StackOverflow](#how-reask-and-reanswer-it-on-stackoverflow) +- [Goal: Collect the best solutions to common build-related problems into a central location](#goal-collect-the-best-solutions-to-common-build-related-problems-into-a-central-location) + - [How: Add it to a special "build" repository](#how-add-it-to-a-special-build-repository) +- [Goal: Add Syntax Examples for Core Libraries](#goal-add-syntax-examples-for-core-libraries) + - [How: Document a syntax example in Jordan's Learning Repo](#how-document-a-syntax-example-in-jordans-learning-repo) +- [Goal: Document "best practices" for writing a good bindings library.](#goal-document-best-practices-for-writing-a-good-bindings-library) + - [How: ???](#how) + ## Goal: The top 30 dependencies used in PS' ecosystem have examples and counterexamples in all of their Pursuit docs. ### How: A community-curated "ACME" Spago project From de522ecac9b14c55ce79a3e0373de900c95cf798 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 13 Apr 2019 16:25:04 -0700 Subject: [PATCH 122/133] Generate 'state of ps docs' ToC --- .../State-of-PureScript-Documentation-2019.md | 23 ++++++++----------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 311bde0..6575295 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -14,22 +14,17 @@ Numerous parties within the PureScript community (e.g. [core contributors](), [u 3. Summarize the current opinions of PureScript's documentation audiences. 4. Explore strategies for improving PureScript's documentation for its audiences. - - +Table of Contents - [What is "Good" Documentation Anyway?](#what-is-good-documentation-anyway) - - [The Types of Documentation](#the-types-of-documentation) - - [The Documentation's Intended Audience](#the-documentations-intended-audience) - - [Maintaining Documentation's Accuracy](#maintaining-documentations-accuracy) - - [The "Size" of a Change](#the-size-of-a-change) - - [The "Frequency" of a Change](#the-frequency-of-a-change) - - [How to Make Maintenance Easier](#how-to-make-maintenance-easier) - - [Criteria for "Good" Documentation](#criteria-for-good-documentation) - [Evaluating PureScript's Documentation](#evaluating-purescripts-documentation) -- [Why is PureScript's Documentation Lacking and How Do We Improve It?](#why-is-purescripts-documentation-lacking-and-how-do-we-improve-it) -- [New Learners: What is the Best Way to Learn PureScript?](#new-learners-what-is-the-best-way-to-learn-purescript) -- [PureScript Documentation Writers: What is the Best Way to Write Documentation in this Context?](#purescript-documentation-writers-what-is-the-best-way-to-write-documentation-in-this-context) -- [Core Contributors: ???](#core-contributors-) - +- [Why is PureScript's Documentation Lacking?](#why-is-purescripts-documentation-lacking) +- [Addressing Audiences](#addressing-audiences) + - [New Learners: What is the Best Way to Learn PureScript?](#new-learners-what-is-the-best-way-to-learn-purescript) + - [PureScript Documentation Writers: What is the Best Way to Write Documentation in this Context?](#purescript-documentation-writers-what-is-the-best-way-to-write-documentation-in-this-context) + - [Core Contributors: "How Should We Support You?" and Other General Feedback](#core-contributors-how-should-we-support-you-and-other-general-feedback) +- [Everyone: What Should Our Documentation Outcomes Be?](#everyone-what-should-our-documentation-outcomes-be) + +(The above Table of contents was generated by http://tableofcontent.eu) ## What is "Good" Documentation Anyway? From a4e919fefc4f96dd070c1e346933d30bbeaab585 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 13 Apr 2019 16:26:28 -0700 Subject: [PATCH 123/133] Move OOM section to 'outdated' section --- .../Why-Docs-Are-Lacking.md | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/02-Context-or-Narrative/Why-Docs-Are-Lacking.md b/02-Context-or-Narrative/Why-Docs-Are-Lacking.md index 9455a4b..cbc6fd1 100644 --- a/02-Context-or-Narrative/Why-Docs-Are-Lacking.md +++ b/02-Context-or-Narrative/Why-Docs-Are-Lacking.md @@ -201,19 +201,6 @@ If done after a `v1.0`, then many libraries and docs will need to be updated, th (Related interpretation sections: [Lack of a clearly-defined communit-wide mutually-held vision/goal](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#lack-of-a-clearly-defined-community-wide-mutually-held-visiongoal), [Lack of a clearly-defined core-contributor-wide mutually-held language specification](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#lack-of-a-clearly-defined-core-contributor-wide-mutually-held-language-specification), [Fear that people will misinterpret at "v1.0" compiler release for a "v1.0" ecosystem release](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#fear-that-people-will-misinterpret-a-v10-compiler-release-for-a-v10-ecosystem-release)) -### Some libraries cannot publish their docs due to OOM error - -From [pulp version runs out of memory (fatal exception) - Issue 351](https://github.com/purescript-contrib/pulp/issues/351): -- Context: Bower is used to produce the "resolutions file" that the compiler expects - - > The compiler expects a “resolutions file” in a similar format to the output of this problematic bower command. We only need a very small portion of the information produced by that command though; for each dependency, if the bower.json specifies anything other than a version range for it, we need to know so that we can produce a warning about that. Otherwise, we need to know which version bower’s solver picked. If I remember correctly that’s everything. Unfortunately I’m not aware of a more sensible variant of bower list which produces all the information we need. [comment in issue, paragraph 2](https://github.com/purescript-contrib/pulp/issues/351#issuecomment-395611759) -- Problem: Bower throws a `RangeError` when attempting to `JSON.stringify` an object that includes a massive dependency tree due to duplicate transitive dependencies: - - > Bower builds a log object, which has our dependency tree. When they try to JSON.stringify this object, it throws RangeError: Invalid string length [comment in issue](https://github.com/purescript-contrib/pulp/issues/351#issuecomment-395605607) - -The proposed solution: change the compiler's "resolution file" schema. Unfortunately, this is a breaking change (tracking issue: [Simplify `purs publish` resolution format](https://github.com/purescript/purescript/issues/3499)): - - > To clarify, the course of action I'm suggesting is that we have `pulp` actually look through the filesystem and collect the resolutions data, and we then pass that information to the compiler. It would make our lives easier if we could also change the compiler so that it accepts this information using a more sensible schema than that of `bower list --offline --json` (and this is what I'm suggesting in that issue ([comment in issue](https://github.com/purescript-contrib/pulp/issues/351#issuecomment-450465708))). - -Thus, a heavily-used library like `Halogen` cannot publish its `v4.0.0` or `v5.0.0` docs on Pursuit. Unfortunately, there's nothing they can do about it. - ### The current support system doesn't build towards structured, persistent documentation Because the documentation is lacking, many are encouraged to ask their questions on the `#purescript` channel in the FP Slack. Many have greatly benefited from the quick answers they receive. @@ -230,3 +217,20 @@ However, the format is poor. One must read through a (sometimes) lengthy convers Contrast that with an StackOverflow question and answer that appears in a Google search. (Related interpretation section: [PureScript's Mediums of Communication](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#purescripts-mediums-of-communication)) + +## Outdated + +The below section contains summaries that are no longer true. + +### Some libraries cannot publish their docs due to OOM error + +From [pulp version runs out of memory (fatal exception) - Issue 351](https://github.com/purescript-contrib/pulp/issues/351): +- Context: Bower is used to produce the "resolutions file" that the compiler expects + - > The compiler expects a “resolutions file” in a similar format to the output of this problematic bower command. We only need a very small portion of the information produced by that command though; for each dependency, if the bower.json specifies anything other than a version range for it, we need to know so that we can produce a warning about that. Otherwise, we need to know which version bower’s solver picked. If I remember correctly that’s everything. Unfortunately I’m not aware of a more sensible variant of bower list which produces all the information we need. [comment in issue, paragraph 2](https://github.com/purescript-contrib/pulp/issues/351#issuecomment-395611759) +- Problem: Bower throws a `RangeError` when attempting to `JSON.stringify` an object that includes a massive dependency tree due to duplicate transitive dependencies: + - > Bower builds a log object, which has our dependency tree. When they try to JSON.stringify this object, it throws RangeError: Invalid string length [comment in issue](https://github.com/purescript-contrib/pulp/issues/351#issuecomment-395605607) + +The proposed solution: change the compiler's "resolution file" schema. Unfortunately, this is a breaking change (tracking issue: [Simplify `purs publish` resolution format](https://github.com/purescript/purescript/issues/3499)): + - > To clarify, the course of action I'm suggesting is that we have `pulp` actually look through the filesystem and collect the resolutions data, and we then pass that information to the compiler. It would make our lives easier if we could also change the compiler so that it accepts this information using a more sensible schema than that of `bower list --offline --json` (and this is what I'm suggesting in that issue ([comment in issue](https://github.com/purescript-contrib/pulp/issues/351#issuecomment-450465708))). + +Thus, a heavily-used library like `Halogen` cannot publish its `v4.0.0` or `v5.0.0` docs on Pursuit. Unfortunately, there's nothing they can do about it. From 461e9a5a9a83862a97d122319d6874886f52d8a3 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 13 Apr 2019 16:27:35 -0700 Subject: [PATCH 124/133] Update header levels by reducing them by one: 'why docs lacking' file --- .../Why-Docs-Are-Lacking.md | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/02-Context-or-Narrative/Why-Docs-Are-Lacking.md b/02-Context-or-Narrative/Why-Docs-Are-Lacking.md index cbc6fd1..748a5ea 100644 --- a/02-Context-or-Narrative/Why-Docs-Are-Lacking.md +++ b/02-Context-or-Narrative/Why-Docs-Are-Lacking.md @@ -1,6 +1,6 @@ # Why Docs Are Lacking -### What Exactly are FP's "Best Practices" +## What Exactly are FP's "Best Practices" Coming from an Object-Oriented Paradigm, some have asked, "Why aren't the best practices / design patterns / idioms in Functional Programming explained/documented?" @@ -21,7 +21,7 @@ FP languages tend to draw people who are intellectually curious. These people te (Related interpretation section: [FP "best practices" are not well-defined, are assumed, or are unconscious habits](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#fp-best-practices-are-not-well-defined-are-assumed-or-are-unconscious-habits), [FP's culture creates "knowledge silos"](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#fps-culture-creates-knowledge-silos)) -### PureScript is not _currently_ trying to be the next "mainstream language" +## PureScript is not _currently_ trying to be the next "mainstream language" A few have wrongly assumed that PureScript is trying to replace [insert your favorite web language here]. That is not the case. @@ -49,7 +49,7 @@ Thus, PureScript might not be the language for you: (Related interpretation sections: [Keeping the motto of `Avoid "success at all costs"` and understanding its meaning](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#knowing-whom-to-trust-with-write-access-defining-best-workflow-procedures-and-providing-necessary-support)) -### Only core contributors have write / deployment privileges to PureScript websites +## Only core contributors have write / deployment privileges to PureScript websites The following PureScript websites either are outdated or could be modified to improve the documentation situation. @@ -61,7 +61,7 @@ Who can merge PRs into the websites' repositories and redeploy them once these P | Pursuit | Core Contributors | Phil Freeman | [The State of Things, point 2](https://discourse.purescript.org/t/the-state-of-things/282) | Try PureScript | Core Contributors | Phil Freeman | [The State of Things, point 2](https://discourse.purescript.org/t/the-state-of-things/282) -### Core contributors are spread thin +## Core contributors are spread thin > It’s been 7 months since I announced that I would be taking a long break from PureScript development.... > @@ -93,7 +93,7 @@ Thank you for the language you have created, the libraries you wrote and maintai Thank you for putting up with frustrating people, enduring negative and impatient attitudes, and trolls. -#### Implications +### Implications Reviewing documentation can be just as difficult as reviewing code. Some people are faster at reviewing things than others. @@ -106,7 +106,7 @@ Lastly, I (Jordan) don't know whether some tasks could be automated and whether (Related interpretation sections: [Limited Manpower / Not Enough Automation](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#limited-manpower--not-enough-automation), [Slow submitted-reviewed-merged timeline of documentation kills momentum](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#slow-submitted-reviewed-merged-timeline-of-documentation-prs-kills-documentation-momentum), [Reviewing documentation PRS can be just as difficult as code PRs](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#reviewing-documentation-prs-can-be-just-as-difficult-as-code-prs)) -#### Why Not Just Delegate? +### Why Not Just Delegate? > A hypothetical developer says, "If it's so much work, why not just **delegate** the work? This 'somebody' can also be a proxy who's gathering feedback, so that you don't have to be in these discussions." > @@ -130,7 +130,7 @@ New maintainers, once found and properly screened, have to be supported (which t (Related interpretation sections: [Knowing whom to trust with write access, defining best workflow procedures, and providing necessary support](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#knowing-whom-to-trust-with-write-access-defining-best-workflow-procedures-and-providing-necessary-support)) -#### Why Not Just Fund the Language Developers? +### Why Not Just Fund the Language Developers? Been there, done that. Someone took it down. ([PureScript Open Collective]((https://opencollective.com/purescript)) @@ -144,7 +144,7 @@ Our viewpoint of this situation: Perhaps this idea could be revisited in the future. For now, we cannot say. -### Breaking Changes Outdate Documentation and Kill Documenters' Motivation +## Breaking Changes Outdate Documentation and Kill Documenters' Motivation The main 'go-to' documentation resource for PureScript was/is [PureScript By Example](https://leanpub.com/purescript/) by Phil Freeman. This resource documents the `0.11.7` PureScript release. The current PureScript release is `0.12.3` (as of this writing). @@ -160,7 +160,7 @@ Gary later pointed out that releases with "breaking changes" were occuring less (Related interpretation sections: [Breaking Changes Render Documentation Outdated](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#breaking-changes-renders-documentation-outdated)) -### There Is No Roadmap That Coordinates Efforts +## There Is No Roadmap That Coordinates Efforts Defining a roadmap is hard. It's easy to... - ...disagree on which goals should be pursued and which to ignore @@ -175,7 +175,7 @@ Therefore: - Those who could help do not know where help is needed - Those who would help do not know how they can help -#### Avoiding a `v1.0` PureScript language release +### Avoiding a `v1.0` PureScript language release When people announce "Language X is now `1.0`!", it tends to draw a lot of focus and a lot of traffic. People probably think, "Wow! It's now stable enough to be used to write all my programs." @@ -189,7 +189,7 @@ What good is a `v1.0` language, if Thus, core contributors might avoid defining a roadmap to prevent people from having a `v1.0` ecosystem connotation. -#### Defining a Language Specification +### Defining a Language Specification When should future breaking changes be done: before a `v1.0` or afterwards? @@ -201,7 +201,7 @@ If done after a `v1.0`, then many libraries and docs will need to be updated, th (Related interpretation sections: [Lack of a clearly-defined communit-wide mutually-held vision/goal](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#lack-of-a-clearly-defined-community-wide-mutually-held-visiongoal), [Lack of a clearly-defined core-contributor-wide mutually-held language specification](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#lack-of-a-clearly-defined-core-contributor-wide-mutually-held-language-specification), [Fear that people will misinterpret at "v1.0" compiler release for a "v1.0" ecosystem release](https://github.com/chexxor/purescript-documentation-discussion/blob/master/01-Sources-and-Interpretation/All-Interpretations.md#fear-that-people-will-misinterpret-a-v10-compiler-release-for-a-v10-ecosystem-release)) -### The current support system doesn't build towards structured, persistent documentation +## The current support system doesn't build towards structured, persistent documentation Because the documentation is lacking, many are encouraged to ask their questions on the `#purescript` channel in the FP Slack. Many have greatly benefited from the quick answers they receive. From 91a7021529a5344bdb88aceaf93ead17437ad7f3 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 13 Apr 2019 16:28:50 -0700 Subject: [PATCH 125/133] Generate 'why docs are lacking' ToC --- 02-Context-or-Narrative/Why-Docs-Are-Lacking.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/02-Context-or-Narrative/Why-Docs-Are-Lacking.md b/02-Context-or-Narrative/Why-Docs-Are-Lacking.md index 748a5ea..fd5a95d 100644 --- a/02-Context-or-Narrative/Why-Docs-Are-Lacking.md +++ b/02-Context-or-Narrative/Why-Docs-Are-Lacking.md @@ -1,5 +1,22 @@ # Why Docs Are Lacking +- [What Exactly are FP's "Best Practices"](#what-exactly-are-fps-best-practices) +- [PureScript is not _currently_ trying to be the next "mainstream language"](#purescript-is-not-_currently_-trying-to-be-the-next-mainstream-language) +- [Only core contributors have write / deployment privileges to PureScript websites](#only-core-contributors-have-write-deployment-privileges-to-purescript-websites) +- [Core contributors are spread thin](#core-contributors-are-spread-thin) + - [Implications](#implications) + - [Why Not Just Delegate?](#why-not-just-delegate) + - [Why Not Just Fund the Language Developers?](#why-not-just-fund-the-language-developers) +- [Breaking Changes Outdate Documentation and Kill Documenters' Motivation](#breaking-changes-outdate-documentation-and-kill-documenters-motivation) +- [There Is No Roadmap That Coordinates Efforts](#there-is-no-roadmap-that-coordinates-efforts) + - [Avoiding a `v1.0` PureScript language release](#avoiding-a-v10-purescript-language-release) + - [Defining a Language Specification](#defining-a-language-specification) +- [The current support system doesn't build towards structured, persistent documentation](#the-current-support-system-doesnt-build-towards-structured-persistent-documentation) +- [Outdated](#outdated) + - [Some libraries cannot publish their docs due to OOM error](#some-libraries-cannot-publish-their-docs-due-to-oom-error) + +(The above Table of Contents was generated by: http://tableofcontent.eu) + ## What Exactly are FP's "Best Practices" Coming from an Object-Oriented Paradigm, some have asked, "Why aren't the best practices / design patterns / idioms in Functional Programming explained/documented?" From a610cf68df53b0d6201946a61735d0c02e32e6bb Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 13 Apr 2019 16:29:40 -0700 Subject: [PATCH 126/133] Decrease header levels in 'good documentation.md' file --- 02-Context-or-Narrative/Good-Documentation.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/02-Context-or-Narrative/Good-Documentation.md b/02-Context-or-Narrative/Good-Documentation.md index 796b975..5ec2b16 100644 --- a/02-Context-or-Narrative/Good-Documentation.md +++ b/02-Context-or-Narrative/Good-Documentation.md @@ -13,7 +13,7 @@ Essentially, there are 3 factors that affect whether documentation is "good" or It's important to note that this section is sourced from only two blog posts, [What Nobody Tells You About Documentation](https://www.divio.com/blog/documentation/) and [Teach, Don't Tell](http://stevelosh.com/blog/2013/09/teach-dont-tell/). As we learn more this section might change in significant ways, so any conclusions we draw should be kept "flexible". -### The Types of Documentation +## The Types of Documentation First, there are 5 types of documentation that target specific phases of a learner's experience (as explained in [What Nobody Tells You About Documentation](https://www.divio.com/blog/documentation/) and [Teach, Don't Tell](http://stevelosh.com/blog/2013/09/teach-dont-tell/)) @@ -34,7 +34,7 @@ Moreover, there are clear examples of "bad" documentation (as explained in [Teac | API docs | One must know the name of the function/value to be able to read its documentation. Most won't know the name until you teach it to them. Likewise, people don't learn by reading alphabetized lists of disconnected information | Wiki | Content is usually not written by the code's authors, but by multiple 3rd-party people. There are often multiple disconnected voices throughout the material. It's like asking a student to write his own lesson plan. -### The Documentation's Intended Audience +## The Documentation's Intended Audience Second, the number of intended audiences can vary greatly. For example, here are different ways of categorizing them: - The language/paradigms they primarily use and think in (e.g. JavaScript, Ruby, Haskell; lazy, strict; OO, FP; etc.) @@ -48,13 +48,13 @@ As a result, others who read the resulting documentation will consider it "poor" - If one comes from a different experience level, one might have unanswered questions: "They didn't even mention what the performance trade-offs for specific libraries were..." ~ a senior developer - If one has a different goal in mind, some crucial libraries might never be covered: "They didn't explain how I can make my Bitcoin client cryptographically secure..." -### Maintaining Documentation's Accuracy +## Maintaining Documentation's Accuracy Third, documentation becomes outdated/inaccurate when the thing being documented changes in two ways: - the 'size' of a change - the 'frequency' of changes -#### The "Size" of a Change +### The "Size" of a Change The 'size' of a change can decrease its usefulness. @@ -73,7 +73,7 @@ When breaking changes occur, documentation can immediately become useless becaus Updating documentation in light of breaking changes often requires the most work to update. -#### The "Frequency" of a Change +### The "Frequency" of a Change The 'frequency' of a change can decrease its coherence. @@ -89,7 +89,7 @@ When changes occur frequently, documentation can appear more like loosely-couple Updating documentation in light of frequent changes often requires less overall work. -#### How to Make Maintenance Easier +### How to Make Maintenance Easier Moreover, when breaking changes occur frequently, it discourages people from updating the documentation. Why waste time on something that will become outdated soon? @@ -103,7 +103,7 @@ Other mediums of documentation (e.g. blog posts, literate programming, videos) e Lastly, some documentations tasks are tedious and consume lots of time. Finding ways to automate them can greatly improve the situation. -### Criteria for "Good" Documentation +## Criteria for "Good" Documentation In short, it is impossible to write "good" documentation for everyone that is always up-to-date. There's simply not enough manpower, time, and incentives to do that. Rather, it will be "good", "horrible", or "somewhere in-between" for diffent kinds of people and at different times/seasons. From 9ee1a8651f796ab8bcf2cdb6df9c455317734b61 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 13 Apr 2019 16:30:31 -0700 Subject: [PATCH 127/133] Generate ToC for 'good documentation.md' file --- 02-Context-or-Narrative/Good-Documentation.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/02-Context-or-Narrative/Good-Documentation.md b/02-Context-or-Narrative/Good-Documentation.md index 5ec2b16..33c2075 100644 --- a/02-Context-or-Narrative/Good-Documentation.md +++ b/02-Context-or-Narrative/Good-Documentation.md @@ -1,5 +1,16 @@ # Good Documentation +- [What is "Good" Documentation Anyway?](#what-is-good-documentation-anyway) +- [The Types of Documentation](#the-types-of-documentation) +- [The Documentation's Intended Audience](#the-documentations-intended-audience) +- [Maintaining Documentation's Accuracy](#maintaining-documentations-accuracy) + - [The "Size" of a Change](#the-size-of-a-change) + - [The "Frequency" of a Change](#the-frequency-of-a-change) + - [How to Make Maintenance Easier](#how-to-make-maintenance-easier) +- [Criteria for "Good" Documentation](#criteria-for-good-documentation) + +(The above Table of Contents was generated by: http://tableofcontent.eu) + ## What is "Good" Documentation Anyway? Did someone ever teach you how to write "good" documentation? Probably not - you likely just wrote what came to mind and hoped it was good enough. From 26c4a60e6d5047d2d163ea53b04b237af2d17433 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 13 Apr 2019 16:32:58 -0700 Subject: [PATCH 128/133] Adjust document's purpose --- .../State-of-PureScript-Documentation-2019.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 6575295..27b4401 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -7,12 +7,11 @@ Numerous parties within the PureScript community (e.g. [core contributors](), [u (Purpose) The following document tries to do the following things: 1. Provide a researched narrative of PureScript's documentation development and history. -2. Define the types of audiences of PureScript documentation and their expectations. +2. Speak to individual audiences - New learners (regardless of language background) - PureScript documentation writers - Core contributors -3. Summarize the current opinions of PureScript's documentation audiences. -4. Explore strategies for improving PureScript's documentation for its audiences. +3. Brainstorm outcomes for improving PureScript's documentation in this context. Table of Contents - [What is "Good" Documentation Anyway?](#what-is-good-documentation-anyway) From f85df758618990e9de0d9747d49a53ac5da77621 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Thu, 25 Apr 2019 19:10:58 -0700 Subject: [PATCH 129/133] Change header to emphasize the criteria definition of section --- .../State-of-PureScript-Documentation-2019.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 27b4401..da63126 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -14,7 +14,7 @@ Numerous parties within the PureScript community (e.g. [core contributors](), [u 3. Brainstorm outcomes for improving PureScript's documentation in this context. Table of Contents -- [What is "Good" Documentation Anyway?](#what-is-good-documentation-anyway) +- [Defining a Criteria: What is "Good" Documentation Anyway?](#defining-a-criteria--what-is-good-documentation-anyway) - [Evaluating PureScript's Documentation](#evaluating-purescripts-documentation) - [Why is PureScript's Documentation Lacking?](#why-is-purescripts-documentation-lacking) - [Addressing Audiences](#addressing-audiences) @@ -25,7 +25,7 @@ Table of Contents (The above Table of contents was generated by http://tableofcontent.eu) -## What is "Good" Documentation Anyway? +## Defining a Criteria: What is "Good" Documentation Anyway? There are 5 types of documentation that target specific phases of a learner's experience (as explained in [What Nobody Tells You About Documentation](https://www.divio.com/blog/documentation/) and [Teach, Don't Tell](http://stevelosh.com/blog/2013/09/teach-dont-tell/)) From b487c60e5c0ec5d6526ee17e005f276603745cf5 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 27 Apr 2019 10:23:31 -0700 Subject: [PATCH 130/133] Clarify: do not understand 'doc types' table as linear progression --- .../State-of-PureScript-Documentation-2019.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index da63126..18cdca6 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -29,6 +29,8 @@ Table of Contents There are 5 types of documentation that target specific phases of a learner's experience (as explained in [What Nobody Tells You About Documentation](https://www.divio.com/blog/documentation/) and [Teach, Don't Tell](http://stevelosh.com/blog/2013/09/teach-dont-tell/)) +Do not misinterpret the below table as a linear progression from Curious Outsider onward. Rather, these are different spots on a 2-axis graph (see the end of 'What Nobody Tells You About Documentation') for a visual. + | Learner's Phase | Type | Analogy | Characteristics | -- | -- | -- | -- | | Curious Outsider | The Hook | Selling a product to a potential customer | Answers these questions:
  • What is this thing? / What problem does it solve?
  • Why whould I care? / How is this relevant to me for my purposes? / Who should not care?
  • How long will it take to learn it and how difficult is the learning curve?
  • Where do I go to get started / learn how to use this?
From fc1460bdfe9f740ca378e1880b8a260448479880 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 27 Apr 2019 10:24:11 -0700 Subject: [PATCH 131/133] Fix typo: 'whould' -> 'would' --- .../State-of-PureScript-Documentation-2019.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index 18cdca6..b35f5dd 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -33,7 +33,7 @@ Do not misinterpret the below table as a linear progression from Curious Outside | Learner's Phase | Type | Analogy | Characteristics | -- | -- | -- | -- | -| Curious Outsider | The Hook | Selling a product to a potential customer | Answers these questions:
  • What is this thing? / What problem does it solve?
  • Why whould I care? / How is this relevant to me for my purposes? / Who should not care?
  • How long will it take to learn it and how difficult is the learning curve?
  • Where do I go to get started / learn how to use this?
+| Curious Outsider | The Hook | Selling a product to a potential customer | Answers these questions:
  • What is this thing? / What problem does it solve?
  • Why would I care? / How is this relevant to me for my purposes? / Who should not care?
  • How long will it take to learn it and how difficult is the learning curve?
  • Where do I go to get started / learn how to use this?
| Potential User | Getting Started | Teaching a child how to cook |
  • Focuses on the learner 'doing' stuff, not 'explaining' stuff to the learner
  • Provides a small simple working example that teaches the basics
  • New learners experience an 'I can use this now!' moment by the end
  • Focuses on concrete tasks, not abstract concepts
  • Does not use jargon
  • Explains only what is necessary and cuts out all else
  • Avoids explaining deeper concepts or different ways of doing the same thing
| New User | How-To Guides | Following a cookbook's recipe |
  • Achieves some goal or solves a problem
  • States the pre-requisites one needs to have before starting (not a Getting Started Guide)
  • The Guide follows a clearly-labeled step-by-step process
  • By following the steps, one reproduces the same results without fail
  • Explains the different ways one can achieve the same goal
  • Explains only what is necessary
| Active User | Reference | Reading an encyclopedia |
  • Concise explanation of each piece of the code
  • The structure of the reference mirrors the structure of the code it documents
  • Formatting is consistent throughout the material
From ed01b07faf88123db80ccdb44a1cf50ef79aaab8 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 27 Apr 2019 10:35:40 -0700 Subject: [PATCH 132/133] Document idea about improving testing libraries --- 02-Context-or-Narrative/Our-Outcome-Ideas.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/02-Context-or-Narrative/Our-Outcome-Ideas.md b/02-Context-or-Narrative/Our-Outcome-Ideas.md index ed43801..5e4d12f 100644 --- a/02-Context-or-Narrative/Our-Outcome-Ideas.md +++ b/02-Context-or-Narrative/Our-Outcome-Ideas.md @@ -85,4 +85,12 @@ Some questions people might ask: - How should a library author analyze the library to which they want to write bindings? - What are common problems such people face and their possible solutions? -### How: ??? + ### How: TBD + +## Goal: Improve guides for how to test applications / test libraries + +Inspired by [this comment](https://github.com/JordanMartinez/purescript-jordans-reference/issues/280#issuecomment-485144396), producing a stable library or finished application could be slowed down if writing tests get slowed down by small issues like this. + + ### How: TBD + +One idea is to write more convenience functions that make it easier to generate the `String`s we need. From 50351c1aae8346c0f24125157316476ebb310db8 Mon Sep 17 00:00:00 2001 From: Alex Berg Date: Sat, 4 May 2019 15:17:01 -0500 Subject: [PATCH 133/133] Header revising in context/narrative (#68) * Header revising in context/narrative --- .../State-of-PureScript-Documentation-2019.md | 20 ++++++------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md index b35f5dd..b751ecf 100644 --- a/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md +++ b/02-Context-or-Narrative/State-of-PureScript-Documentation-2019.md @@ -5,18 +5,10 @@ This document is not meant to convince you to use PureScript, we assume that rea Numerous parties within the PureScript community (e.g. [core contributors](), [users](), [new learners]()) believe that the documentation is lacking in some critical areas. As a result, @chexxor started the [PureScript documentation efforts in 2019](https://discourse.purescript.org/t/purescript-documentation-efforts-in-2019/524) Discourse thread to answer one question: > How can we improve the PureScript documentation in 2019? -(Purpose) The following document tries to do the following things: -1. Provide a researched narrative of PureScript's documentation development and history. -2. Speak to individual audiences - - New learners (regardless of language background) - - PureScript documentation writers - - Core contributors -3. Brainstorm outcomes for improving PureScript's documentation in this context. - Table of Contents -- [Defining a Criteria: What is "Good" Documentation Anyway?](#defining-a-criteria--what-is-good-documentation-anyway) - - [Evaluating PureScript's Documentation](#evaluating-purescripts-documentation) -- [Why is PureScript's Documentation Lacking?](#why-is-purescripts-documentation-lacking) +- [Defining a Criteria: What is "Good" Documentation Anyway?](#defining-a-criteria-what-is-good-documentation-anyway) +- [Assessing PureScript's Documentation](#assessing-purescripts-documentation) +- [What are Factors Affecting PureScript's Documentation Quality?](#what-are-factors-affecting-purescripts-documentation-quality) - [Addressing Audiences](#addressing-audiences) - [New Learners: What is the Best Way to Learn PureScript?](#new-learners-what-is-the-best-way-to-learn-purescript) - [PureScript Documentation Writers: What is the Best Way to Write Documentation in this Context?](#purescript-documentation-writers-what-is-the-best-way-to-write-documentation-in-this-context) @@ -50,9 +42,9 @@ Moreover, there are clear examples of "bad" documentation (as explained in [Teac Note: this section is sourced from only two blog posts, [What Nobody Tells You About Documentation](https://www.divio.com/blog/documentation/) and [Teach, Don't Tell](http://stevelosh.com/blog/2013/09/teach-dont-tell/). Understand these as a starting point for defining a criteria for "good" documentation, not a final "there's nothing more to say" conclusion. -### Evaluating PureScript's Documentation +## Assessing PureScript's Documentation -Below, we tagged each documentation effort with its documentation type (if yours isn't listed or is incorrect, notify us). By looking at what exists, we can see that the following types of documentation are lacking: +Below, we tagged each documentation effort with its documentation type (if yours isn't listed or is incorrect, notify us). By looking at what exists, we can see that the following types of documentation might need more improvement: - Hooks - How-To Guides - Explanations @@ -84,7 +76,7 @@ Here's what has been added to the above since then: | A Guide to the PureScript Numeric Hierarchy | Explanation | New Learners | Read the Docs | Make the Leap from JavaScript to PureScript | Getting Started + Explanation | Javascript developers | Blog Post series -## Why is PureScript's Documentation Lacking? +## What are Factors Affecting PureScript's Documentation Quality? Here's the short version. Each paragraph will have a link that explains its summary in more detail.