├── LICENSE.md
├── NFTs.md
├── sotu.md
└── voice-feminization.md
/LICENSE.md:
--------------------------------------------------------------------------------
1 | # Attribution 4.0 International
2 |
3 | Creative Commons Corporation (“Creative Commons”) is not a law firm and does not provide legal services or legal advice. Distribution of Creative Commons public licenses does not create a lawyer-client or other relationship. Creative Commons makes its licenses and related information available on an “as-is” basis. Creative Commons gives no warranties regarding its licenses, any material licensed under their terms and conditions, or any related information. Creative Commons disclaims all liability for damages resulting from their use to the fullest extent possible.
4 |
5 | ### Using Creative Commons Public Licenses
6 |
7 | Creative Commons public licenses provide a standard set of terms and conditions that creators and other rights holders may use to share original works of authorship and other material subject to copyright and certain other rights specified in the public license below. The following considerations are for informational purposes only, are not exhaustive, and do not form part of our licenses.
8 |
9 | * __Considerations for licensors:__ Our public licenses are intended for use by those authorized to give the public permission to use material in ways otherwise restricted by copyright and certain other rights. Our licenses are irrevocable. Licensors should read and understand the terms and conditions of the license they choose before applying it. Licensors should also secure all rights necessary before applying our licenses so that the public can reuse the material as expected. Licensors should clearly mark any material not subject to the license. This includes other CC-licensed material, or material used under an exception or limitation to copyright. [More considerations for licensors](http://wiki.creativecommons.org/Considerations_for_licensors_and_licensees#Considerations_for_licensors).
10 |
11 | * __Considerations for the public:__ By using one of our public licenses, a licensor grants the public permission to use the licensed material under specified terms and conditions. If the licensor’s permission is not necessary for any reason–for example, because of any applicable exception or limitation to copyright–then that use is not regulated by the license. Our licenses grant only permissions under copyright and certain other rights that a licensor has authority to grant. Use of the licensed material may still be restricted for other reasons, including because others have copyright or other rights in the material. A licensor may make special requests, such as asking that all changes be marked or described. Although not required by our licenses, you are encouraged to respect those requests where reasonable. [More considerations for the public](http://wiki.creativecommons.org/Considerations_for_licensors_and_licensees#Considerations_for_licensees).
12 |
13 | ## Creative Commons Attribution 4.0 International Public License
14 |
15 | By exercising the Licensed Rights (defined below), You accept and agree to be bound by the terms and conditions of this Creative Commons Attribution 4.0 International Public License ("Public License"). To the extent this Public License may be interpreted as a contract, You are granted the Licensed Rights in consideration of Your acceptance of these terms and conditions, and the Licensor grants You such rights in consideration of benefits the Licensor receives from making the Licensed Material available under these terms and conditions.
16 |
17 | ### Section 1 – Definitions.
18 |
19 | a. __Adapted Material__ means material subject to Copyright and Similar Rights that is derived from or based upon the Licensed Material and in which the Licensed Material is translated, altered, arranged, transformed, or otherwise modified in a manner requiring permission under the Copyright and Similar Rights held by the Licensor. For purposes of this Public License, where the Licensed Material is a musical work, performance, or sound recording, Adapted Material is always produced where the Licensed Material is synched in timed relation with a moving image.
20 |
21 | b. __Adapter's License__ means the license You apply to Your Copyright and Similar Rights in Your contributions to Adapted Material in accordance with the terms and conditions of this Public License.
22 |
23 | c. __Copyright and Similar Rights__ means copyright and/or similar rights closely related to copyright including, without limitation, performance, broadcast, sound recording, and Sui Generis Database Rights, without regard to how the rights are labeled or categorized. For purposes of this Public License, the rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights.
24 |
25 | d. __Effective Technological Measures__ means those measures that, in the absence of proper authority, may not be circumvented under laws fulfilling obligations under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, and/or similar international agreements.
26 |
27 | e. __Exceptions and Limitations__ means fair use, fair dealing, and/or any other exception or limitation to Copyright and Similar Rights that applies to Your use of the Licensed Material.
28 |
29 | f. __Licensed Material__ means the artistic or literary work, database, or other material to which the Licensor applied this Public License.
30 |
31 | g. __Licensed Rights__ means the rights granted to You subject to the terms and conditions of this Public License, which are limited to all Copyright and Similar Rights that apply to Your use of the Licensed Material and that the Licensor has authority to license.
32 |
33 | h. __Licensor__ means the individual(s) or entity(ies) granting rights under this Public License.
34 |
35 | i. __Share__ means to provide material to the public by any means or process that requires permission under the Licensed Rights, such as reproduction, public display, public performance, distribution, dissemination, communication, or importation, and to make material available to the public including in ways that members of the public may access the material from a place and at a time individually chosen by them.
36 |
37 | j. __Sui Generis Database Rights__ means rights other than copyright resulting from Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, as amended and/or succeeded, as well as other essentially equivalent rights anywhere in the world.
38 |
39 | k. __You__ means the individual or entity exercising the Licensed Rights under this Public License. Your has a corresponding meaning.
40 |
41 | ### Section 2 – Scope.
42 |
43 | a. ___License grant.___
44 |
45 | 1. Subject to the terms and conditions of this Public License, the Licensor hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive, irrevocable license to exercise the Licensed Rights in the Licensed Material to:
46 |
47 | A. reproduce and Share the Licensed Material, in whole or in part; and
48 |
49 | B. produce, reproduce, and Share Adapted Material.
50 |
51 | 2. __Exceptions and Limitations.__ For the avoidance of doubt, where Exceptions and Limitations apply to Your use, this Public License does not apply, and You do not need to comply with its terms and conditions.
52 |
53 | 3. __Term.__ The term of this Public License is specified in Section 6(a).
54 |
55 | 4. __Media and formats; technical modifications allowed.__ The Licensor authorizes You to exercise the Licensed Rights in all media and formats whether now known or hereafter created, and to make technical modifications necessary to do so. The Licensor waives and/or agrees not to assert any right or authority to forbid You from making technical modifications necessary to exercise the Licensed Rights, including technical modifications necessary to circumvent Effective Technological Measures. For purposes of this Public License, simply making modifications authorized by this Section 2(a)(4) never produces Adapted Material.
56 |
57 | 5. __Downstream recipients.__
58 |
59 | A. __Offer from the Licensor – Licensed Material.__ Every recipient of the Licensed Material automatically receives an offer from the Licensor to exercise the Licensed Rights under the terms and conditions of this Public License.
60 |
61 | B. __No downstream restrictions.__ You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, the Licensed Material if doing so restricts exercise of the Licensed Rights by any recipient of the Licensed Material.
62 |
63 | 6. __No endorsement.__ Nothing in this Public License constitutes or may be construed as permission to assert or imply that You are, or that Your use of the Licensed Material is, connected with, or sponsored, endorsed, or granted official status by, the Licensor or others designated to receive attribution as provided in Section 3(a)(1)(A)(i).
64 |
65 | b. ___Other rights.___
66 |
67 | 1. Moral rights, such as the right of integrity, are not licensed under this Public License, nor are publicity, privacy, and/or other similar personality rights; however, to the extent possible, the Licensor waives and/or agrees not to assert any such rights held by the Licensor to the limited extent necessary to allow You to exercise the Licensed Rights, but not otherwise.
68 |
69 | 2. Patent and trademark rights are not licensed under this Public License.
70 |
71 | 3. To the extent possible, the Licensor waives any right to collect royalties from You for the exercise of the Licensed Rights, whether directly or through a collecting society under any voluntary or waivable statutory or compulsory licensing scheme. In all other cases the Licensor expressly reserves any right to collect such royalties.
72 |
73 | ### Section 3 – License Conditions.
74 |
75 | Your exercise of the Licensed Rights is expressly made subject to the following conditions.
76 |
77 | a. ___Attribution.___
78 |
79 | 1. If You Share the Licensed Material (including in modified form), You must:
80 |
81 | A. retain the following if it is supplied by the Licensor with the Licensed Material:
82 |
83 | i. identification of the creator(s) of the Licensed Material and any others designated to receive attribution, in any reasonable manner requested by the Licensor (including by pseudonym if designated);
84 |
85 | ii. a copyright notice;
86 |
87 | iii. a notice that refers to this Public License;
88 |
89 | iv. a notice that refers to the disclaimer of warranties;
90 |
91 | v. a URI or hyperlink to the Licensed Material to the extent reasonably practicable;
92 |
93 | B. indicate if You modified the Licensed Material and retain an indication of any previous modifications; and
94 |
95 | C. indicate the Licensed Material is licensed under this Public License, and include the text of, or the URI or hyperlink to, this Public License.
96 |
97 | 2. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner based on the medium, means, and context in which You Share the Licensed Material. For example, it may be reasonable to satisfy the conditions by providing a URI or hyperlink to a resource that includes the required information.
98 |
99 | 3. If requested by the Licensor, You must remove any of the information required by Section 3(a)(1)(A) to the extent reasonably practicable.
100 |
101 | 4. If You Share Adapted Material You produce, the Adapter's License You apply must not prevent recipients of the Adapted Material from complying with this Public License.
102 |
103 | ### Section 4 – Sui Generis Database Rights.
104 |
105 | Where the Licensed Rights include Sui Generis Database Rights that apply to Your use of the Licensed Material:
106 |
107 | a. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, reuse, reproduce, and Share all or a substantial portion of the contents of the database;
108 |
109 | b. if You include all or a substantial portion of the database contents in a database in which You have Sui Generis Database Rights, then the database in which You have Sui Generis Database Rights (but not its individual contents) is Adapted Material; and
110 |
111 | c. You must comply with the conditions in Section 3(a) if You Share all or a substantial portion of the contents of the database.
112 |
113 | For the avoidance of doubt, this Section 4 supplements and does not replace Your obligations under this Public License where the Licensed Rights include other Copyright and Similar Rights.
114 |
115 | ### Section 5 – Disclaimer of Warranties and Limitation of Liability.
116 |
117 | a. __Unless otherwise separately undertaken by the Licensor, to the extent possible, the Licensor offers the Licensed Material as-is and as-available, and makes no representations or warranties of any kind concerning the Licensed Material, whether express, implied, statutory, or other. This includes, without limitation, warranties of title, merchantability, fitness for a particular purpose, non-infringement, absence of latent or other defects, accuracy, or the presence or absence of errors, whether or not known or discoverable. Where disclaimers of warranties are not allowed in full or in part, this disclaimer may not apply to You.__
118 |
119 | b. __To the extent possible, in no event will the Licensor be liable to You on any legal theory (including, without limitation, negligence) or otherwise for any direct, special, indirect, incidental, consequential, punitive, exemplary, or other losses, costs, expenses, or damages arising out of this Public License or use of the Licensed Material, even if the Licensor has been advised of the possibility of such losses, costs, expenses, or damages. Where a limitation of liability is not allowed in full or in part, this limitation may not apply to You.__
120 |
121 | c. The disclaimer of warranties and limitation of liability provided above shall be interpreted in a manner that, to the extent possible, most closely approximates an absolute disclaimer and waiver of all liability.
122 |
123 | ### Section 6 – Term and Termination.
124 |
125 | a. This Public License applies for the term of the Copyright and Similar Rights licensed here. However, if You fail to comply with this Public License, then Your rights under this Public License terminate automatically.
126 |
127 | b. Where Your right to use the Licensed Material has terminated under Section 6(a), it reinstates:
128 |
129 | 1. automatically as of the date the violation is cured, provided it is cured within 30 days of Your discovery of the violation; or
130 |
131 | 2. upon express reinstatement by the Licensor.
132 |
133 | For the avoidance of doubt, this Section 6(b) does not affect any right the Licensor may have to seek remedies for Your violations of this Public License.
134 |
135 | c. For the avoidance of doubt, the Licensor may also offer the Licensed Material under separate terms or conditions or stop distributing the Licensed Material at any time; however, doing so will not terminate this Public License.
136 |
137 | d. Sections 1, 5, 6, 7, and 8 survive termination of this Public License.
138 |
139 | ### Section 7 – Other Terms and Conditions.
140 |
141 | a. The Licensor shall not be bound by any additional or different terms or conditions communicated by You unless expressly agreed.
142 |
143 | b. Any arrangements, understandings, or agreements regarding the Licensed Material not stated herein are separate from and independent of the terms and conditions of this Public License.
144 |
145 | ### Section 8 – Interpretation.
146 |
147 | a. For the avoidance of doubt, this Public License does not, and shall not be interpreted to, reduce, limit, restrict, or impose conditions on any use of the Licensed Material that could lawfully be made without permission under this Public License.
148 |
149 | b. To the extent possible, if any provision of this Public License is deemed unenforceable, it shall be automatically reformed to the minimum extent necessary to make it enforceable. If the provision cannot be reformed, it shall be severed from this Public License without affecting the enforceability of the remaining terms and conditions.
150 |
151 | c. No term or condition of this Public License will be waived and no failure to comply consented to unless expressly agreed to by the Licensor.
152 |
153 | d. Nothing in this Public License constitutes or may be interpreted as a limitation upon, or waiver of, any privileges and immunities that apply to the Licensor or You, including from the legal processes of any jurisdiction or authority.
154 |
155 | > Creative Commons is not a party to its public licenses. Notwithstanding, Creative Commons may elect to apply one of its public licenses to material it publishes and in those instances will be considered the “Licensor.” Except for the limited purpose of indicating that material is shared under a Creative Commons public license or as otherwise permitted by the Creative Commons policies published at [creativecommons.org/policies](http://creativecommons.org/policies), Creative Commons does not authorize the use of the trademark “Creative Commons” or any other trademark or logo of Creative Commons without its prior written consent including, without limitation, in connection with any unauthorized modifications to any of its public licenses or any other arrangements, understandings, or agreements concerning use of licensed material. For the avoidance of doubt, this paragraph does not form part of the public licenses.
156 | >
157 | > Creative Commons may be contacted at creativecommons.org
158 |
--------------------------------------------------------------------------------
/NFTs.md:
--------------------------------------------------------------------------------
1 | # Critique of NFTs for prospective artists
2 |
3 | My mom teaches art history and her students (many of them graphic designers)
4 | have inquired about NFTs and whether they are a legitimate form of art. Both of
5 | us are skeptical about NFTs, but she's not as technical, so she reached out to
6 | me for help explaining them and resources that are informed critiques of NFTs.
7 | I in turn also
8 | [reached out to my Twitter network](https://twitter.com/GabriellaG439/status/1482432122350493702)
9 | to help me compile a list of resources for this purpose.
10 |
11 | This post will not explain NFTs *per se* but will instead be a survey that links
12 | to related resources critiquing NFTs and attempts to market them to artists and
13 | game designers.
14 |
15 | Also, feel free to submit a pull request editing or expanding upon this post.
16 | You can treat this like a collaborative wiki.
17 |
18 | ## Introductions to NFTs and their underlying technology
19 |
20 | * [The Third Web](https://tante.cc/2021/12/17/the-third-web/)
21 |
22 | > This text is intended for a general audience. For anyone that wants to know
23 | > what all the fuss is about and why they should care. Any artist who heard
24 | > that NFTs are the future or art and any gamer who heard the same about video
25 | > games. For anyone who got some lecture about how the future of the web would
26 | > be built on this new tech that feels hard to grasp. For anyone who’s being
27 | > bombarded with investment opportunities in NFTs that sound way too good to
28 | > be true.
29 |
30 | ## Other summaries and surveys
31 |
32 | * [/u/NoahDiesSlowly explains the problems with NFTs](https://www.reddit.com/r/OutOfTheLoop/comments/rho91b/whats_up_with_the_nft_hate/horr549/)
33 |
34 | `/u/Zombiehype` asked "What's up with the NFT hate?" on `/r/OutOfTheLoop` and
35 | `/u/NoahDiesSlowly` succinctly summarizes the most common criticisms of NFTs.
36 |
37 | * [The Problem With NFTs](https://www.youtube.com/watch?v=YQ_xWvX1n9g)
38 |
39 | This is a YouTube video explaining some of the basics behind NFTs and the
40 | problems associated with them.
41 |
42 | * [Why NFTs are bad: the long version](https://antsstyle.medium.com/why-nfts-are-bad-the-long-version-2c16dae145e2)
43 |
44 | > This long article explains technical and economic details to explain both
45 | > why NFTs are bad, why they don’t work (they don’t do what they claim to do),
46 | > and explains the hype surrounding them.
47 |
48 | ## Technical limitations of NFTs
49 |
50 | * [My first impressions of web3](https://moxie.org/2022/01/07/web3-first-impressions.html)
51 |
52 | This post criticizes the technical underpinnings behind NFTs and shows that
53 | the marketing behind them is detached from the technical reality.
54 |
55 | > All this means that if your NFT is removed from OpenSea, it also disappears
56 | > from your wallet. It doesn’t functionally matter that my NFT is indelibly on
57 | > the blockchain somewhere, because the wallet (and increasingly everything
58 | > else in the ecosystem) is just using the OpenSea API to display NFTs, which
59 | > began returning 304 No Content for the query of NFTs owned by my address!
60 |
61 | * [look what you made me do: a lot of people have asked me to make NFT games and I won’t because i’m not a fucking dumbass. now let me tell you why only a dumbass would get into NFT games.](https://docseuss.medium.com/look-what-you-made-me-do-a-lot-of-people-have-asked-me-to-make-nft-games-and-i-wont-because-i-m-29c7cfdbbb79)
62 |
63 | This article written by a game designer explains the fundamental issues with
64 | game industry proposals to adopt NFTs. Yes, that is the actual title.
65 |
66 | ## The NFT community does not respect or protect artists
67 |
68 | * [Content Creators Are Having Their Pictures And YouTube Channels Stolen And Sold As NFTs](https://www.thegamer.com/opensea-nft-stolen-art-pictures-youtubers-streamers/)
69 |
70 | This article explains how NFTs do not protect content creators. Quite the
71 | opposite: they commonly profit off of their content without their consent and
72 | disrespect them along the way:
73 |
74 | > YouTubers Jim Sterling and Caddicarus are among the first to notice their
75 | > channels being sold online, in a move that they're labelling "pathetic",
76 | > "disrespectful" and "exploitative". Sony Santa Monica Studios' Alanah
77 | > Pearce has also had her pictures stolen and sold on the site, with the
78 | > sellers going a step further than theft, and photoshopping the game dev onto
79 | > a porn magazine cover.
80 |
81 | *
82 |
83 | *
84 |
85 | ## NFT-related fraud
86 |
87 | * [Web3 is going just great](https://web3isgoinggreat.com/)
88 |
89 | This site catalogs rampant fraud within the NFT ecosystem.
90 |
91 | * [NFTs Are a Pyramid Scheme and People Are Already Losing Money](https://fstoppers.com/opinion/nfts-are-pyramid-scheme-and-people-are-already-losing-money-554869)
92 |
93 | > On the surface, the NFT marketplace is made to look like everyone is making
94 | > money, and while crypto might be rewriting the rules of economics, there is
95 | > one dictum it cannot escape: for someone to make money, another has to lose
96 | > money. NFTs do not magically generate wealth from nowhere; they’re taking it
97 | > from those buying into the idea that everyone who’s getting in early is
98 | > making a killing. As David Gerard, author of Attack of the 50 Foot
99 | > Blockchain explains, “NFTs are entirely for the benefit of the crypto
100 | > grifters. The only purpose the artists serve is as aspiring suckers to pump
101 | > the concept of crypto — and, of course, to buy cryptocurrency to pay for
102 | > ‘minting’ NFTs.”
103 |
104 | * [NFT “Sells” for Over $500 Million Back to Original Owner in Apparent “WASH,” Potentially Heightening Securities Concerns in This Emerging Market](https://www.winston.com/en/the-playbook/nft-sells-for-over-500-million-back-to-original-owner-in-apparent-wash-potentially-heightening-securities-concerns-in-this-emerging-market.html)
105 |
106 | This documents an example of "wash trading", a common form of NFT fraud where
107 | people buy their NFT from themselves to inflate the perceived value. Wash
108 | trading is illegal, by the way.
109 |
110 | > On October 28, 2021, a bot that tracks sales of CryptoPunks, a set of NFT
111 | > avatars traded via the Ethereum cryptocurrency, reported that CryptoPunk
112 | > 9998, an 8-bit figure with shaggy white hair, had sold for
113 | > $532,414,877.01. As expected, the buyer, who used “flash loans” to acquire
114 | > the funds to purchase the NFT, sent the Ethereum to the seller, who in turn
115 | > sent the NFT memorializing the ownership of CryptoPunk 9998 to the buyer.
116 | > However, as part of the same transaction, the seller then sent the Ethereum
117 | > back to the buyer, who repaid his loans. Finally, the “Punk” was sent back
118 | > to the original owner, who quickly listed it for sale again at nearly double
119 | > the original price, 250,000 Ethereum (over $1 billion).
120 |
121 | *
122 |
123 | ## NFTs are not art
124 |
125 | * [The NFT's Aura, or, Why Is NFT Art So Ugly?](https://www.stormingtheivorytower.com/2021/06/the-nfts-aura-or-why-is-nft-art-so-ugly.html)
126 |
127 | This post explains why NFT art tends to be ugly and devoid of artistic
128 | merit:
129 |
130 | > It's actually very difficult to talk about NFT art as art because most of
131 | > it is so god damn ugly, vapid, and amateurish. NFT art is like, imagine if
132 | > you took a bunch of dudes in a high school art fair, then put them in an
133 | > echo chamber for a decade that constantly told them that everything they
134 | > did was Epic Bacon, and then finally started handing them million dollar
135 | > checks for that artwork. Does this sound like an environment where artists
136 | > would develop self awareness, or intellectual depth, or aesthetic
137 | > uniqueness, or any of the other stuff that a critic might be interested
138 | > in?
139 |
140 | ## NFTs are harmful to the environment
141 |
142 | * [HERE IS THE ARTICLE YOU CAN SEND TO PEOPLE WHEN THEY SAY “BUT THE ENVIRONMENTAL ISSUES WITH CRYPTOART WILL BE SOLVED SOON, RIGHT?”](https://everestpipkin.medium.com/but-the-environmental-issues-with-cryptoart-1128ef72e6a3)
143 |
144 | This article explains why NFTs are harmful for the environment. Yes, that is
145 | the actual title.
146 |
147 | ## NFTs are a net social negative
148 |
149 | * [Brian Eno on NFTs & Automaticism](https://the-crypto-syllabus.com/brian-eno-on-nfts-and-automatism/)
150 |
151 | This is an interview of an artist explaining his misgivings about NFTs and
152 | their benefit to society:
153 |
154 | > I am trying to keep an open mind about these questions. People I like and
155 | > trust are convinced they’re the best thing since sliced bread, so I wish I
156 | > could have a more positive view but right now I mainly see hustlers
157 | > looking for suckers. And lots of bright-eyed artists willing to play the
158 | > latter role. Forgive my cynicism… I’m not feeling too positive right now.
159 |
160 | ## Process/performance art about NFTs
161 |
162 | Artists curious about NFTs might appreciate process art or performance art
163 | critiquing NFTs:
164 |
165 | * [The NFT Bay asks if you would steal all the JPEGs](https://www.theverge.com/2021/11/18/22790131/nft-bay-pirating-digital-ownership-piracy-crypto-art-right-click)
166 |
167 | This is an article about someone orchestrating the greatest NFT "heist" of
168 | all time, downloading all of available NFTs and making them available via a
169 | torrent.
170 |
171 | * [This Powerful Right-Click Artwork Is Made of 10,000 NFTs](https://www.vice.com/en/article/3abnwv/this-powerful-right-click-artwork-is-made-of-10000-nfts)
172 |
173 | This article describes a mosaic depicting a person right-clicking to save an
174 | image, where the mosaic is created from NFT images.
175 |
--------------------------------------------------------------------------------
/sotu.md:
--------------------------------------------------------------------------------
1 |
2 | # State of the Haskell ecosystem
3 |
4 | In this post I will describe the current state of the Haskell ecosystem to the
5 | best of my knowledge and its suitability for various programming domains and
6 | tasks. The purpose of this post is to discuss both the good and the bad by
7 | advertising where Haskell shines while highlighting where I believe there is
8 | room for improvement.
9 |
10 | This post is grouped into two sections: the first section covers Haskell's
11 | suitability for particular programming application domains (i.e. servers,
12 | games, or data science) and the second section covers Haskell's suitability
13 | for common general-purpose programming needs (such as testing, IDEs, or
14 | concurrency).
15 |
16 | The topics are roughly sorted from greatest strengths to greatest weaknesses.
17 | Each programming area will also be summarized by a single rating of either:
18 |
19 | * **Best in class**: the best experience in any language
20 | * **Mature**: suitable for most programmers
21 | * **Immature**: only acceptable for early-adopters
22 | * **Bad**: pretty unusable
23 |
24 | The more positive the rating the more I will support the rating with
25 | success stories in the wild. The more negative the rating the more I will
26 | offer constructive advice for how to improve things.
27 |
28 | **Disclaimer #1:** I obviously don't know everything about the Haskell
29 | ecosystem, so whenever I am unsure I will make a ballpark guess and clearly
30 | state my uncertainty in order to solicit opinions from others who have more
31 | experience. I keep tabs on the Haskell ecosystem pretty well, but even this
32 | post is stretching my knowledge. If you believe any of my ratings are
33 | incorrect, I am more than happy to accept corrections (both upwards and
34 | downwards)
35 |
36 | **Disclaimer #2:** There are some "Educational resource" sections below which
37 | are remarkably devoid of books, since I am not as familiar with
38 | textbook-related resources. If you have suggestions for textbooks to add,
39 | please let me know.
40 |
41 | **Disclaimer #3:** I am very obviously a Haskell fanboy if you haven't guessed
42 | from the name of my blog and I am also an author of several libraries mentioned
43 | below, so I'm highly biased. I've made a sincere effort to honestly appraise
44 | the language, but please challenge my ratings if you believe that my bias is
45 | blinding me! I've also clearly marked Haskell sales pitches as "Propaganda"
46 | in my external link sections. :)
47 |
48 | **Disclaimer #4:** I've contributed the majority of these recommendations and I
49 | also play an editorial role. This means that although some contributions have been
50 | crowd-sourced I reserve the right to decline a pull request or edit/delete content
51 | if I feel that a resource is abandoned or if I feel there are better alternatives
52 | already listed. I try to be as fair as possible and if you disagree with any
53 | decision of mine or you feel that my recommendation does not reflect the consensus
54 | of the Haskell community you can challenge my decision by opening an issue and I will
55 | either defend my decision or change my mind.
56 |
57 | ## Table of Contents
58 |
59 | Legend:
60 |
61 | 🏆 = Best in class
62 |
63 | 🥈 = Mature
64 |
65 | 🌱 = Immature
66 |
67 | ⛔ = Bad
68 |
69 | * [Application Domains](#application-domains)
70 | * 🏆 [Compilers](#compilers)
71 | * 🥈 [Server-side web programming](#server-side-web-programming)
72 | * 🥈 [Scripting / Command-line applications](#scripting--command-line-applications)
73 | * 🌱 [Data science](#data-science)
74 | * 🌱 [Numerical programming](#numerical-programming)
75 | * 🌱 [Front-end web programming](#front-end-web-programming)
76 | * 🌱 [Distributed programming](#distributed-programming)
77 | * 🌱 [Standalone GUI applications](#standalone-gui-applications)
78 | * 🌱 [Machine learning](#machine-learning)
79 | * 🌱 [Game programming](#game-programming)
80 | * 🌱 [ARM processor support](#arm-processor-support)
81 | * 🌱 [Computer Vision](#computer-vision)
82 | * 🌱 [Mobile apps](#mobile-apps)
83 | * 🌱/⛔ [Systems / embedded programming](#systems--embedded-programming)
84 | * [Common Programming Needs](#common-programming-needs)
85 | * 🏆 [Maintenance](#maintenance)
86 | * 🏆 [Single-machine Concurrency](#single-machine-concurrency)
87 | * 🏆 [Types / Type-driven development](#types--type-driven-development)
88 | * 🏆 [Parsing / Pretty-printing](#parsing--pretty-printing)
89 | * 🥈 [Domain-specific languages (DSLs)](#domain-specific-languages-dsls)
90 | * 🥈 [Testing](#testing)
91 | * 🥈 [Data structures and algorithms](#data-structures-and-algorithms)
92 | * 🥈 [Benchmarking](#benchmarking)
93 | * 🥈 [Unicode](#unicode)
94 | * 🥈 [Stream programming](#stream-programming)
95 | * 🥈 [Serialization / Deserialization](#serialization--deserialization)
96 | * 🥈 [Support for file formats](#support-for-file-formats)
97 | * 🥈 [Package management](#package-management)
98 | * 🥈 [Logging](#logging)
99 | * 🥈 [Code formatting](#code-formatting)
100 | * 🥈 [Education](#education)
101 | * 🌱 [Databases and data stores](#databases-and-data-stores)
102 | * 🌱 [Debugging](#debugging)
103 | * 🌱 [Cross-platform support](#cross-platform-support)
104 | * 🌱 [Hot code loading](#hot-code-loading)
105 | * 🌱 [IDE support](#ide-support)
106 |
107 | # Application Domains
108 |
109 | ## Compilers
110 |
111 | **Rating:** Best in class
112 |
113 | Haskell is an amazing language for writing your own compiler. If you are
114 | writing a compiler in another language you should genuinely consider switching.
115 |
116 | Haskell originated in academia, and most languages of academic origin (such as
117 | the ML family of languages) excel at compiler-related tasks for obvious
118 | reasons. As a result the language has a rich ecosystem of libraries dedicated
119 | to compiler-related tasks, such as parsing, pretty-printing, unification,
120 | bound variables, syntax tree manipulations, and optimization.
121 |
122 | Anybody who has ever written a compiler knows how difficult they are to
123 | implement because by necessity they manipulate very weakly typed data
124 | structures (trees and maps of strings and integers). Consequently, there is a
125 | huge margin for error in everything a compiler does, from type-checking to
126 | optimization, to code generation. Haskell knocks this out of the park, though,
127 | with a really powerful type system with many extensions that can eliminate
128 | large classes of errors at compile time.
129 |
130 | I also believe that there are many excellent educational resources for compiler
131 | writers, both papers and books. I'm not the best person to summarize all the
132 | educational resources available, but the ones that I have read have been very
133 | high quality.
134 |
135 | Finally, there are a large number of parsers and pretty-printers for other
136 | languages which you can use to write compilers to or from these languages.
137 |
138 | **Notable libraries:**
139 |
140 | * [`parsec`](https://hackage.haskell.org/package/parsec) / [`megaparsec`](https://hackage.haskell.org/package/megaparsec) / [`attoparsec`](https://hackage.haskell.org/package/attoparsec) / [`trifecta`](https://hackage.haskell.org/package/trifecta) / [`alex`](https://hackage.haskell.org/package/alex)+[`happy`](https://hackage.haskell.org/package/happy) - parsing libraries
141 | * [`bound`](https://hackage.haskell.org/package/bound) / [`unbound`](https://hackage.haskell.org/package/unbound) - manipulating bound variables
142 | * [`hoopl`](https://hackage.haskell.org/package/hoopl) - optimization
143 | * [`uuagc`](https://hackage.haskell.org/package/uuagc) - attribute grammars
144 | * [`unification-fd`](https://hackage.haskell.org/package/unification-fd) - fast structural unification
145 | * [`prettyprinter`](https://hackage.haskell.org/package/prettyprinter) - pretty-printing
146 | * [`llvm-general`](https://hackage.haskell.org/package/llvm-general) - LLVM 3.5 API
147 | * [`llvm-hs`](https://hackage.haskell.org/package/llvm-hs) - LLVM 5 API (actively maintained fork of llvm-general)
148 | * `language-`{[`ecmascript`](https://hackage.haskell.org/package/language-ecmascript)|[`python`](https://hackage.haskell.org/package/language-python)|[`c-quote`](https://hackage.haskell.org/package/language-c-quote)|[`lua`](https://hackage.haskell.org/package/language-lua)|[`java`](https://hackage.haskell.org/package/language-java)|[`objc`](https://hackage.haskell.org/package/language-objc)|[`cil`](https://hackage.haskell.org/package/language-cil)} - parsers and
149 | pretty-printers for other languages
150 |
151 | **Some compilers written in Haskell:**
152 |
153 | * [`Elm`](http://elm-lang.org)
154 | * [`Purescript`](http://www.purescript.org)
155 | * [`Idris`](http://www.idris-lang.org)
156 | * [`Agda`](http://wiki.portal.chalmers.se/agda/pmwiki.php)
157 | * [`Pugs`](http://www.perlfoundation.org/perl6/index.cgi?pugs) (the first Perl 6 implementation)
158 | * [`ghc`](https://www.haskell.org/ghc/) (self-hosting)
159 | * [`frege`](https://github.com/Frege/frege) (very similar to Haskell, also self-hosting)
160 | * [`hython`](https://github.com/mattgreen/hython) (a Python3 interpreter written in Haskell)
161 | * [`Lasca`](http://lasca-lang.org) (a small Scala-like language with global type inference and optional dynamic mode on LLVM backend)
162 | * [`verve`](https://github.com/tadeuzagallo/verve-lang) - Functional language with object-oriented support
163 | * [`sixten`](https://github.com/ollef/sixten) - Haskell/Idris-style language with a focus on precise and efficient memory layout
164 | * [`carp`](https://github.com/carp-lang/Carp) - An efficient, statically typed Lisp with ownership tracking.
165 | * [`unison`](https://github.com/unisonweb/unison) - A purely functional distributed programming language with algebraic effects.
166 | * [`oden`](https://github.com/oden-lang/oden) (no longer in active development)
167 |
168 | **Educational resources:**
169 |
170 | * [Write you a Haskell](http://dev.stephendiehl.com/fun/)
171 | * [A Tutorial Implementation of a Dependently Typed Lambda Calculus](http://www.andres-loeh.de/LambdaPi/)
172 | * [Binders Unbound](http://ozark.hendrix.edu/~yorgey/pub/unbound.pdf)
173 |
174 | **Propaganda:**
175 |
176 | * [Oden restrospective on rewrite from Racket to Haskell](https://github.com/oden-lang/oden-lang.github.io/blob/master/blog/_posts/2016-01-17-the-haskell-rewrite.md)
177 |
178 |
179 | ## Server-side web programming
180 |
181 | **Rating:** Mature
182 |
183 | Haskell's second biggest strength is the back-end, both for web applications
184 | and services. The main features that the language brings to the table are:
185 |
186 | * Server stability
187 | * Performance
188 | * Ease of concurrent programming
189 | * Excellent support for web standards
190 |
191 | The strong type system and polished runtime greatly improve server stability
192 | and simplify maintenance. This is the greatest differentiator of Haskell from
193 | other backend languages, because it significantly reduces the
194 | total-cost-of-ownership. You should expect that you can maintain Haskell-based
195 | services with significantly fewer programmers than other languages, even when
196 | compared to other statically typed languages.
197 |
198 | However, the greatest weakness of server stability is space leaks. The most
199 | common solution that I know of is to use `ekg` (a process monitor) to examine
200 | a server's memory stability before deploying to production. The second most
201 | common solution is to learn to detect and prevent space leaks with experience,
202 | which is not as hard as people think.
203 |
204 | Haskell's performance is excellent and currently comparable to Java. Both
205 | languages give roughly the same performance in beginner or expert hands,
206 | although for different reasons.
207 |
208 | Where Haskell shines in usability is the runtime support for the following
209 | three features:
210 |
211 | * software transactional memory (which differentiates Haskell from Go)
212 | * lightweight threads that use non-blocking I/O (which differentiates Haskell from the JVM)
213 | * garbage collection (which differentiates Haskell from Rust)
214 |
215 | If you have never tried out Haskell's software transactional memory you should
216 | really, really, really give it a try, since it eliminates a large number of
217 | concurrency logic bugs. STM is far and away the most underestimated feature
218 | of the Haskell runtime.
219 |
220 | **Notable libraries:**
221 |
222 | * [`warp`](https://hackage.haskell.org/package/warp) / [`wai`](https://hackage.haskell.org/package/wai) - the low-level server and API that all server libraries share, with the exception of `snap`
223 | * [`scotty`](https://hackage.haskell.org/package/scotty) - A beginner-friendly server framework analogous to Ruby's Sinatra
224 | * [`spock`](https://www.spock.li/) - Lighter than the "enterprise" frameworks, but more featureful than scotty (type-safe routing, sessions, conn pooling, csrf protection, authentication, etc)
225 | * [`yesod`](https://hackage.haskell.org/package/yesod) / [`yesod-*`](https://hackage.haskell.org/packages/search?terms=yesod) / [`snap`](https://hackage.haskell.org/package/snap) / [`snap-*`](https://hackage.haskell.org/packages/search?terms=snap) / [`happstack-server`](https://hackage.haskell.org/package/happstack-server) / [`happstack-*`](https://hackage.haskell.org/packages/search?terms=happstack) - "Enterprise" server frameworks with all the bells and whistles
226 | * [`ihp`](https://ihp.digitallyinduced.com/) - batteries-included web framework with a friendly and helpful community. The best choice when getting started with haskell.
227 | * [`servant`](https://hackage.haskell.org/package/servant) / [`servant-*`](https://hackage.haskell.org/packages/search?terms=servant) - Library for type-safe REST servers and clients that might blow your mind
228 | * [`graphql-api`](http://hackage.haskell.org/package/graphql-api) - Implement a GraphQL API
229 | * [`websockets`](https://hackage.haskell.org/package/websockets) - Standalone websockets client and server
230 | * [`authenticate`](https://hackage.haskell.org/package/authenticate) / [`authenticate-*`](https://hackage.haskell.org/packages/search?terms=authenticate) - Shared authentication libraries
231 | * [`ekg`](https://hackage.haskell.org/package/ekg) / [`ekg-*`](https://hackage.haskell.org/packages/search?terms=ekg) - Haskell service monitoring
232 | * [`stm`](https://hackage.haskell.org/package/stm) - Software-transactional memory
233 | * [`lucid`](https://hackage.haskell.org/package/lucid) - Haskell DSL for
234 | building HTML
235 | * [`mustache`](https://hackage.haskell.org/package/mustache) / [`karver`](https://hackage.haskell.org/package/karver) - Templating libraries
236 | * [`aeson`](https://hackage.haskell.org/package/aeson) - Parsing and generation of JSON
237 |
238 | **Some web sites,services, and projects powered by Haskell:**
239 |
240 | * Facebook's spam filter: Sigma
241 | * IMVU's REST API
242 | * Utrecht's bicycle parking guidance system
243 | * [elm-lang.org](http://elm-lang.org/)
244 | * [glot.io](http://glot.io/)
245 | * [The Perry Bible Fellowship](http://pbfcomics.com/)
246 | * [Silk](https://www.silk.co)
247 | * [Shellcheck](http://www.shellcheck.net/)
248 | * [instantwatcher.com](http://instantwatcher.com/)
249 | * [markup.rocks](http://markup.rocks/)
250 | * [ZoomHub](http://zoomhub.net/) ([Code](https://github.com/zoomhub/zoomhub))
251 | * [PostgREST](https://postgrest.com/en/v4.3/) - Generates a REST API for a
252 | Postgres database
253 | * [Hasura](https://github.com/hasura/graphql-engine)
254 | * [Mercury](https://mercury.com/)
255 |
256 | **Propaganda:**
257 |
258 | * [Fighting spam with Haskell - Haskell in production, at scale, at Facebook](https://code.facebook.com/posts/745068642270222/fighting-spam-with-haskell/)
259 | * [IMVU Engineering - What it's like to use Haskell](http://engineering.imvu.com/2014/03/24/what-its-like-to-use-haskell/)
260 | * [Haskell-based Bicycle Parking Guidance System in Utrecht](https://www.reddit.com/r/haskell/comments/3959r0/haskellbased_bicycle_parking_guidance_system_in/)
261 | * [Mio: A High-Performance Multicore IO Manager for GHC](http://haskell.cs.yale.edu/wp-content/uploads/2013/08/hask035-voellmy.pdf)
262 | * [The Performance of Open Source Applications - Warp](http://www.aosabook.org/en/posa/warp.html)
263 | * [Optimising Garbage Collection Overhead in Sigma](https://simonmar.github.io/posts/2015-07-28-optimising-garbage-collection-overhead-in-sigma.html)
264 | * instantwatcher.com author comments on rewrite from Ruby to Haskell - [\[1\]](http://www.reddit.com/r/haskell/comments/3am3qu/should_i_put_a_powered_by_haskell_tag_w_haskell/csef8eq)
265 | [\[2\]](http://www.reddit.com/r/haskell/comments/3e10ea/til_instantwatcher_is_made_with_haskell/ctavz2m)
266 | * [A lot of websockets in Haskell](https://blog.wearewizards.io/a-lot-of-websockets-in-haskell) - A load test showing that a Haskell server can handle 500K connections in 10 GB of memory. The load tester requires more resources than the server
267 |
268 | **Educational resources:**
269 |
270 | * [Making a Website With Haskell](http://adit.io/posts/2013-04-15-making-a-website-with-haskell.html)
271 | * [Beautiful concurrency](https://www.schoolofhaskell.com/school/advanced-haskell/beautiful-concurrency) - a software-transactional memory tutorial
272 | * [The Yesod book](http://www.yesodweb.com/book)
273 | * [The Servant tutorial](https://haskell-servant.readthedocs.io/en/stable/tutorial/index.html)
274 | * [Overview of Happstack](http://www.happstack.com)
275 | * [IHP Guide](https://ihp.digitallyinduced.com/Guide/index.html)
276 | * [IHP Casts](https://ihpcasts.com/)
277 |
278 | **Notable hosting platforms:**
279 | * [IHP Cloud](https://ihpcloud.com/)
280 |
281 |
282 |
283 | ## Scripting / Command-line applications
284 |
285 | **Rating:** Mature
286 |
287 | Haskell's biggest advantage as a scripting language is that Haskell is the
288 | most widely adopted language that supports global type inference. Many
289 | languages support local type inference (such as Rust, Go, Java, C#), which
290 | means that function argument types and interfaces must be declared but
291 | everything else can be inferred. In Haskell, you can omit everything: all
292 | types and interfaces are completely inferred by the compiler (with some
293 | caveats, but they are minor).
294 |
295 | Global type inference gives Haskell the feel of a scripting language while
296 | still providing static assurances of safety. Script type safety matters in
297 | particular for enterprise environments where glue scripts running with elevated
298 | privileges are one of the weakest points in these software architectures.
299 |
300 | The second benefit of Haskell's type safety is ease of script maintenance.
301 | Many scripts grow out of control as they accrete arcane requirements and once
302 | they begin to exceed 1000 LOC they become difficult to maintain in a
303 | dynamically typed language. People rarely budget sufficient time to create a
304 | sufficiently extensive test suite that exercises every code path for each and
305 | every one of their scripts. Having a strong type system is like getting a
306 | large number of auto-generated tests for free that exercise all script code
307 | paths. Moreover, the type system is more resilient to refactoring than a test
308 | suite.
309 |
310 | However, the main reason I mark Haskell as mature because the language is also
311 | usable even for simple one-off disposable scripts. These Haskell scripts are
312 | comparable in size and simplicity to their equivalent Bash or Python scripts.
313 | This lets you easily start small and finish big.
314 |
315 | Haskell has one advantage over many dynamic scripting languages, which is that
316 | Haskell can be compiled into a native and statically linked binary for
317 | distribution to others.
318 |
319 | Haskell's scripting libraries are feature complete and provide all the
320 | niceties that you would expect from scripting in Python or Ruby, including
321 | features such as:
322 |
323 | * rich suite of Unix-like utilities
324 | * advanced sub-process management
325 | * POSIX support
326 | * light-weight idioms for exception safety and automatic resource disposal
327 |
328 | **Notable libraries:**
329 |
330 | * [`shelly`](https://hackage.haskell.org/package/shelly) / [`turtle`](https://hackage.haskell.org/package/turtle) / [`shellmet`](http://hackage.haskell.org/package/shellmet) - scripting libraries (Full disclosure: I authored `turtle`)
331 | * [`optparse-applicative`](https://hackage.haskell.org/package/optparse-applicative) / [`cmdargs`](https://hackage.haskell.org/package/cmdargs) - command-line argument parsing
332 | * [`haskeline`](https://hackage.haskell.org/package/haskeline) - a complete Haskell implementation of `readline` for console
333 | building
334 | * [`process`](https://hackage.haskell.org/package/process) - low-level library for sub-process management
335 | * [`ansi-terminal`](https://hackage.haskell.org/package/ansi-terminal) - de facto standard cross-platform terminal library (works on Windows as well)
336 | * [`brick`](http://hackage.haskell.org/package/brick) - terminal user interfaces (TUIs)
337 | * [`path`](https://hackage.haskell.org/package/path) / [`path-io`](https://hackage.haskell.org/package/path-io) - type safe handling of file paths
338 | * [`http-client`](http://hackage.haskell.org/package/http-client) / [`http-client-*`](https://hackage.haskell.org/packages/search?terms=http-client) / [`req`](http://hackage.haskell.org/package/req) / [`req-*`](https://hackage.haskell.org/packages/search?terms=req) / [`wreq`](http://hackage.haskell.org/package/wreq) - HTTP clients
339 |
340 | **Some command-line tools written in Haskell:**
341 |
342 | * [`pandoc`](https://hackage.haskell.org/package/pandoc)
343 | * [`git-annex`](https://hackage.haskell.org/package/git-annex)
344 | * [`hledger`](http://hledger.org/)
345 |
346 | **Educational resources:**
347 |
348 | * [Shelly: Write your shell scripts in Haskell](http://www.yesodweb.com/blog/2012/03/shelly-for-shell-scripts)
349 | * [Use Haskell for shell scripting](http://www.haskellforall.com/2015/01/use-haskell-for-shell-scripting.html)
350 |
351 |
352 |
353 | ## Data science
354 |
355 | **Rating:** Immature
356 |
357 | Haskell data science can take advantage of other data science ecosystems via the
358 | [`HaskellR`](http://tweag.github.io/HaskellR/) and
359 | [`Sparkle`](https://github.com/tweag/sparkle) projects. `HaskellR` is a
360 | Haskell-to-R bridge with Jupyter notebook integration, which lets you take
361 | advantage of the broad R ecosystem while benefiting from the speed and type
362 | safety of Haskell. `Sparkle` is a Haskell-to-Spark bridge which lets you
363 | interface with the Spark subset of the Java/Scala data science ecosystem.
364 | However, to get a Mature rating Haskell data science needs to be able to
365 | stand alone without depending on other programming language ecosystems.
366 |
367 | If you restrict yourself to just the Haskell ecosystem then choices are more
368 | limited. I'll primarily compare Haskell to Python since that's the data science
369 | ecosystem that I'm more familiar with. Specifically, I'll compare to the
370 | `scipy` suite of libraries:
371 |
372 | The Haskell analog of `NumPy` is the `hmatrix` library, which provides Haskell
373 | bindings to BLAS, LAPACK. `hmatrix`'s main limitation is that the API is a bit
374 | clunky, but all the tools are there.
375 |
376 | Haskell's charting story is okay. Probably my main criticism of most charting
377 | APIs is that their APIs tend to be large, the types are a bit complex, and they
378 | have a very large number of dependencies.
379 |
380 | Fortunately, Haskell does integrate into IPython so you can use Haskell within
381 | an IPython shell or an online notebook. For example, there is an online
382 | "IHaskell" notebook that you can use right now located here:
383 |
384 | * [IHaskell notebook](https://try.jupyter.org/) - Click on "Welcome to Haskell.ipynb"
385 |
386 | If you want to learn more about how to setup your own IHaskell notebook, visit
387 | this project:
388 |
389 | * [IHaskell Github repository](https://github.com/gibiansky/IHaskell)
390 |
391 | The closest thing to Python's `pandas` is the `frames` library. I haven't used
392 | it that much personally so I won't comment on it much other than to link to
393 | some tutorials in the Educational Resources section.
394 |
395 | I'm not aware of a Haskell analog to `SciPy` (the library) or `sympy`. If
396 | you know of an equivalent Haskell library then let me know.
397 |
398 | One Haskell library that deserves honorable mention here is the `diagrams`
399 | library which lets you produce complex data visualizations very easily if
400 | you want something a little bit fancier than a chart. Check out the `diagrams`
401 | project if you have time:
402 |
403 | * [The Diagrams project](http://projects.haskell.org/diagrams/)
404 | * [Gallery of example diagrams](http://projects.haskell.org/diagrams/gallery.html)
405 |
406 | **Areas for improvement:**
407 |
408 | * Smooth user experience and integration across all of these libraries
409 | * Simple types and APIs. The data science programmers I know dislike overly
410 | complex or verbose APIs
411 | * Beautiful data visualizations with very little investment
412 |
413 | **Notable libraries:**
414 |
415 | * [`HaskellR`](http://tweag.github.io/HaskellR/) - Mix Haskell and R code in Jupyter notebooks
416 | * [`Sparkle`](https://github.com/tweag/sparkle) - Haskell-to-Spark bridge
417 | * [`cassava`](https://hackage.haskell.org/package/cassava) - CSV encoding and decoding
418 | * [`hmatrix`](https://hackage.haskell.org/package/hmatrix) - BLAS / LAPACK wrapper
419 | * [`Frames`](https://hackage.haskell.org/package/Frames) - Haskell data analysis tool analogous to Python's `pandas`
420 | * [`statistics`](https://hackage.haskell.org/package/statistics) - Statistics (duh!)
421 | * [`Chart`](https://hackage.haskell.org/package/Chart) / [`Chart-*`](https://hackage.haskell.org/packages/search?terms=Chart) - Charting library
422 | * [`diagrams`](https://hackage.haskell.org/package/diagrams) / [`diagrams-*`](https://hackage.haskell.org/packages/search?terms=diagrams) - Vector graphics library
423 | * [`ihaskell`](https://hackage.haskell.org/package/ihaskell) - Haskell backend to IPython
424 |
425 |
426 |
427 | ## Numerical programming
428 |
429 | **Rating:** Immature
430 |
431 | Haskell's numerical programming story is not ready, but steadily improving.
432 |
433 | My main experience in this area was from a few years ago doing numerical
434 | programming for bioinformatics that involved a lot of vector and matrix
435 | manipulation and my rating is largely colored by that experience.
436 |
437 | The biggest issues that the ecosystem faces are:
438 |
439 | * Really clunky matrix library APIs
440 | * Fickle rewrite-rule-based optimizations
441 |
442 | When the optimizations work they are amazing and produce code competitive with
443 | C. However, small changes to your code can cause the optimizations to
444 | suddenly not trigger and then performance drops off a cliff.
445 |
446 | There is one Haskell library that avoids this problem entirely which I believe
447 | holds a lot of promise: `accelerate` generates LLVM and CUDA code at runtime
448 | and does not rely on Haskell's optimizer for code generation, which side-steps
449 | the problem. `accelerate` has a large set of supported algorithms that you
450 | can find by just checking the library's reverse dependencies:
451 |
452 | * [Reverse dependencies of `accelerate`](http://packdeps.haskellers.com/reverse/accelerate)
453 |
454 | However, I don't have enough experience with `accelerate` or enough familiarity
455 | with numerical programming success stories in Haskell to vouch for this just
456 | yet. If somebody has more experience than me in this regard and can provide
457 | evidence that the ecosystem is mature then I might consider revising my rating
458 | upward.
459 |
460 | **Notable libraries:**
461 |
462 | * [`accelerate`](https://hackage.haskell.org/package/accelerate) / [`accelerate-*`](https://hackage.haskell.org/packages/search?terms=accelerate) - GPU programming
463 | * [`vector`](https://hackage.haskell.org/package/vector) - high-performance arrays
464 | * [`massiv`](https://hackage.haskell.org/package/massiv) / [`repa`](https://hackage.haskell.org/package/repa) / [`repa-*`](https://hackage.haskell.org/packages/search?terms=repa) - parallel shape-polymorphic arrays
465 | * [`hmatrix`](https://hackage.haskell.org/package/hmatrix) / [`hmatrix-*`](https://hackage.haskell.org/packages/search?terms=hmatrix) - Haskell's BLAS / LAPACK wrapper
466 | * [`ad`](https://hackage.haskell.org/package/ad) - automatic differentiation
467 |
468 | **Propaganda:**
469 |
470 | * [Exploiting vector instructions with generalized stream fusion](http://research.microsoft.com/en-us/um/people/simonpj/papers/ndp/haskell-beats-C.pdf)
471 | * [Type-safe Runtime Code Generation: Accelerate to LLVM](https://github.com/tmcdonell/tmcdonell.github.io/raw/master/papers/acc-llvm-haskell2015.pdf)
472 |
473 | **Educational Resources:**
474 |
475 | * [Parallel and concurrent programming in Haskell](http://chimera.labs.oreilly.com/books/1230000000929/index.html)
476 |
477 |
478 |
479 | ## Front-end web programming
480 |
481 | **Rating:** Immature
482 |
483 | This boils down to Haskell's ability to compile to JavaScript. `ghcjs` is the
484 | front-runner, but for a while setting up `ghcjs` was non-trivial. Now that
485 | the `stack` build tool supports `ghcjs` you can very easily set up a new `ghcjs`
486 | project by following these instructions:
487 |
488 | * [Stack + GHCJS support](http://docs.haskellstack.org/en/stable/ghcjs/)
489 |
490 | One of the distinctive features of `ghcjs` compared to other competing
491 | Haskell-to-JavaScript compilers is that a huge number of Haskell libraries work
492 | out of the box with `ghcjs` because it supports most of `ghc`'s primitive
493 | operations.
494 |
495 | I would also like to mention that there are two Haskell-like languages that
496 | you should also try out for front-end programming: `elm` and `purescript`.
497 | These are both used in production today and have equally active maintainers and
498 | communities of their own. `purescript` in particular is extremely similar to
499 | Haskell.
500 |
501 | **Areas for improvement:**
502 |
503 | * There needs to be a clear story for smooth integration with existing
504 | JavaScript projects
505 | * There need to be many more educational resources targeted at non-experts
506 | explaining how to translate existing front-end programming idioms to Haskell
507 | * There need to be several well-maintained and polished Haskell libraries for
508 | front-end programming
509 | * The whole `ghcjs` ecosystem needs much more documentation. There's not even
510 | a basic tutorial on how to actually use `ghcjs`
511 |
512 | **Notable Haskell-to-JavaScript compilers:**
513 |
514 | * [`ghcjs`](https://github.com/ghcjs/ghcjs)
515 | * [`haste`](https://hackage.haskell.org/package/haste-compiler)
516 |
517 | **Notable libraries:**
518 |
519 | * [reflex](https://hackage.haskell.org/package/reflex) / [reflex-dom](https://hackage.haskell.org/package/reflex-dom) - Functional reactive programming library
520 | for the front end
521 | * [miso](https://haskell-miso.org/) a small "[isomorphic](http://nerds.airbnb.com/isomorphic-javascript-future-web-apps/)" front-end framework featuring a virtual-dom, inspired by [Elm](http://elm-lang.org/), [Redux](http://redux.js.org/) and [Bobril](http://github.com/bobris/bobril).
522 |
523 |
524 |
525 | ## Distributed programming
526 |
527 | **Rating:** Immature
528 |
529 | This is sort of a broad area since I'm using this topic to refer to both
530 | distributed computation (for analytics) and distributed service architectures.
531 | For distributed service architectures Haskell is catching up to its peers with
532 | service toolkit libraries, but for distributed computation Haskell still lags
533 | behind.
534 |
535 | There has been a lot of work in replicating Erlang-like functionality in
536 | Haskell through the Cloud Haskell project, not just in creating the low-level
537 | primitives for code distribution / networking / transport, but also in
538 | assembling a Haskell analog of Erlang's OTP. Work on the higher-level libraries
539 | seems to have stopped, but the low-level libraries are still good for
540 | distributing computation.
541 |
542 | **Areas for improvement:**
543 |
544 | * We need more analytics libraries. Haskell has no analog of `scalding` or
545 | `spark`. The most we have is just a Haskell wrapper around `hadoop`
546 | * We need a polished consensus library (i.e. a high quality Raft
547 | implementation in Haskell)
548 |
549 | **Notable libraries:**
550 |
551 | * [`glue-core`](https://hackage.haskell.org/package/glue-core) /
552 | [`glue-ekg`](https://hackage.haskell.org/package/glue-ekg) /
553 | [`glue-example`](https://hackage.haskell.org/package/glue-example) - Service toolkit supporting
554 | * [`haxl`](https://hackage.haskell.org/package/haxl) - Facebook library for
555 | efficient batching and scheduling of concurrent data access
556 | * [`distributed-process`](https://hackage.haskell.org/package/distributed-process) / [`distributed-process-*`](https://hackage.haskell.org/packages/search?terms=distributed-process) - Haskell analog to Erlang
557 | * [`hadron`](https://github.com/Soostone/hadron) - Haskell wrapper around `hadoop`
558 | * [`amazonka`](https://hackage.haskell.org/package/amazonka) / [`amazonka-*`](https://hackage.haskell.org/packages/search?terms=amazonka) - Auto-generated
559 | bindings to the entire Amazon Web Services SDK
560 | * [`gogol`](http://hackage.haskell.org/package/gogol) / [`gogol-*`](https://hackage.haskell.org/packages/search?terms=gogol) - Auto-generated bindings to the entire Google Cloud Platform
561 | * [`transient`](https://github.com/transient-haskell/transient) - composable primitives for concurrency / parallelism / distributed computing
562 |
563 |
564 |
565 | ## Standalone GUI applications
566 |
567 | **Rating:** Immature
568 |
569 | All Haskell GUI libraries are wrappers around toolkits written in other
570 | languages (such as GTK+ or Qt). The last time I checked the `gtk` bindings
571 | were the most comprehensive, best maintained, and had the best documentation.
572 |
573 | The reason for the "Immature" rating is that there still isn't a Haskell
574 | binding to a widget toolkit that doesn't have some sort of setup issues with the
575 | toolkit.
576 |
577 | However, the Haskell bindings to GTK+ have a strongly imperative feel to them.
578 | The way you do everything is communicating between callbacks by mutating
579 | `IORef`s. Also, you can't take extensive advantage of Haskell's awesome
580 | threading features because the GTK+ runtime is picky about what needs to happen
581 | on certain threads. I haven't really seen a Haskell library that takes this
582 | imperative GTK+ interface and wraps it in a more idiomatic Haskell API.
583 |
584 | My impression is that most Haskell programmers interested in applications
585 | programming have collectively decided to concentrate their efforts on improving
586 | Haskell web applications instead of standalone GUI applications. Honestly,
587 | that's probably the right decision in the long run.
588 |
589 | Another post that goes into more detail about this topic is this post written
590 | by Keera Studios:
591 |
592 | * [On the state of GUI programming in Haskell](http://keera.co.uk/blog/2014/05/23/state-gui-programming-haskell/)
593 |
594 | **Areas for improvement:**
595 |
596 | * A GUI toolkit binding that is maintained, comprehensive, and easy to use
597 | * Polished GUI interface builders
598 |
599 | **Notable libraries:**
600 |
601 | * [`gi-gtk`](https://hackage.haskell.org/package/gi-gtk) and various [other bindings](https://github.com/haskell-gi/haskell-gi/tree/master/bindings) such as GStreamer audio/video - GTK+ (and more generally, GObject) bindings done right (autogenerated using GObject Introspection, hence `gi`)
602 | * [`wx`](https://hackage.haskell.org/package/wx) - wxWidgets bindings
603 | * [`X11`](https://hackage.haskell.org/package/X11) - X11 bindings
604 | * [`threepenny-gui`](https://hackage.haskell.org/package/threepenny-gui) - Framework for local apps that use the web browser as the
605 | interface
606 | * [`hsqml`](http://hackage.haskell.org/package/hsqml) - A Haskell binding for Qt Quick, a cross-platform framework for creating graphical user interfaces.
607 | * [`fltkhs`](http://hackage.haskell.org/package/fltkhs) - A Haskell binding to FLTK. Easy install/use, cross-platform, self-contained executables.
608 | * [`FregeFX`](https://github.com/Frege/FregeFX) - Frege bindings to Java FX
609 | (Frege is essentially the Haskell for the JVM)
610 | * [`typed-spreadsheet`](http://hackage.haskell.org/package/typed-spreadsheet) -
611 | Library for building composable interactive forms
612 | * [`brick`](https://github.com/jtdaugherty/brick) - Terminal UI based on vty package
613 |
614 | **Some example applications:**
615 |
616 | * [`xmonad`](http://xmonad.org)
617 | * [`leksah`](http://leksah.org/index.html)
618 |
619 | **Educational resources:**
620 |
621 | * [Haskell port of the GTK tutorial](http://code.haskell.org/gtk2hs/docs/tutorial/Tutorial_Port/)
622 | * [Building pragmatic user interfaces in Haskell with HsQML](https://www.youtube.com/watch?v=JCSxWfUvi6o)
623 | * [FLTK GUIs, including support for the Fluid visual interface builder](https://github.com/deech/fltkhs-compose-conference-2016-talk/blob/master/Talk.pdf)
624 |
625 |
626 |
627 | ## Machine learning
628 |
629 | **Rating:** Immature
630 |
631 | There are two approaches to using machine learning in Haskell:
632 |
633 | * Use a Haskell binding to an implementation in another language
634 | * Use a machine learning library implemented in Haskell
635 |
636 | You will most likely want to check out Haskell bindings to the `tensorflow`
637 | library if you are interested in the first approach:
638 |
639 | * [`tensorflow` Haskell bindings](https://github.com/tensorflow/haskell)
640 |
641 | You will also want to check out Haskell bindings to the `ArrayFire`
642 | library if you are interested in the first approach:
643 |
644 | * [`ArrayFire` Haskell bindings](https://github.com/arrayfire/arrayfire-haskell)
645 |
646 | Also, Tweag.io has released `Sparkle`, a Haskell integration with Spark. This
647 | enables the use of MLib from Haskell. MLib is widely used in the industry
648 | for machine learning. Sparkle itself is fairly new.
649 |
650 | * [Github repository for `Sparkle`](https://github.com/tweag/sparkle)
651 |
652 | If you are interested in Haskell implementations of machine learning libraries
653 | then the most promising ones are the `HLearn` project:
654 |
655 | * [Github repository for `HLearn`](https://github.com/mikeizbicki/HLearn)
656 |
657 | ... and the `grenade` project:
658 |
659 | * [Github repository for `grenade`](https://github.com/HuwCampbell/grenade)
660 |
661 | **Notable libraries:**
662 |
663 | * [`hasktorch`](https://github.com/hasktorch/hasktorch#readme) - Haskell bindings to
664 | libtorch which is the C++ API for PyTorch
665 | * [`HLearn-*`](https://hackage.haskell.org/packages/search?terms=HLearn) -
666 | Advanced implementations of a subset of machine learning algorithms
667 | * [`grenade`](https://github.com/HuwCampbell/grenade) - Machine learning
668 | library implemented in Haskell with a BLAS/LAPACK backend and a high-level
669 | type-based API
670 | * [`tensorflow`](https://github.com/tensorflow/haskell) - Haskell bindings to
671 | Google's `tensorflow` project
672 | * [`arrayfire`](https://github.com/arrayfire/arrayfire-haskell) - Haskell bindings to
673 | ArrayFire
674 | * [`ad`](https://hackage.haskell.org/package/ad) - Automatic differentiation,
675 | used as a substrate for many Haskell machine learning projects
676 |
677 |
678 |
679 | ## Game programming
680 |
681 | **Rating:** Immature
682 |
683 | Haskell is a garbage collected language, so Haskell is more appropriate for the
684 | scripting / logic layer of a game but not suitable manipulating a large object
685 | graph or for implementing a high-performance game engine due to the risk of
686 | introducing perceptible pauses due to GC pauses. Also, for simple games you can
687 | realistically use Haskell for the entire stack.
688 |
689 | Examples of games that could be fully implemented in Haskell:
690 |
691 | * Casual games
692 | * Turn-based strategy games
693 | * Adventure games
694 | * Platform / side-scrolling games
695 | * First-person shooter
696 |
697 | Examples of games that are difficult to implement at all in Haskell:
698 |
699 | * Real-time strategy games
700 | * MMORPGs
701 |
702 | Haskell has SDL, OpenGL, and Vulkan bindings, which are actually quite good, but that's
703 | about it. You're on your own from that point onward. There is not a rich
704 | ecosystem of higher-level libraries built on top of those bindings. There is
705 | some work in this area, but I'm not aware of anything production quality or
706 | easy to use.
707 |
708 | The primary reason for the immature rating is the difficulty of integrating
709 | Haskell with existing game platforms, which often are biased towards a
710 | particular language or toolchain. The only game platform where Haskell has no
711 | issues is native binaries for desktop games. For the web, you must compile to
712 | JavaScript, which is doable. For mobile games on Android you have to cross
713 | compile and interface the Haskell logic with Android through JNI + Haskell's
714 | foreign function interface. For console games, you have no hope.
715 |
716 | **Areas for improvement:**
717 |
718 | * Improve the garbage collector and benchmark performance with large heap sizes
719 | * Provide higher-level game engines
720 | * Improve distribution of Haskell games on proprietary game platforms
721 |
722 | **Notable libraries:**
723 |
724 | * [`gloss`](https://hackage.haskell.org/package/gloss) - Simple graphics and
725 | game programming for beginners
726 | * [Code World](https://code.world/haskell) - Similar to `gloss`, but you can try
727 | it in your browser
728 | * [`vulkan`](https://hackage.haskell.org/package/vulkan) - Low-level Vulkan bindings
729 | * [`gl`](https://hackage.haskell.org/package/gl) - Comprehensive OpenGL bindings
730 | * [`SDL`](https://hackage.haskell.org/package/SDL) / [`SDL-*`](https://hackage.haskell.org/packages/search?terms=SDL) / [`sdl2`](https://hackage.haskell.org/package/sdl2) - Bindings to the SDL library
731 | * [`SFML`](https://hackage.haskell.org/package/SFML) - Bindings to the SFML library
732 | * [`quine`](https://github.com/ekmett/quine) - Github project with cool 3D demos
733 | * [`GPipe`](https://hackage.haskell.org/package/GPipe) - Type-safe OpenGL API
734 | that also lets you embed shader code directly within Haskell. See the
735 | [GPipe wiki](https://wiki.haskell.org/GPipe) to learn more
736 |
737 | **Educational resources:**
738 |
739 | * [Purely Functional Games](https://gilmi.me/blog/post/2018/07/24/pfgames)
740 |
741 |
742 |
743 | ## ARM processor support
744 |
745 | **Rating:** Immature
746 |
747 | On hobbyist boards like the Raspberry Pi its possible to compile Haskell code
748 | with GHC. There are limitations; some libraries have problems on the arm platform,
749 | and GHCi only works on newer compilers. Cross compiling doesn't work with
750 | template Haskell. Stack and other large projects can take more than 1g of memory
751 | to compile.
752 |
753 | However, if the Haskell code builds, it runs with respectable performance on these machines.
754 |
755 | **Arch (Banana Pi)**
756 |
757 | update 2016-02-25:
758 |
759 | * installed today from pacman, current versions are GHC 7.10.3 and cabal-install 1.22.6.0
760 | * a compatible version of llvm also installed automatically.
761 | * GHCi passes hello world test; cabal/GHC compiled a modest project normally.
762 |
763 | **Raspian (Raspberry Pi, pi2, others)**
764 |
765 | * current version: GHC 7.4, cabal-install 1.14
766 | * GHCi doesn't work.
767 |
768 | **Debian Jesse (Raspberry Pi 3)**
769 |
770 | * works with: `ghc-7.10.3` and `stack-1.1.2`
771 | * Requires `llvm` version 3.5.2 or higher. Do not use the `llvm-3.5` provided by default in the Jessie package distribution
772 |
773 | **Arch (Raspberry Pi 2)**
774 |
775 | * current version 7.8.2, but llvm is 3.6, which is too new.
776 | * downgrade packages for llvm not officially available.
777 | * with llvm downgrade to 3.4, GHC and GHCi work, but problems compiling yesod,
778 | scotty.
779 | * compiler crashes, segfaults, etc.
780 |
781 |
782 |
783 | ## Computer Vision
784 |
785 | **Rating:** Immature
786 |
787 | The largest real world Haskell usage of computer vision is LumiGuide, which
788 | powers municipal bicycle detection and guidance systems in Amsterdam. They
789 | maintain `OpenCV` bindings in their `haskell-opencv` library.
790 |
791 | There are some interesting projects which try to tackle computer vision in a
792 | purely functional manner. `cv-combinators`, `easyVision`, and `Zef` are some
793 | examples.
794 |
795 | There are Haskell bindings for OpenCV available via `HOpenCV` which has bindings
796 | for versions up to `OpenCV 2.0`. A fork maintained by Anthony Cowley has bindings
797 | available for versions up to `OpenCV 2.4`, but it pretty much stops there.
798 | Currently, `OpenCV 3.0` has been released, and there are no Haskell bindings
799 | covering it.
800 |
801 | **Notable libraries:**
802 |
803 | * [`haskell-opencv`](https://github.com/LumiGuide/haskell-opencv)
804 | * [`HOpenCV`](https://github.com/sinelaw/HOpenCV)
805 | * [`HOpenCV` fork](https://github.com/acowley/HOpenCV)
806 | * [`easyVision`](https://github.com/albertoruiz/easyVision)
807 | * [`cv-combinators`](https://github.com/sinelaw/cv-combinators)
808 | * [`Zef`](https://github.com/ethereon/Zef)
809 |
810 | **Propaganda:**
811 |
812 | * [Google TechTalk on LumiGuide](https://www.youtube.com/watch?v=IKznN_TYjZk)
813 |
814 |
815 |
816 | ## Mobile apps
817 |
818 | **Rating:** Immature
819 |
820 | This greatly lags behind using languages that are natively supported by the
821 | mobile platform (i.e. Java for Android or Objective-C / Swift for iOS).
822 |
823 | However, one route is to compile Haskell to a supported language. For
824 | example, you can compile Haskell to Java using [Eta](https://eta-lang.org/)
825 | to port Haskell games to Android.
826 |
827 | **Educational resources:**
828 |
829 | * [Android 2048 game in Eta](https://github.com/Jyothsnasrinivas/eta-android-2048)
830 | * [Android development in Haskell](https://wiki.haskell.org/Android)
831 | * [iPhone development in Haskell](https://wiki.haskell.org/IPhone)
832 |
833 |
834 |
835 | ## Systems / embedded programming
836 |
837 | **Rating:** Bad / Immature (See description)
838 |
839 | Since systems programming is an abused word, I will clarify that I mean
840 | programs where speed, memory layout, and latency really matter.
841 |
842 | Haskell fares really poorly in this area because:
843 |
844 | * The language is garbage collected, so there are no latency guarantees
845 | * Executable sizes are large
846 | * Memory usage is difficult to constrain (thanks to space leaks)
847 | * Haskell has a large and unavoidable runtime, which means you cannot easily
848 | embed Haskell within larger programs
849 | * You can't easily predict what machine code that Haskell code will compile to
850 |
851 | Typically people approach this problem from the opposite direction: they write
852 | the low-level parts in C or Rust and then write Haskell bindings to the
853 | low-level code.
854 |
855 | It's worth noting that there is an alternative approach which is Haskell DSLs
856 | that are strongly typed that generate low-level code at runtime. This is the
857 | approach championed by the company Galois.
858 |
859 | **Notable libraries:**
860 |
861 | * [`atom`](https://hackage.haskell.org/package/atom) / [`ivory`](https://hackage.haskell.org/package/ivory) - DSL for generating embedded programs
862 | * [`copilot`](https://hackage.haskell.org/package/copilot) - Stream DSL that generates C code
863 | * [`improve`](https://hackage.haskell.org/package/improve) - High-assurance DSL for embedded code that generates C and Ada
864 |
865 | **Educational resources:**
866 |
867 | * [/r/haskell - Haskell compiled down to Embedded Hardware](https://www.reddit.com/r/haskell/comments/3gyol1/haskell_compiled_down_to_embedded_hardware/)
868 |
869 |
870 |
871 | # Common Programming Needs
872 |
873 | ## Maintenance
874 |
875 | **Rating:** Best in class
876 |
877 | Haskell is unbelievably awesome for maintaining large projects. There's nothing
878 | that I can say that will fully convey how nice it is to modify existing Haskell
879 | code. You can only appreciate this through experience.
880 |
881 | When I say that Haskell is easy to maintain, I mean that you can easily
882 | approach a large Haskell code base written by somebody else and make sweeping
883 | architectural changes to the project without breaking the code.
884 |
885 | You'll often hear people say: "if it compiles, it works". I think that is a
886 | bit of an exaggeration, but a more accurate statement is: "if you refactor and
887 | it compiles, it works". This lets you move fast without breaking things.
888 |
889 | Most statically typed languages are easy to maintain, but Haskell is on its
890 | own level for the following reasons:
891 |
892 | * Strong types
893 | * Purity
894 | * Global type inference
895 | * Type classes
896 | * Laziness
897 |
898 | The latter three features are what differentiate Haskell from other statically
899 | typed languages.
900 |
901 | If you've ever maintained code in other languages you know that usually your
902 | test suite breaks the moment you make large changes to your code base and you
903 | have to spend a significant amount of effort keeping your test suite up to date
904 | with your changes. However, Haskell has a very powerful type system that lets
905 | you transform tests into invariants that are enforced by the types so that you
906 | can statically eliminate entire classes of errors at compile time. These
907 | types are much more flexible than tests when modifying code and types require
908 | much less upkeep as you make large changes.
909 |
910 | The Haskell community and ecosystem use the type system heavily to "test" their
911 | applications, more so than other programming language communities. That's not
912 | to say that Haskell programmers don't write tests (they do), but rather they
913 | prefer types over tests when they have the option.
914 |
915 | Global type inference means that you don't have to update types and interfaces
916 | as you change the code. Whenever I do a large refactor the first thing I do is
917 | delete all type signatures and let the compiler infer the types and interfaces
918 | for me as I go. When I'm done refactoring I just insert back the type
919 | signatures that the compiler infers as machine-checked documentation.
920 |
921 | Type classes also assist refactoring because the compiler automatically
922 | infers type class constraints (analogous to interfaces in other languages) so
923 | that you don't need to explicitly annotate interfaces. This is a huge time
924 | saver.
925 |
926 | Laziness deserves special mention because many outsiders do not appreciate how
927 | laziness simplifies maintenance. Many languages require tight coupling between
928 | producers and consumers of data structures in order to avoid wasteful
929 | evaluation, but laziness avoids this problem by only evaluating data structures
930 | on demand. This means that if your refactoring process changes the order in
931 | which data structures are consumed or even stops referencing them altogether
932 | you don't need to reorder or delete those data structures. They will just
933 | sit around patiently waiting until they are actually needed, if ever, before
934 | they are evaluated.
935 |
936 |
937 |
938 | ## Single-machine Concurrency
939 |
940 | **Rating:** Best in class
941 |
942 | I give Haskell a "Best in class" rating because Haskell's concurrency runtime
943 | performs as well or better than mainstream languages and is significantly easier
944 | to use due to the runtime support for software-transactional memory.
945 |
946 | The best explanation of Haskell's threading module is the documentation in
947 | `Control.Concurrent`:
948 |
949 | > Concurrency is "lightweight", which means that both thread creation and
950 | > context switching overheads are extremely low. Scheduling of Haskell threads
951 | > is done internally in the Haskell runtime system, and doesn't make use of any
952 | > operating system-supplied thread packages.
953 |
954 | In Haskell, all I/O is non-blocking by default, so for example a web server
955 | will just spawn one lightweight thread per connection and each thread can be
956 | written in an ordinary synchronous style instead of nested callbacks like in
957 | Node.js.
958 |
959 | The best way to explain the performance of Haskell's threaded runtime is to
960 | give hard numbers:
961 |
962 | * The Haskell thread scheduler can easily handle millions of threads
963 | * Each thread requires 1 kb of memory, so the hard limitation to thread count
964 | is memory (1 GB per million threads).
965 | * Haskell channel overhead for the standard library (using `TQueue`) is on the
966 | order of one microsecond per message and degrades linearly with increasing
967 | contention
968 | * Haskell channel overhead using the `unagi-chan` library is on the order of
969 | 100 nanoseconds (even under contention)
970 | * Haskell's `MVar` (a low-level concurrency communication primitive) requires
971 | 10-20 ns to add or remove values (roughly on par with acquiring or releasing
972 | a lock in other languages)
973 |
974 | Haskell also provides software-transactional memory, which allows programmers
975 | build composable and atomic memory transactions. You can compose transactions
976 | together in multiple ways to build larger transactions:
977 |
978 | * You can sequence two transactions to build a larger atomic transaction
979 | * You can combine two transactions using alternation, falling back on the
980 | second transaction if the first one fails
981 | * Transactions can retry, rolling back their state and sleeping until one
982 | of their dependencies changes in order to avoid wasteful polling
983 |
984 | A few other languages provide software-transactional memory, but Haskell's
985 | implementation has two main advantages over other implementations:
986 |
987 | * The type system enforces that transactions only permit reversible memory
988 | modifications. This guarantees at compile time that all transactions can
989 | be safely rolled back.
990 | * Haskell's STM runtime takes advantage of enforced purity to improve the
991 | efficiency of transactions, retries, and alternation.
992 |
993 | Haskell is also the only language that supports both software transactional
994 | memory and non-blocking I/O.
995 |
996 | **Notable libraries:**
997 |
998 | * [`stm`](https://hackage.haskell.org/package/stm) - Software transactional memory
999 | * [`unagi-chan`](https://hackage.haskell.org/package/unagi-chan) - High performance channels
1000 | * [`async`](https://hackage.haskell.org/package/async) - Futures library
1001 | * [`streamly`](http://hackage.haskell.org/package/streamly) - A streaming library offering high performance concurrency
1002 |
1003 | **Educational resources:**
1004 |
1005 | * [Parallel and Concurrent Programming in Haskell](http://chimera.labs.oreilly.com/books/1230000000929)
1006 | * [Parallel and Concurrent Programming in Haskell - Software transactional
1007 | memory](http://chimera.labs.oreilly.com/books/1230000000929/ch10.html#sec_stm-async)
1008 | * [Beautiful concurrency](https://www.fpcomplete.com/school/advanced-haskell/beautiful-concurrency) - a software-transactional memory tutorial
1009 | * [Performance numbers for primitive operations](https://github.com/jberryman/chan-benchmarks#some-analysis-of-primitive-operations) - Latency timings for
1010 | various low-level operations
1011 |
1012 | **Propaganda:**
1013 |
1014 | * [What is the Haskell response to Node.js?](http://stackoverflow.com/questions/3847108/what-is-the-haskell-response-to-node-js)
1015 | * [Haskell and non-blocking asynchronous IO](https://blog.lahteenmaki.net/haskell-and-non-blocking-asynchronous-io.html)
1016 |
1017 |
1018 |
1019 | ## Types / Type-driven development
1020 |
1021 | **Rating:** Best in class
1022 |
1023 | Haskell definitely does not have the most advanced type system (not even close
1024 | if you count research languages) but out of all languages that are actually used
1025 | in production Haskell is probably at the top. Idris is probably the closest
1026 | thing to a type system more powerful than Haskell that has a realistic chance of
1027 | use in production in the foreseeable future.
1028 |
1029 | The killer features of Haskell's type system are:
1030 |
1031 | * Type classes
1032 | * Global type and type class inference
1033 | * Light-weight type syntax
1034 |
1035 | Haskell's type system really does not get in your way at all. You (almost)
1036 | never need to annotate the type of anything. As a result, the language feels
1037 | light-weight to use like a dynamic language, but you get all the assurances of
1038 | a static language.
1039 |
1040 | Many people are familiar with languages that support "local" type inference
1041 | (like Rust, Java, C#), where you have to explicitly type function arguments but
1042 | then the compiler can infer the types of local variables. Haskell, on the
1043 | other hand, provides "global" type inference, meaning that the types and
1044 | interfaces of all function arguments are inferred, too. Type signatures are
1045 | optional (with some minor caveats) and are primarily for the benefit of the
1046 | programmer.
1047 |
1048 | Here is an example of writing a function without any types or interfaces at all
1049 | and asking the compiler to infer them for you:
1050 |
1051 | ```haskell
1052 | >>> let addAndShow x y = show (x + y)
1053 | >>> :type addAndShow
1054 | addAndShow :: (Num a, Show a) => a -> a -> String
1055 | ```
1056 |
1057 | This really benefits projects where you need to prototype quickly but refactor
1058 | painlessly when you realize you are on the wrong track. You can leave out all
1059 | type signatures while prototyping but the types are still there even if you
1060 | don't see them. Then when you dramatically change course those strong and
1061 | silent types step in and keep large refactors painless.
1062 |
1063 | Some Haskell programmers use a "type-driven development" programming style,
1064 | analogous to "test-driven development":
1065 |
1066 | * they specify desired behavior as a type signature which initially fails to
1067 | type-check (analogous to adding a test which starts out "red")
1068 | * they create a quick and dirty solution that satisfies the type-checker
1069 | (analogous to turning the test "green")
1070 | * they improve on their initial solution while still satisfying the type-checker
1071 | (analogous to a "red/green refactor")
1072 |
1073 | "Type-driven development" supplements "test-driven development" and has
1074 | different tradeoffs:
1075 |
1076 | * The biggest disadvantage of types is that they don't test as many things as full-blown
1077 | tests, because Haskell is not (yet) dependently typed
1078 | * The biggest advantage of types is that they can prove the complete absence of
1079 | programming errors that you can encode in the type system, whereas tests
1080 | do not typically exercise every possible code path
1081 | * Type-checking is much faster than running tests
1082 | * Type error messages are informative: they explain what went wrong
1083 | * Type-checking never hangs and never gives flaky results
1084 |
1085 | Haskell also provides the "Typed Holes" extension, which lets you add an
1086 | underscore (i.e. "`_`") anywhere in the code whenever you don't know what
1087 | expression belongs there. The compiler will then tell you the expected type of
1088 | the hole and suggest terms in scope with related types that you can use to fill
1089 | the hole.
1090 |
1091 | There is also a newly added "Liquid Haskell" extension under development which
1092 | you can use to program with "refinement types". These types enrich Haskell's
1093 | type system with the ability to decorate type signatures with logical predicates
1094 | and arithmetic, and increases the number of invariants that you can encode at
1095 | the type level.
1096 |
1097 | **Educational resources:**
1098 |
1099 | * [Learn you a Haskell - Types and type classes](http://learnyouahaskell.com/types-and-typeclasses)
1100 | * [Learn you a Haskell - Making our own types and type classes](http://learnyouahaskell.com/making-our-own-types-and-typeclasses)
1101 | * [Typed holes](https://mail.haskell.org/pipermail/ghc-devs/2014-March/004239.html)
1102 | * [Partial type signatures proposal](https://mail.haskell.org/pipermail/ghc-devs/2014-March/004239.html)
1103 | * [Programming with refinement types](https://ucsd-progsys.github.io/liquidhaskell-tutorial/01-intro.html) - Very extensive tutorial on how to use Liquid
1104 | Haskell with interactive examples you can run in your browser
1105 |
1106 | **Propaganda:**
1107 |
1108 | * [What exactly makes the Haskell type system so revered (vs say, Java)?](http://programmers.stackexchange.com/questions/279316/what-exactly-makes-the-haskell-type-system-so-revered-vs-say-java)
1109 | * [Difference between OOP interfaces and FP type classes](http://stackoverflow.com/questions/8122109/difference-between-oop-interfaces-and-fp-type-classes)
1110 | * [Compile-time memory safety using Liquid Haskell](http://www.haskellforall.com/2015/12/compile-time-memory-safety-using-liquid.html) - post illustrating an
1111 | example use case for refinement types
1112 |
1113 |
1114 |
1115 | ## Parsing / Pretty-printing
1116 |
1117 | **Rating:** Best in class
1118 |
1119 | Haskell parsing is sooooooooooo slick. Recursive descent parser combinators are
1120 | far-and-away the most popular parsing paradigm within the Haskell ecosystem, so
1121 | much so that people use them even in place of regular expressions. I strongly
1122 | recommend reading the "Monadic Parsing in Haskell" functional pearl linked
1123 | below if you want to get a feel for why parser combinators are so dominant in
1124 | the Haskell landscape.
1125 |
1126 | If you're not sure what library to pick, I generally recommend the `parsec`
1127 | library as a default well-rounded choice because it strikes a decent balance
1128 | between ease-of-use, performance, good error messages, and small dependencies
1129 | (since it ships with GHC). There is also the `megaparsec` library, which is
1130 | modern and improved version of `parsec`.
1131 |
1132 | `attoparsec` deserves special mention as an extremely fast backtracking parsing
1133 | library. The speed and simplicity of this library will blow you away. The
1134 | main deficiency of `attoparsec` is the poor error messages.
1135 |
1136 | The pretty-printing front is also excellent. Academic researchers just really
1137 | love writing pretty-printing libraries in Haskell for some reason.
1138 |
1139 | **Parsing libraries:**
1140 |
1141 | * [`parsec`](https://hackage.haskell.org/package/parsec) - Best overall "value"
1142 | * [`megaparsec`](https://hackage.haskell.org/package/megaparsec) - Modern, actively maintained fork of `parsec`
1143 | * [`attoparsec`](https://hackage.haskell.org/package/attoparsec) - Extremely fast backtracking parser
1144 | * [`Earley`](https://hackage.haskell.org/package/Earley) - Earley parsing
1145 | embedded within the Haskell language. Parses all context-free
1146 | grammars, even ambiguous ones, with no need to left factor.
1147 | Returns all valid parses.
1148 | * [`trifecta`](https://hackage.haskell.org/package/trifecta) - Best error messages (`clang`-style)
1149 | * [`parsers`](https://hackage.haskell.org/package/parsers) - Interface compatible with `attoparsec`, `parsec` and `trifecta` which lets you easily switch between them. People commonly use this library to begin with `trifecta` or `parsec` (for better error messages) then switch to `attoparsec` when done for performance
1150 | * [`alex`](https://hackage.haskell.org/package/alex) / [`happy`](https://hackage.haskell.org/package/happy) - Like `lexx` / `yacc` but with Haskell integration
1151 |
1152 | **Pretty-printing libraries:**
1153 |
1154 | * [`prettyprinter`](https://hackage.haskell.org/package/prettyprinter) - Pretty-printing library
1155 | * [`text-format`](https://hackage.haskell.org/package/text-format) - High-performance string formatting
1156 |
1157 | **Educational resources:**
1158 |
1159 | * [Monadic Parsing in Haskell](http://www.cs.nott.ac.uk/~gmh/pearl.pdf)
1160 |
1161 | **Propaganda:**
1162 |
1163 | * [A major upgrade to attoparsec: more speed, more power](http://www.serpentine.com/blog/2014/05/31/attoparsec/)
1164 |
1165 |
1166 |
1167 | ## Domain-specific languages (DSLs)
1168 |
1169 | **Rating:** Mature
1170 |
1171 | Haskell rocks at DSL-building. While not as flexible as a Lisp language I
1172 | would venture that Haskell is the most flexible of the non-Lisp languages.
1173 | You can overload a large amount of built-in syntax for your custom DSL.
1174 |
1175 | The most popular example of overloaded syntax is `do` notation, which you can
1176 | overload to work with any type that implements the `Monad` interface. This
1177 | syntactic sugar for `Monad`s in turn led to a huge overabundance of `Monad`
1178 | tutorials.
1179 |
1180 | However, there are lesser known but equally important things that you can
1181 | overload, such as:
1182 |
1183 | * numeric and string literals
1184 | * `if`/`then`/`else` expressions
1185 | * list comprehensions
1186 | * numeric operators
1187 |
1188 | **Educational resources:**
1189 |
1190 | * [You could have invented monads](http://blog.sigfpe.com/2006/08/you-could-have-invented-monads-and.html)
1191 | * [Rebindable syntax](https://downloads.haskell.org/ghc/latest/docs/users_guide/exts/rebindable_syntax.html)
1192 | * [Monad comprehensions](https://downloads.haskell.org/ghc/latest/docs/users_guide/exts/monad_comprehensions.html)
1193 | * [Overloaded strings](https://www.fpcomplete.com/school/to-infinity-and-beyond/pick-of-the-week/guide-to-ghc-extensions/basic-syntax-extensions#overloadedstrings)
1194 |
1195 |
1196 |
1197 | ## Testing
1198 |
1199 | **Rating:** Mature
1200 |
1201 | There are a few places where Haskell is the clear leader among all languages:
1202 |
1203 | * property-based testing
1204 | * mocking / dependency injection
1205 |
1206 | Haskell's `QuickCheck` is the gold standard which all other property-based
1207 | testing libraries are measured against. The reason `QuickCheck` works so
1208 | smoothly in Haskell is due to Haskell's type class system and purity. The type
1209 | class system simplifies automatic generation of random data from the input type
1210 | of the property test. Purity means that any failing test result can be
1211 | automatically minimized by rerunning the check on smaller and smaller inputs
1212 | until `QuickCheck` identifies the corner case that triggers the failure.
1213 |
1214 | Mocking is another area where Haskell shines because you can overload almost
1215 | all built-in syntax, including:
1216 |
1217 | * `do` notation
1218 | * `if` statements
1219 | * numeric literals
1220 | * string literals
1221 |
1222 | Haskell programmers overload this syntax (particularly `do` notation) to write
1223 | code that looks like it is doing real work:
1224 |
1225 | ```haskell
1226 | example = do str <- readLine
1227 | putLine str
1228 | ```
1229 |
1230 | ... and the code will actually evaluate to a pure syntax tree that you can use
1231 | to mock in external inputs and outputs:
1232 |
1233 | ```haskell
1234 | example = ReadLine (\str -> PutStrLn str (Pure ()))
1235 | ```
1236 |
1237 | Haskell also supports most testing functionality that you expect from other
1238 | languages, including:
1239 |
1240 | * standard package interfaces for testing
1241 | * unit testing libraries
1242 | * test result summaries and visualization
1243 |
1244 | **Notable libraries:**
1245 |
1246 | * [`QuickCheck`](https://hackage.haskell.org/package/QuickCheck) - property-based testing
1247 | * [`doctest`](https://hackage.haskell.org/package/doctest) - tests embedded directly within documentation
1248 | * [`free`](https://hackage.haskell.org/package/free) - Haskell's abstract version of "dependency injection"
1249 | * [`hspec`](https://hackage.haskell.org/package/hspec) - Testing library analogous to Ruby's RSpec
1250 | * [`HUnit`](https://hackage.haskell.org/package/HUnit) - Testing library analogous to Java's JUnit
1251 | * [`tasty`](https://hackage.haskell.org/package/tasty) - Combination unit / regression / property testing library
1252 | * [`hedgehog`](http://hackage.haskell.org/package/hedgehog) - property-based testing with integrated shrinking
1253 | - [`HTF`](https://hackage.haskell.org/package/HTF) - Preprocessor based unit testing with various output formats
1254 |
1255 | **Educational resources:**
1256 |
1257 | * [Why free monads matter](http://www.haskellforall.com/2012/06/you-could-have-invented-free-monads.html)
1258 | * [Purify code using free monads](http://www.haskellforall.com/2012/07/purify-code-using-free-monads.html)
1259 | * [Up-front Unit Testing in Haskell](https://github.com/kazu-yamamoto/unit-test-example/blob/master/markdown/en/tutorial.md)
1260 |
1261 |
1262 |
1263 | ## Data structures and algorithms
1264 |
1265 | **Rating:** Mature
1266 |
1267 | Haskell primarily uses persistent data structures, meaning that when you
1268 | "update" a persistent data structure you just create a new data structure and
1269 | you can keep the old one around (thus the name: persistent). Haskell data
1270 | structures are immutable, so you don't actually create a deep copy of the data
1271 | structure when updating; any new structure will reuse as much of the original
1272 | data structure as possible.
1273 |
1274 | The **Notable libraries** sections contains links to Haskell collections
1275 | libraries that are heavily tuned. You should realistically expect these
1276 | libraries to compete with tuned Java code. However, you should not expect
1277 | Haskell to match expertly tuned C++ code.
1278 |
1279 | The selection of algorithms is not as broad as in Java or C++ but it is still
1280 | pretty good and diverse enough to cover the majority of use cases.
1281 |
1282 | **Notable libraries:**
1283 |
1284 | * [`vector`](https://hackage.haskell.org/package/vector) - High-performance arrays
1285 | * [`containers`](https://hackage.haskell.org/package/containers) - High-performance `Map`s, `Set`s, `Tree`s, `Graph`s, `Seq`s
1286 | * [`unordered-containers`](https://hackage.haskell.org/package/unordered-containers) - High-performance `HashMap`s, HashSets
1287 | * [`accelerate`](https://hackage.haskell.org/package/accelerate) / [`accelerate-*`](https://hackage.haskell.org/packages/search?terms=accelerate) - GPU programming
1288 | * [`massiv`](https://hackage.haskell.org/package/massiv) / [`repa`](https://hackage.haskell.org/package/repa) / [`repa-*`](https://hackage.haskell.org/packages/search?terms=repa) - parallel shape-polymorphic arrays
1289 | * [`discrimination`](http://hackage.haskell.org/package/discrimination) - Efficient linear-time sorting for user-defined datatypes
1290 | * [`algebraic-graphs`](https://hackage.haskell.org/package/algebraic-graphs)
1291 |
1292 |
1293 |
1294 | ## Benchmarking
1295 |
1296 | **Rating:** Mature
1297 |
1298 | This boils down exclusively to the `criterion` library, which was done so well
1299 | that nobody bothered to write a competing library. Notable `criterion`
1300 | features include:
1301 |
1302 | * Detailed statistical analysis of timing data
1303 | * Beautiful graph output: ([Example](http://www.serpentine.com/criterion/report.html))
1304 | * High-resolution analysis (accurate down to nanoseconds)
1305 | * Customizable HTML/CSV/JSON output
1306 | * Garbage collection insensitivity
1307 |
1308 | **Notable libraries:**
1309 |
1310 | * [`criterion`](https://hackage.haskell.org/package/criterion)
1311 | * [`gauge`](http://hackage.haskell.org/package/gauge) offers a similar feature set as `criterion` but has much fewer dependencies
1312 | * [`tasty-bench`](https://hackage.haskell.org/package/tasty-bench) even lighter than `guage` with support for comparing benchmarks
1313 |
1314 | **Educational resources:**
1315 |
1316 | * [The `criterion` tutorial](http://www.serpentine.com/criterion/tutorial.html)
1317 |
1318 |
1319 |
1320 | ## Unicode
1321 |
1322 | **Rating:** Mature
1323 |
1324 | Haskell's Unicode support is excellent. Just use the `text` and `text-icu`
1325 | libraries, which provide a high-performance, space-efficient, and easy-to-use
1326 | API for Unicode-aware text operations.
1327 |
1328 | Note that there is one big catch: the default `String` type in Haskell is
1329 | inefficient. You should always use `Text` whenever possible.
1330 |
1331 | **Notable libraries:**
1332 |
1333 | * [`text`](https://hackage.haskell.org/package/text)
1334 | * [`text-icu`](https://hackage.haskell.org/package/text-icu)
1335 | * [`unicode-transforms`](https://hackage.haskell.org/package/unicode-transforms) – Unicode normalization
1336 |
1337 |
1338 |
1339 | ## Stream programming
1340 |
1341 | **Rating:** Mature
1342 |
1343 | Haskell's streaming ecosystem is mature. Probably the biggest issue is that
1344 | there are too many good choices (and a lot of ecosystem fragmentation as a
1345 | result), but each of the streaming libraries listed below has a sufficiently
1346 | rich ecosystem including common streaming tasks like:
1347 |
1348 | * Network transmissions
1349 | * Compression
1350 | * External process pipes
1351 | * High-performance streaming aggregation
1352 | * Concurrent streams
1353 | * Incremental parsing
1354 |
1355 | **Notable libraries:**
1356 |
1357 | * [`conduit`](https://hackage.haskell.org/package/conduit) / [`io-streams`](https://hackage.haskell.org/package/io-streams) / [`pipes`](https://hackage.haskell.org/package/pipes) / [`streaming`](https://hackage.haskell.org/package/streaming) / [`streamly`](http://hackage.haskell.org/package/streamly) - Stream programming libraries (Full disclosure: I authored `pipes` and wrote the official `io-streams` tutorial)
1358 | * [`machines`](https://hackage.haskell.org/package/machines) - Networked stream transducers library
1359 |
1360 | **Educational resources:**
1361 |
1362 | * [The official `conduit` tutorial](https://www.fpcomplete.com/school/to-infinity-and-beyond/pick-of-the-week/conduit-overview)
1363 | * [The official `pipes` tutorial](http://hackage.haskell.org/package/pipes/docs/Pipes-Tutorial.html)
1364 | * [The official `io-streams` tutorial](http://hackage.haskell.org/package/io-streams/docs/System-IO-Streams-Tutorial.html)
1365 | * [A benchmark of popular streaming libraries](https://github.com/composewell/streaming-benchmarks)
1366 |
1367 |
1368 |
1369 | ## Serialization / Deserialization
1370 |
1371 | **Rating:** Mature
1372 |
1373 | Haskell's serialization libraries are reasonably efficient and very easy to
1374 | use. You can easily automatically derive serializers/deserializers for
1375 | user-defined data types and it's very easy to encode/decode values.
1376 |
1377 | Haskell's serialization does not suffer from any of the gotchas that
1378 | object-oriented languages deal with (particularly Java/Scala). Haskell data
1379 | types don't have associated methods or state to deal with so
1380 | serialization/deserialization is straightforward and obvious. That's also
1381 | why you can automatically derive correct serializers/deserializers.
1382 |
1383 | Serialization performance is pretty good. You should expect to serialize data
1384 | at a rate between 100 Mb/s to 1 Gb/s with careful tuning. Serialization
1385 | performance still has about 3x-5x room for improvement by multiple independent
1386 | estimates. See the "Faster binary serialization" link below for details of the
1387 | ongoing work to improve the serialization speed of existing libraries.
1388 |
1389 | **Notable libraries:**
1390 |
1391 | * [`binary`](https://hackage.haskell.org/package/binary) / [`cereal`](https://hackage.haskell.org/package/cereal) / [`serialise`](http://hackage.haskell.org/package/serialise) / [`store`](http://hackage.haskell.org/package/store) - serialization / deserialization libraries
1392 |
1393 | **Educational resources:**
1394 |
1395 | * [Benchmarks of several popular serialization libraries](https://github.com/haskell-perf/serialization)
1396 | * [Faster binary serialization](http://code.haskell.org/~duncan/binary-experiment/binary.pdf) / [Better, faster binary serialization](https://github.com/meiersi/HaskellerZ/blob/master/meetups/20150529-ZuriHac2015_Duncan_Coutts-Better_Faster_Binary_Serialization/binary.pdf) - Slides on serialization efficiency improvements
1397 |
1398 |
1399 |
1400 | ## Support for file formats
1401 |
1402 | **Rating:** Mature
1403 |
1404 | Haskell supports all the common domain-independent serialization formats (i.e.
1405 | XML/JSON/YAML/CSV). For more exotic formats Haskell won't be as good as, say,
1406 | Python (which is notorious for supporting a huge number of file formats) but
1407 | it's so easy to write your own quick and dirty parser in Haskell that this is
1408 | not much of an issue.
1409 |
1410 | **Notable libraries:**
1411 |
1412 | * [`aeson`](https://hackage.haskell.org/package/aeson) - JSON encoding/decoding
1413 | * [`cassava`](https://hackage.haskell.org/package/cassava) / [`sv`](http://hackage.haskell.org/package/sv)- CSV encoding/decoding
1414 | * [`yaml`](https://hackage.haskell.org/package/yaml) - YAML encoding/decoding
1415 | * [`HsYAML`](https://hackage.haskell.org/package/HsYAML) - pure Haskell YAML 1.2 parser
1416 | * [`xml`](https://hackage.haskell.org/package/xml) - XML encoding/decoding
1417 | * [`tomland`](http://hackage.haskell.org/package/tomland) - TOML encoding/decoding
1418 |
1419 |
1420 |
1421 | ## Package management
1422 |
1423 | **Rating:** Mature
1424 |
1425 | This rating is based entirely on the recent release of the `stack` package tool
1426 | by FPComplete which greatly simplifies package installation and dependency
1427 | management. This tool was created in response to a broad survey of existing
1428 | Haskell users and potential users where `cabal-install` was identified as the
1429 | single greatest issue for professional Haskell development.
1430 |
1431 | The `stack` tool is not just good by Haskell standards but excellent even
1432 | compared to other language package managers. Key features include:
1433 |
1434 | * Excellent project isolation (including compiler isolation)
1435 | * Global caching of shared dependencies to avoid wasteful rebuilds
1436 | * Easily add local repositories or remote GitHub repositories as dependencies
1437 |
1438 | `stack` is also powered by Stackage, which is a very large Hackage mono-build
1439 | that ensures that a large subset of Hackage builds correctly against each
1440 | other and automatically notifies package authors to fix or update libraries
1441 | when they break the mono-build. Periodically this package set is frozen as a
1442 | Stackage LTS release which you can supply to the `stack` tool in order to
1443 | select dependencies that are guaranteed to build correctly with each other.
1444 | Also, if all your projects use the same or similar LTS releases they will
1445 | benefit heavily from the shared global cache.
1446 |
1447 | **Educational resources:**
1448 |
1449 | * [The `stack` project](https://github.com/commercialhaskell/stack)
1450 |
1451 | **Propaganda:**
1452 |
1453 | * [`stack` announcement](https://www.fpcomplete.com/blog/2015/06/stack-0-1-release)
1454 |
1455 |
1456 |
1457 | ## Logging
1458 |
1459 | Haskell has decent logging support. That's pretty much all there is to say.
1460 |
1461 | **Rating:** Mature
1462 |
1463 | * [`fast-logger`](https://hackage.haskell.org/package/fast-logger) - High-performance multicore logging system
1464 | * [`hslogger`](https://hackage.haskell.org/package/hslogger) - Logging library analogous to Python's `logging` library
1465 | * [`monad-logger`](https://hackage.haskell.org/package/monad-logger) - add logging with line numbers to your monad stack. Uses fast-logger under the hood.
1466 | * [`katip`](http://hackage.haskell.org/package/katip) - Structured logging
1467 | * [`log`](https://hackage.haskell.org/package/log-base) - Logging system with ElasticSearch, PostgreSQL and stdout sinks.
1468 | * [`co-log`](https://hackage.haskell.org/package/co-log) - Composable contravariant comonadic logging library.
1469 |
1470 |
1471 |
1472 | ## Code formatting
1473 |
1474 | **Rating:** Mature
1475 |
1476 | Haskell has tools for automatic code formatting:
1477 |
1478 | * [`stylish-haskell`](https://hackage.haskell.org/package/stylish-haskell) - Less opinionated code formatting tool that mostly
1479 | formats imports, language extensions, and data type definitions
1480 | * [`ormolu`](https://hackage.haskell.org/package/ormolu) - More opinionated formatting tool that uses GHC's own parser
1481 | * [`brittany`](https://hackage.haskell.org/package/brittany) - Formats more than `stylish-haskell`, but less opinionated than
1482 | `ormolu`.
1483 |
1484 |
1485 |
1486 | ## Education
1487 |
1488 | **Rating:** Mature
1489 |
1490 | "Haskell Programming from first principles" has been published. I highly recommend it, for the following reasons:
1491 |
1492 | * The book does not assume any prior programming experience
1493 | * The book does not have any conceptual gaps or out-of-order dependencies
1494 | * The book is extremely comprehensive
1495 |
1496 | **Educational resources:**
1497 |
1498 | * [Haskell Programming from first principles](http://haskellbook.com/) - The best Haskell resource to learn from. The book costs $60, but it's worth the price.
1499 | * [Get Programming with Haskell](https://www.manning.com/books/get-programming-with-haskell)- An approachable and thorough introduction to Haskell and functional programming. A capstone project at the end of each unit.
1500 | * [Haskell Wikibook](https://en.wikibooks.org/wiki/Haskell) — One of the highest
1501 | quality among Wikimedia's Wikibooks, which starts from zero, with no
1502 | assumption of previous programming experience
1503 | * [How I Start - Haskell](https://howistart.org/posts/haskell/1) — Example
1504 | development environment and workflow
1505 | * [Happy Learn Haskell Tutorial](http://www.happylearnhaskelltutorial.com) - An
1506 | example-driven book for complete beginners, with interesting cartoons
1507 | * [Learn You a Haskell for Great Good](http://learnyouahaskell.com/chapters) — A
1508 | beginning Haskell book
1509 | * [Real world Haskell](http://book.realworldhaskell.org/read/) — A book that
1510 | contains several practical cookbook-style examples. Many code examples are
1511 | out of date, but the book is still useful
1512 | * [Parallel and Concurrent Programming in Haskell](http://chimera.labs.oreilly.com/books/1230000000929) — Exactly what the title says
1513 | * [Thinking Functionally with Haskell](http://www.cambridge.org/us/academic/subjects/computer-science/programming-languages-and-applied-logic/thinking-functionally-haskell) —
1514 | Book targeting people who are interested in Haskell in order to "think
1515 | differently"
1516 | * [Haskell wiki](https://wiki.haskell.org/Haskell) — Grab bag of Haskell-related
1517 | information with wide variation in quality. Excels at large lists of
1518 | resources or libraries if you don't mind sifting through stale or abandoned
1519 | entries
1520 | * [The Haskell 2010 Report](https://www.haskell.org/onlinereport/haskell2010/) —
1521 | The Haskell language specification
1522 | * [Queensland FP Lab - FP Course](https://blog.qfpl.io/projects/courses/) - An "interactive" course
1523 | ran within GHCI; beginner-safe, smoothly ramps up introduction of content.
1524 |
1525 |
1526 |
1527 | ## Databases and data stores
1528 |
1529 | **Rating:** Immature
1530 |
1531 | This is is not one of my areas of expertise, but what I do know is that Haskell
1532 | has bindings to most of the open source databases and datastores such as MySQL,
1533 | Postgres, SQLite, Cassandra, Redis, DynamoDB and MongoDB. However, I haven't really
1534 | evaluated the quality of these bindings other than the `postgresql-simple`
1535 | library, which is the only one I've personally used and was decent as far as I
1536 | could tell.
1537 |
1538 | The "Immature" ranking is based on the lack of bindings to commercial databases
1539 | like Microsoft SQL server and Oracle. So whether or not Haskell is right for
1540 | you probably depends heavily on whether there are bindings to the specific data
1541 | store you use.
1542 |
1543 | **Notable libraries:**
1544 |
1545 | * [`mysql-haskell`](http://hackage.haskell.org/package/mysql-haskell) / [`mysql-simple`](https://hackage.haskell.org/package/mysql-simple) - MySQL bindings
1546 | * [`postgresql-simple`](https://hackage.haskell.org/package/postgresql-simple) - Postgres bindings
1547 | * [`persistent`](https://hackage.haskell.org/package/persistent) - Database-agnostic ORM that supports automatic migrations
1548 | * [`esqueleto`](https://hackage.haskell.org/package/esqueleto) / [`relational-record`](https://hackage.haskell.org/package/relational-record) / [`opaleye`](https://hackage.haskell.org/package/opaleye) - type-safe APIs for building well-formed SQL queries
1549 | * [`acid-state`](https://hackage.haskell.org/package/acid-state) - Simple ACID data store that saves Haskell data types natively
1550 | * [`aws`](https://hackage.haskell.org/package/aws) - Bindings to Amazon DynamoDB
1551 | * [`hedis`](https://hackage.haskell.org/package/hedis) - Bindings to Redis
1552 | * [`groundhog`](https://hackage.haskell.org/package/groundhog) - A nice datatype to relational mapping library, similar to ORMs
1553 | * [`hasql`](https://hackage.haskell.org/package/hasql) - An efficient PostgreSQL driver and a flexible mapping API based on the binary protocol
1554 |
1555 |
1556 |
1557 | ## Debugging
1558 |
1559 | **Rating:** Immature
1560 |
1561 | The main Haskell debugging features are:
1562 |
1563 | * Memory and performance profiling
1564 | * Stack traces
1565 | * Source-located errors, using [the `assert` function](http://hackage.haskell.org/package/base-4.8.1.0/docs/Control-Exception-Base.html#v%3Aassert)
1566 | * Breakpoints, single-stepping, and tracing within the GHCi REPL
1567 | * Informal `printf`-style tracing using [`Debug.Trace`](https://hackage.haskell.org/package/base-4.8.1.0/docs/Debug-Trace.html)
1568 | * ThreadScope
1569 |
1570 | The two reasons I still mark debugging "Immature" are:
1571 |
1572 | * GHC's stack traces require profiling to be enabled
1573 | * There is only one IDE that I know of (`leksah`) that integrates support for
1574 | breakpoints and single-stepping and `leksah` still needs more polish
1575 |
1576 | `ghc-7.10` also added preliminary support for DWARF symbols which allow support
1577 | for `gdb`-based debugging and `perf`-based profiling, but there is still more
1578 | work that needs to be done. See the following page for more details:
1579 |
1580 | * [GHC DWARF support](https://ghc.haskell.org/trac/ghc/wiki/DWARF)
1581 |
1582 | **Educational resources**:
1583 |
1584 | * [GHC Manual - Profiling chapter](https://downloads.haskell.org/ghc/latest/docs/users_guide/profiling.html) - Read the whole thing; you will thank me
1585 | later
1586 | * [Debugging runtime options](https://downloads.haskell.org/ghc/latest/docs/users_guide/runtime_control.html#rts-options-for-hackers-debuggers-and-over-interested-souls) - See the `+RTS -xc` flag which adds stack traces to all exceptions (requires profiling enabled)
1587 | * [`GHC.Stack`](http://hackage.haskell.org/package/base-4.8.1.0/docs/GHC-Stack.html) - Programmatic access to the call stack
1588 | * [Pinpointing space leaks in big programs](http://blog.ezyang.com/2011/06/pinpointing-space-leaks-in-big-programs/)
1589 | * [Real World Haskell - Profiling and Optimization](http://book.realworldhaskell.org/read/profiling-and-optimization.html)
1590 | * [The GHCi Debuggger](https://downloads.haskell.org/ghc/latest/docs/users_guide/ghci.html#the-ghci-debugger) - Manual for GHCi-based breakpoints and
1591 | single-stepping
1592 | * [Parallel and Concurrent Programming in Haskell - Debugging, Tuning, and Interfacing with Foreign Code](http://chimera.labs.oreilly.com/books/1230000000929/ch15.html#_debugging_concurrent_programs) - Debugging concurrent programs
1593 | * [Haskell wiki - ThreadScope](https://wiki.haskell.org/ThreadScope)
1594 |
1595 |
1596 |
1597 | ## Cross-platform support
1598 |
1599 | **Rating:** Immature
1600 |
1601 | I give Haskell an "Immature" rating primarily due to poor user experience on
1602 | Windows:
1603 |
1604 | * Most Haskell tutorials assume a Unix-like system
1605 | * Several Windows-specific GHC bugs
1606 | * Poor IDE support (Most Windows programmers don't use a command-line editor)
1607 |
1608 | This is partly a chicken-and-egg problem. Haskell has many Windows-specific
1609 | issues because it has such a small pool of Windows developers to contribute
1610 | fixes. Most Haskell developers are advised to use another operating system or
1611 | a virtual machine to avoid these pain points, which exacerbates the problem.
1612 |
1613 | The situation is not horrible, though. I know because I do half of my Haskell
1614 | programming on Windows in order to familiarize myself with the pain points of
1615 | the Windows ecosystem and most of the issues affect beginners and can be worked
1616 | around by more experienced developers. I wouldn't say any individual issue is
1617 | an outright dealbreaker; it's more like a thousand papercuts which turn people
1618 | off of the language.
1619 |
1620 | If you're a Haskell developer using Windows, I highly recommend the following
1621 | installs to get started quickly and with as few issues as possible:
1622 |
1623 | * [Git for Windows](https://git-for-windows.github.io/) - A Unix-like
1624 | command-line environment bundled with `git` that you can use to follow along
1625 | with tutorials
1626 | * [MinGHC](https://www.haskell.org/downloads/windows) - Use this for
1627 | project-independent Haskell experimentation
1628 | * [Stack](https://github.com/commercialhaskell/stack) - Use this for
1629 | project development
1630 |
1631 | Additionally, learn to use the command line a little bit until Haskell IDE
1632 | support improves. Plus, it's a useful skill in general as you become a more
1633 | experienced programmer.
1634 |
1635 | For Mac, the recommended installation is:
1636 |
1637 | * [Haskell for Mac](http://haskellformac.com/) - A self-contained
1638 | relocatable GHC build for project-independent Haskell experimentation
1639 | * [Stack](https://github.com/commercialhaskell/stack) - Use this for
1640 | project development
1641 |
1642 | For other operating systems, use your package manager of choice to install
1643 | `ghc` and `stack`.
1644 |
1645 | **Educational resources:**
1646 |
1647 | * [Haskell wiki - Windows](https://wiki.haskell.org/Windows) - Windows startup
1648 | guide for Haskell
1649 |
1650 |
1651 |
1652 | ## Hot code loading
1653 |
1654 | **Rating:** Immature
1655 |
1656 | Haskell does provide support for hot code loading, although nothing in the same
1657 | ballpark as in languages like Clojure.
1658 |
1659 | There are two main approaches to hot code loading:
1660 |
1661 | * Compiling and linking object code at runtime (i.e. the `plugins` or `hint`
1662 | libraries)
1663 | * Recompiling the entire program and then reinitializing the program with the
1664 | program's saved state (i.e. the `dyre` or `halive` libraries)
1665 |
1666 | You might wonder how Cloud Haskell sends code over the wire and my understanding
1667 | is that it doesn't. Any function you wish to send over the wire is instead
1668 | compiled ahead of time on both sides and stored in a shared symbol table which
1669 | each side references when encoding or decoding the function.
1670 |
1671 | Haskell does not let you edit a live program like Clojure does so Haskell will
1672 | probably never be "Best in class" short of somebody releasing a completely new
1673 | Haskell compiler built from the ground up to support this feature. The existing
1674 | Haskell tools for hot code swapping seem as good as they are reasonably going
1675 | to get, but I'm waiting for commercial success stories of their use before
1676 | rating this "Mature".
1677 |
1678 | The `halive` library has the best hot code swapping demo by far:
1679 |
1680 | 
1681 |
1682 | **Notable libraries:**
1683 |
1684 | * [`rapid`](http://hackage.haskell.org/package/rapid) - Code reloading within
1685 | `ghci` that persists state across reloads
1686 | * [`plugins`](https://hackage.haskell.org/package/plugins) / [`hint`](https://hackage.haskell.org/package/hint) - Runtime compilation and linking
1687 | * [`dyre`](https://hackage.haskell.org/package/dyre) / [`halive`](https://hackage.haskell.org/package/halive) - Program reinitialization with saved state
1688 |
1689 |
1690 |
1691 | ## IDE support
1692 |
1693 | **Rating:** Immature
1694 |
1695 | The best supported editors at the moment appear to be:
1696 |
1697 | * Emacs (via `haskell-mode` + `intero`)
1698 | * Spacemacs (via haskell-layer)
1699 | * Vim (via `haskell-vim-now`)
1700 | * Atom (via `ide-haskell`)
1701 | * IntelliJ IDEA (http://rikvdkleij.github.io/intellij-haskell/)
1702 |
1703 | I am not the best person to review this area since I do not use an IDE myself.
1704 | I'm basing this "Immature" rating purely on what I have heard from others. The
1705 | impression I get is that the biggest pain point is that Haskell IDEs, IDE
1706 | plugins, and low-level IDE tools keep breaking. The above three editors are the
1707 | ones that have historically had the fewest setup issues.
1708 |
1709 | Most of the Haskell early adopters have been `vi`/`vim` or `emacs` users so
1710 | those editors have gotten the most love. Support for more traditional IDEs
1711 | has improved recently with Haskell plugins for Atom, IntelliJ, and also the
1712 | Haskell-native `leksah` IDE.
1713 |
1714 | Also, if you have a Mac then the "Haskell for Mac" development environment is
1715 | supposed to work really well for learning since it provides an interactive and
1716 | visual playground for exploring the code.
1717 |
1718 | **Notable tools:**
1719 |
1720 | * [`hoogle`](https://www.haskell.org/hoogle/) — Type-based function search
1721 | * [`hayoo`](http://hayoo.fh-wedel.de/) — Haskell function search covering more libraries
1722 | * [`hlint`](https://hackage.haskell.org/package/hlint) — Code linter
1723 | * [`ghc-mod`](https://hackage.haskell.org/package/ghc-mod) — editor agnostic tool that powers many IDE-like features
1724 | * [`ghcid`](https://hackage.haskell.org/package/ghcid) — lightweight background type-checker that triggers on code changes
1725 | * [`codex`](https://hackage.haskell.org/package/codex) — Tags file generator for cabal project dependencies.
1726 | * [`hdevtools`](https://hackage.haskell.org/package/hdevtools) — Persistent GHC-powered background server for development tools
1727 | * [`ghc-imported-from`](https://hackage.haskell.org/package/ghc-imported-from) — editor agnostic tool that finds Haddock documentation page for a symbol
1728 | * [`haskell-tools`](http://haskelltools.org/) - Refactoring tool + library
1729 | * [`ghcide`](https://github.com/digital-asset/ghcide) - A library for building Haskell IDE tooling
1730 | * [`stan`](https://github.com/kowainik/stan) - Haskell Static Analyser
1731 |
1732 | **Vim and Neovim Plugins:**
1733 |
1734 | * [`haskell-vim-now`](https://github.com/begriffs/haskell-vim-now) - a highly
1735 | customized `.vimrc` with some 20 plugins and key bindings configured to work with Haskell.
1736 | * [haskell-ide-engine](https://github.com/haskell/haskell-ide-engine) (see below) via [LanguageClient-neovim](https://github.com/autozimu/LanguageClient-neovim)
1737 |
1738 | The two plugins provide different sets of features.
1739 | Many plugins installed by `haskell-vim-now` can be used with `haskell-ide-engine`
1740 | as well, but there is no ready made config/installation script yet.
1741 |
1742 | **Emacs Plugins:**
1743 |
1744 | * [`haskell-mode`](https://github.com/haskell/haskell-mode) — Umbrella project for Haskell `emacs` support
1745 | * [`intero`](https://commercialhaskell.github.io/intero/) - Intero, a complete interactive development program for Haskell (another all-in-the-one solution for `emacs`)
1746 | * [`structured-haskell-mode`](https://github.com/chrisdone/structured-haskell-mode) - structural editing based on Haskell syntax for `emacs`
1747 | * [`haskell-ide-engine`](https://github.com/haskell/haskell-ide-engine) (see below) via [`emacs-lsp/lsp-haskell`](https://github.com/emacs-lsp/lsp-haskell)
1748 |
1749 | **Language Service Protocol:**
1750 |
1751 | The recent movement is to migrate all the editor plugins for Haskell to the Microsoft's Language Protocol (LSP) which allows to support many different editors with one unified plugin. The server part of the protocol is in [`haskell-ide-engine`](https://github.com/haskell/haskell-ide-engine) (not yet on hackage). The client part is different for different editors.
1752 |
1753 | The following editors are tested. See [haskell-ide-engine/README.md](https://github.com/haskell/haskell-ide-engine/blob/master/README.md#editor-integration) for installation instructions:
1754 |
1755 | - Visual Studio Code / VSCode
1756 | - Atom
1757 | - neovim / vim7
1758 | - Sublime Text
1759 |
1760 | More editors probably work, but there is no installation instruction yet: Eclipse, Eclipse Che, Microsoft Monaco,IntelliJ / JetBrains IDEs, Emacs, Theia, Spyder IDE, Oni. See an up to date list of "language clients" at http://langserver.org/
1761 |
1762 | Note that the [LSP protocol specification](https://microsoft.github.io/language-server-protocol/specification) currently only covers navigation/browsing/references, types/symbol info, refactoring, linting and completion/intellisense aspects of IDE. Project management, building, syntax highlighting and debugging are not covered yet, so you need separate editor-specific support for that. Sometimes when you install HIE as per instruction, these components are bundled as well, but sometimes they don't.
1763 |
1764 | **Non-LSP IDE plugins:**
1765 |
1766 | * Atom (the `ide-haskell` plugin)
1767 | * IntelliJ IDEA (Intellij-Haskell http://rikvdkleij.github.io/intellij-haskell/ or Haskforce http://haskforce.com/)
1768 | * Visual Studio Code (the `Haskell Syntax Highlighting` extension)
1769 |
1770 | **IDEs:**
1771 |
1772 | * [Haskell for Mac](http://haskellformac.com/)
1773 | * [`leksah`](https://hackage.haskell.org/package/leksah).
1774 |
1775 | **Educational resources:**
1776 |
1777 | * [A Vim + Haskell Workflow](https://www.stephendiehl.com/posts/vim_2016.html)
1778 | * [Survey: Which Haskell development tools are you using that make you a more
1779 | productive Haskell programmer?](https://www.reddit.com/r/haskell/comments/3bqy5h/survey_which_haskell_development_tools_are_you/)
1780 |
1781 | # Contributors
1782 |
1783 | * Aaron Levin
1784 | * Alois Cochard
1785 | * Ben Kovach
1786 | * Benno Fünfstück
1787 | * Carlo Hamalainen
1788 | * Chris Allen
1789 | * Curtis Gagliardi
1790 | * Deech
1791 | * David Howlett
1792 | * David Johnson
1793 | * Edward Cho
1794 | * Greg Weber
1795 | * Gregor Uhlenheuer
1796 | * Juan Pedro Villa Isaza
1797 | * Kazu Yamamoto
1798 | * Kevin Cantu
1799 | * Kirill Zaborsky
1800 | * Liam O'Connor-Davis
1801 | * Luke Randall
1802 | * Marcio Klepacz
1803 | * Mitchell Rosen
1804 | * Nicolas Kaiser
1805 | * Oliver Charles
1806 | * Pierre Radermecker
1807 | * Rodrigo B. de Oliveira
1808 | * Stephen Diehl
1809 | * Tim Docker
1810 | * Tran Ma
1811 | * Yuriy Syrovetskiy
1812 | * @bburdette
1813 | * @co-dan
1814 | * @ExternalReality
1815 | * @GetContented
1816 | * @psibi
1817 | * @newswim
1818 |
--------------------------------------------------------------------------------
/voice-feminization.md:
--------------------------------------------------------------------------------
1 | # What I wish I had known about voice feminization from the beginning
2 |
3 | This post is a somewhat unassorted collection of observations about voice
4 | feminization that I wish I had known about when I first started.
5 |
6 | This is not really a guide to voice feminization, meaning that this post alone
7 | won't help you feminize your voice or even help you get started. However, this
8 | might help supplement or accelerate your existing work to feminize your voice.
9 |
10 | Also, this guide will focus more on "meta" tips for feminizing your voice and
11 | focus less on low-level specific tips. These tips are not necessarily in any
12 | specific order, although I made an attempt to order them into a somewhat logical
13 | progression.
14 |
15 | Throughout this guide I'll do my best to distinguish observations that might be
16 | idiosyncratic to me and observations that I believe are generally applicable,
17 | based on what my voice therapist has taught me and also based on what I've
18 | learned from comparing notes with other people feminizing their voice.
19 |
20 | ## Background
21 |
22 | I wanted to explain a bit about my own background before I dive into the various
23 | observations since that background may help provide context for what I'm about
24 | to say.
25 |
26 | I'm a trans woman and I began feminizing my voice before coming out and
27 | publicly transitioning. The relevant events from my personal timeline were:
28 |
29 | - January 2021: I began to practice feminizing my voice by being self-taught
30 | (using [this guide](https://www.reddit.com/r/transvoice/comments/d3clhe/ls_voice_training_guide_level_1_for_mtf/))
31 | - July 2021: I first came out publicly on Twitter
32 | - January 2022: I finished coming out to essentially everyone in my life
33 | - March 2022: I began to see a voice therapist
34 | - September 2022: The time I initially wrote this post
35 |
36 | So throughout a long part of the voice feminization process there were plenty of
37 | times where I had neither the psychological safety nor support to feminize my
38 | voice.
39 |
40 | That lack of psychological safety is what led me to being self-taught instead
41 | of seeking a voice therapist and also led to many bad habits that I had to
42 | unlearn.
43 |
44 | If some of that stuff sounds familiar to you then you might find this guide
45 | helpful.
46 |
47 | Also, for what it's worth, these are two recordings of what my voice sounds like before and after voice feminization (the first video is pre-transition):
48 |
49 | - Before voice feminization: [Nix meetup presentation](https://www.youtube.com/watch?v=GMQPzv3Sx58)
50 |
51 | - After voice feminization: [ZuriHac 2023 presentation](https://www.youtube.com/watch?v=iAtYXS7eaiE)
52 |
53 | I'm also still continuing to learn more, but I feel comfortable enough to share
54 | what I've learned so far.
55 |
56 | Alright, with that out of the way, let's get to the tips …
57 |
58 | ## Tips
59 |
60 | ### Don't strain your voice
61 |
62 | I cannot stress this enough. You do not need to strain your voice to
63 | feminize your voice. Your feminine voice should feel
64 | comfortable, easy, and natural when you speak.
65 |
66 | The reason why this is my #1 tip is because this is the only mistake you
67 | can make that can cause permanent damage to your voice. Voice feminization
68 | is a completely reversible process unless you chronically strain your voice and
69 | then you risk irreversible degrading your voice.
70 |
71 | I was fortunate to avoid irreversibly damaging my voice, but I probably came
72 | close back when I was self-taught. Not only did I strain my voice quite a
73 | bit while training, but I began to notice that my voice would reliably get
74 | hoarse for a while after extensively using my feminine voice. I did some
75 | research and realized that I needed to stop and get help, which led me to
76 | seek a voice therapist.
77 |
78 | You also don't want to strain your voice because it will greatly decrease
79 | the quality of your voice: even when you're not hoarse you'll literally
80 | sound "strained" and unnatural while speaking.
81 |
82 | ### What does strain feel like?
83 |
84 | Strain feels like a build-up in tension, typically around your throat. As
85 | this tension builds up you find that you have greater difficulty sustaining
86 | your feminine voice, typically after only a few minutes of use.
87 |
88 | The surefire sign that you strained yourself too much is that your voice
89 | becomes hoarse. It's not the end of the world if you accidentally make your
90 | voice hoarse (everybody gets hoarse once in a while), but frequent and
91 | repeated episodes of voice hoarseness are a red flag that you need to seriously
92 | stop and see a voice therapist.
93 |
94 | When I do feel strain I most commonly feel it either around my vocal cords
95 | (near the middle of my neck) or in the neck muscles beneath my jaw.
96 |
97 | ### You might not have to actively train hard
98 |
99 | Many transfems report feminizing their voice by "just" gradually trying to
100 | slowly speak more effeminately over time. I cannot guarantee that this will
101 | work for you but I felt it was important to mention this.
102 |
103 | I never tried this route because I am a tryhard. When I learn new things I
104 | am pretty intense and voice feminization was no different.
105 |
106 | Did my intense process help me or speed things up? Probably not. But it's
107 | just the way that I learn. I also had no idea when I first started that the
108 | gradual process was even an option.
109 |
110 | If you continue reading, I'll assume you are a tryhard like me.
111 |
112 | ### HRT will not feminize your voice at all
113 |
114 | I think most people know this. If you went through a male puberty like
115 | me then most likely testosterone irreversibly deepened your voice. It's
116 | unfortunate, but that's the reality.
117 |
118 | ### Surgery alone will not feminize your voice
119 |
120 | There is such a thing as voice feminization surgery, but that mainly affects
121 | your habitual pitch which is not really the most important part of voice
122 | feminization. Also, even if you undergo surgery you will still need to
123 | supplement that surgery with voice therapy anyway.
124 |
125 | This is a long-winded way of saying: you will need practice and time to
126 | feminize your voice regardless of what you choose to do. There are no
127 | shortcuts here.
128 |
129 | ### Great news: you can feminize your voice quite well!
130 |
131 | Don't despair! A lot of transfems greatly underestimate how much they can
132 | feminize their voice. Even if your pre-transition voice is extremely deep
133 | and manly I'm confident that you can achieve a very convincing and
134 | comfortable feminine voice.
135 |
136 | Your voice is actually an incredibly versatile instrument and once you learn
137 | to unlock its power you will surprise yourself.
138 |
139 | Moreover, not only can you feminize your voice you can make your feminine
140 | voice your default voice, meaning that you will not need to pay attention
141 | or concentrate to feminize your voice. With practice, your feminine voice
142 | can become automatic and effortless.
143 |
144 | ### Voice training is (mostly) a mental exercise, not a physical exercise
145 |
146 | What I mean is that almost all the muscles you need to engage to feminize
147 | your voice are already strong enough to do what you need. The main
148 | exception I can think of would probably be the muscles you need to raise
149 | your larynx. In the early stages of vocal feminization you will need to
150 | strengthen those muscles so that it becomes effortless and comfortable to
151 | keep your larynx raised all day, every day.
152 |
153 | Other than that, voice feminization is mostly about developing
154 | improved
155 | [proprioceptive control](https://en.wikipedia.org/wiki/Proprioception) of
156 | the relevant muscles, rather than improving their strength.
157 |
158 | To make an analogy: I'm currently unable to raise my left eyebrow in
159 | isolation. I can raise both of my eyebrows simultaneously or raise only my
160 | right eyebrow, but I cannot raise only my left eyebrow. If I cared enough
161 | to really work at it I could slowly begin to learn how to move it over time
162 | but it would take spaced and repetitive practice before my mind could learn
163 | how to properly control those muscles. My brain would probably have to
164 | slowly form new synapses over time before I could fully control my left
165 | eyebrow.
166 |
167 | Voice training is like that. You're learning to move muscles that you've
168 | never moved that much before or never moved "in that way" before. No matter
169 | how diligently you practice your brain just needs time to learn how to
170 | control those muscles.
171 |
172 | This also means that it's less important how long you practice and it's
173 | more important how mentally engaged you are with your practice. Don't just
174 | mindlessly drill various exercises: instead, pay attention to what is
175 | happening inside your vocal tract and use your brain. There are all sorts of
176 | things you can focus on as you practice speaking or perform a drill, like:
177 |
178 | - How does your throat feel? Relaxed or tense? Do you feel strain?
179 | - How does your voice sound to you in your head?
180 | - How does your voice sound when you play back a recording?
181 | - What does the flow of air feel like?
182 | - Where do you feel vibration?
183 | - What did you do to make all of the above happen?
184 | - What is your overall emotional state as you're speaking?
185 |
186 | The more you pay attention to these things the more you improve your "mental
187 | resolution" of what is going on and that in turn improves your control.
188 |
189 | ### Don't try to power through strain
190 |
191 | Thinking of vocal training as a mental exercise rather than a physical
192 | exercise will also help you avoid strain. You do **NOT** want to try to
193 | persist or power through any difficulties you encounter.
194 |
195 | If a certain way of speaking strains your voice, it will always strain your
196 | voice. No amount of practice, exercise, or persistence will fix that. You
197 | just have to explore something different.
198 |
199 | If you find yourself straining as you feminize your voice, then follow these
200 | steps:
201 |
202 | - Stop
203 | - Take a break
204 | - Try something different next time
205 | - Don't give up: trust that you will eventually find a comfortable voice
206 |
207 | ### It's more important to be perceptive than to be persistent
208 |
209 | Along the same lines: if you haven't discovered anything new since your last
210 | practice then likely nothing will have improved since then. Repeating the
211 | same practice over and over day after day without learning any new lessons
212 | along the way will not result in any progress. I'll reiterate: voice
213 | feminization is mostly a mental exercise, not a physical exercise.
214 |
215 | Or to put it another way: if nothing changes, nothing will improve.
216 |
217 | Keep experimenting so that you're always trying new things and learning new
218 | things. Don't get stuck in a practice routine.
219 |
220 | ### Voice feminization still takes time
221 |
222 | A lot of people will hear "mental exercise" and think that they can discover
223 | some sort of clever shortcut or trick to speed up the process. This is
224 | partly true and partly false.
225 |
226 | There are some aspects of voice feminization where a leap of insight will
227 | lead to a marked improvement, kind of like being taught a new way to solve a
228 | math problem: once you know the trick it clicks and now you've got a
229 | powerful new tool in your toolbox.
230 |
231 | However, there are other aspects of voice training that require patience.
232 | In particular, there are many lessons or tricks you might be unable to learn
233 | until you develop improved proprioceptive control of the relevant muscles
234 | and that takes time.
235 |
236 | ### Learn how to not "misplace" your voice
237 |
238 | Eventually you will encounter the following frustrating
239 | phenomenon:
240 |
241 | - Your voice is "on fire" (it feels great and sounds great)
242 | - A few minutes later, you can no longer speak that way
243 | - You can't figure out what went wrong or how to go back to being "on fire"
244 |
245 | I call this "misplacing your voice". You feel like you left your voice
246 | somewhere by mistake and now you can't find it.
247 |
248 | A more advanced form of "misplacing your voice" is:
249 |
250 | - You figure out a trick to produce your desired voice
251 | - You go to sleep
252 | - The next day you try the same trick and … the trick no longer works
253 |
254 | This can be extremely demoralizing! So many times I would go into voice
255 | therapy and say something along the lines of "I swear I had this down pat
256 | yesterday but now I can't do it for some reason".
257 |
258 | In my view, misplacing your voice is sometimes an indicator of poor
259 | proprioceptive control. In other words, you have a low mental resolution of
260 | what's happening to produce your voice. You probably understand and can
261 | identify some of the things that you're doing correctly, but there are other
262 | things you are doing that you are blind to. Failing to notice those
263 | "other things" is one reason why the same trick will work on one day but
264 | then fail the next day.
265 |
266 | ### Voices are complicated
267 |
268 | Some voice training guides will try to distil voice training to a few
269 | orthogonal axes like:
270 |
271 | - resonance
272 | - pitch
273 | - airflow
274 |
275 | … but this is a gross oversimplification of what is actually happening when
276 | you produce a voice.
277 |
278 | First off, these elements of a voice are not really independent of one
279 | another. With training you can manipulate your voice to modulate only
280 | pitch or modulate only resonance, but by default if you try change one of
281 | these things that will likely spill over into other changes. Everything
282 | inside your vocal tract is interconnected. Controlling your voice at first will
283 | feel like like trying to program with really messy and low-level assembly code.
284 |
285 | Furthermore, there is a lot more dimension to these things. For example,
286 | you can technically measure resonance on a linear scale, but your vocal tract
287 | is not a linear dial; there is more than one way to produce the same target
288 | resonance.
289 |
290 | This is why you need to understand your voice at a low level first before
291 | you can begin to understand your voice at a high level. Be detail-oriented
292 | and nuanced when thinking about your voice, even if you have to make up your
293 | own terminology to explain to yourself what is working for you and what
294 | isn't. After doing this long enough you will build up the mental tools to
295 | begin thinking about your voice at a much higher level of abstraction
296 | (like programming in a higher-level programming language).
297 |
298 | ### Voices are simple
299 |
300 | LOL. Just kidding. Voices are still complicated, but I'm going to to
301 | simplify things in the way most other guides do so that I can talk about
302 | voices in broad strokes.
303 |
304 | The three things I'll mention for the purpose of this guide are:
305 |
306 | - resonance
307 |
308 | **RESONANCE IS THE MAIN THING THAT FEMINIZES YOUR VOICE!!!**
309 |
310 | - airflow
311 |
312 | Increasing airflow is what reduces strain and helps you attain a
313 | comfortable, effortless, and natural-sounding voice. Given the importance
314 | of reducing strain, airflow is really important!
315 |
316 | - pitch
317 |
318 | Pitch does far less to feminize your voice and is more of a "stylistic"
319 | thing. I'll expand upon this later.
320 |
321 | If I had to rank these things in order of importance I would say that
322 | resonance and airflow are tied for first place, whereas pitch is a distant
323 | third.
324 |
325 | This means that you should focus primarily on resonance and airflow at first
326 | before worrying about pitch. A common mistake that most people make is
327 | assuming that pitch is the most important part of vocal feminization and
328 | that is (in my view) wrong or at best highly misleading.
329 |
330 | Here are two great recordings highlighting many elements of vocal feminization:
331 |
332 | * [Vocal elements demo (layered)](https://clyp.it/5eq3io3u)
333 | * [Vocal elements demo (separate)](https://clyp.it/ggetrab2)
334 |
335 | … and the author of those recordings also authored the same guide that I
336 | initially used for being self-taught.
337 |
338 | * [L's Voice Training Guide (Level 1) for MTF transgender vocal feminization](https://www.reddit.com/r/transvoice/comments/d3clhe/ls_voice_training_guide_level_1_for_mtf/)
339 |
340 | Although that guide ultimately did not work out for me, it is a GOLDMINE for
341 | useful exercises, videos, and recordings.
342 |
343 | ### Resonance overview
344 |
345 | Resonance is the main thing that feminizes your voice. You want to increase
346 | your voice's resonant frequency which is also called "brightening" your
347 | resonance. In isolation, brightening resonance will make your voice sound
348 | brassy and you will feel your vocal tract "buzz" in new places.
349 |
350 | Anything you do to make your vocal tract smaller will brighten your
351 | resonance and feminize your voice. The most common and effective way to do this
352 | is to raise your larynx, but there are other ways you can modulate resonance,
353 | such as by shaping your tongue or mouth.
354 |
355 | A good sign that you're not brightening your resonance enough is that your
356 | voice doesn't sound feminine enough to your own ears.
357 |
358 | "One simple trick" I see transfems commonly share for brightening resonance is
359 | to try to speak as if your voice is coming from the top back of your vocal tract
360 | instead of coming from your chest. If you do this correctly you will naturally
361 | raise your larynx when attempting to speak in this way.
362 |
363 | I also recommend this video that explains resonance and some ways to practice
364 | and build an intuition for resonance:
365 |
366 | [The Single MOST Powerful Element of Voice Feminization: The Gender Dial (R1) | Exercises and Lecture](https://www.youtube.com/embed/BW8X2nXexQs)
367 |
368 | ### Airflow overview
369 |
370 | Airflow is how much air you muster in order to speak. The greater the
371 | airflow the more "breathy" your voice is, both figuratively (the way it
372 | sounds) and literally (you can feel more breath coming out of your
373 | mouth).
374 |
375 | For example, a loud laugh will tend to produce a lot of airflow, but also
376 | being (or pretending to be) exhausted from aerobic exercise will also
377 | produce a lot of airflow (because you will breathe more heavily). Those are
378 | extreme examples (you don't need *that* much air when speaking) but they can
379 | help you get an idea of what better airflow feels like.
380 |
381 | A good sign that you're not recruiting enough air to speak is that you
382 | strain your voice when speaking (especially when accessing higher pitch).
383 | In particular, you will feel tenseness or a pinch around your vocal cords if
384 | they're not getting enough airflow. When you recruit enough air your vocal
385 | cords will feel more relaxed.
386 |
387 | This video is the best resource I could find on this subject and it helped me
388 | build an intuition for what to listen for and how to promote airflow:
389 |
390 | [CLEAN UP THE VOICE & AVOID STRAIN | False Vocal Fold Control | 8 Exercises, Document, and Lecture](https://www.youtube.com/embed/xdsaPJdU24s)
391 |
392 | ### Pitch overview
393 |
394 | I think we all know what pitch is, so I'll gloss over that part.
395 |
396 | The main thing I want to mention is that resonance is not pitch. They are
397 | very different things and the most common mistake people make is believing
398 | that pitch feminizes the voice, when it's really resonance that feminizes
399 | the voice.
400 |
401 | I like to think of pitch as a tool for self-expression, meaning that it's
402 | something you modulate to "color" the way you speak to better convey
403 | yourself. Masculine speech tends to be more monotone whereas feminine
404 | speech tends to access a *much* wider range of pitch.
405 |
406 | In particular, feminine speaking can use pitch in a very situational way;
407 | it's not like a feminine voice has just "one" pitch. On a "macro" scale,
408 | women might lower their pitch in professional settings and raise their pitch
409 | in more casual settings. On a "micro" scale, feminine pitch can vary
410 | wildly and repeatedly over the course of a single sentence as a tool for
411 | emphasis.
412 |
413 | So think of pitch more as a tool for improved self-expression rather than as
414 | a tool for feminizing your voice *per se*. Accessing a wider range of pitch
415 | gives you more tools to express yourself, and that greater expressiveness
416 | does more to feminize your voice than the average pitch.
417 |
418 | I tried to do pitch training using this video (from the self-taught guide):
419 |
420 | ["How To Warm Up Your Voice" - Voice Lessons To the World](https://www.youtube.com/embed/9-1Padxsmio?start=281)
421 |
422 | … but ultimately I found that improving airflow did much more to improve the
423 | range of my pitch than those exercises.
424 |
425 | ### What do I need to fix?
426 |
427 | I can summarize the recent points by giving you the following rules of
428 | thumb for what to fix when your voice sounds wrong to you.
429 |
430 | - Does your voice not sound feminine enough? *Brighten your resonance*
431 |
432 | - Does your voice sound feminine, but artificial? *Increase your airflow*
433 |
434 | - Does your voice sound natural but it's not your "style"? *Vary your pitch*
435 |
436 | There's obviously more to feminizing a voice than these three changes, but
437 | those were the biggest wins, in my experience.
438 |
439 | ### Airflow - Revisited
440 |
441 | Minimizing strain and improving airflow was a particularly big deal for me
442 | because I have an unusually high "voice demand" compared to to other people.
443 | In particular, I do quite a bit of "long-form" speaking, such as:
444 |
445 | * presentations
446 | * streams
447 | * teaching
448 | * leading meetings at work
449 |
450 | … where I may have to speak for extended periods of time with infrequent
451 | interruptions.
452 |
453 | This is more challenging than conversational speech, where you have numerous
454 | opportunities to pause, catch your breath, and reset your voice. In demanding
455 | contexts, my voice would begin to strain and degrade quite quickly (on the order
456 | of a few minutes) and while I might occasionally reset and recover my voice
457 | quality it would rapidly degrade again.
458 |
459 | For me, improving airflow (and also speaking a little more slowly) was the big
460 | thing that fixed that. Now I can speak at length with fairly consistent
461 | quality.
462 |
463 | Moreover, once I found a voice with much better airflow and lower strain I
464 | began using that voice everywhere (even in less demanding contexts) because it
465 | was way more comfortable. Once you get the hang of speaking effeminately with
466 | lower strain you get hooked on it and can't go back.
467 |
468 | More generally, my voice therapist really drilled into me the importance of
469 | airflow:
470 |
471 | Pinching your voice to brighten resonance? Not enough airflow.
472 |
473 | Voice degrades at night when you're tired? Not enough airflow.
474 |
475 | Having trouble controlling pitch? Not enough airflow.
476 |
477 | Straining your voice? Not enough airflow.
478 |
479 | Voice degrades during long-form speaking? Not enough airflow.
480 |
481 | I got a little sick of hearing of this and it took me a while to understand
482 | what she was asking me to do, but then I realized how right she was.
483 |
484 | ### Practice mixing vowels into your voice
485 |
486 | In this guide I'm not sharing a lot of specific tricks, except for this one.
487 | This is one of the few tricks that had a disproportionate effect on the
488 | quality of my voice and the speed of my learning process. It might not
489 | work for everybody, but I'm mentioning this in case it does help somebody
490 | because I never saw this trick mentioned in the wild.
491 |
492 | The thing that worked really well for me was trying to "mix" specific vowel
493 | sounds into my speech. In other words, I try to "color" the way I speak to
494 | make it sound more like a specific vowel.
495 |
496 | For example, if I mix an "e" sound (either a long "e" or short "e") into my
497 | speech, that tends to promote a brighter resonance. Similarly, if I mix a
498 | "u" sound (either a long "u" or short "u") into my speech, that tends to
499 | promote improved airflow. Longer vowels tend to promote a higher pitch
500 | than shorter vowels.
501 |
502 | The reason this worked well for me was because it focused more on the way
503 | my voice sounded rather than the way I was moving my muscles. I personally
504 | found it easier and more intuitive to reproduce a desired vowel sound
505 | (because I already know how to prounce every vowel) than to think about
506 | "move X muscle to Y position" or "force the air to flow over here".
507 |
508 | The other reason this worked well for me is because it made easier for me
509 | to not "misplace" my voice. Any time my voice was "on fire" I would study
510 | what vowel sounds my voice most closely resembled. Furthermore, those vowel
511 | sounds captured enough nuances of the voice that I'd be able to recreate the
512 | same voice fairly closely day after day.
513 |
514 | ### Record your voice
515 |
516 | You would think that this advice is obvious but I have met people trying to
517 | feminize their voice that don't do this.
518 |
519 | You will actually need two types of recording apps, which brings us to the next
520 | two points:
521 |
522 | ### Get an app for short-term recordings
523 |
524 | You will need to be able to quickly record and play back throwaway
525 | recordings of your voice when practicing by yourself
526 |
527 | This quick and easy playback is essential for a few reasons:
528 |
529 | - You need to listen to your voice the way others hear it
530 |
531 | A voice that sounds feminine in your head might not sound feminine to
532 | others. Taking a recording lets you hear your voice the way others do.
533 |
534 | - You will listen more critically to a recording of your own voice
535 |
536 | Have you ever thought you look great in a mirror but ugly in pictures?
537 | That's because you're more used to seeing yourself (flipped) in a mirror
538 | than (unflipped) in a picture. Same thing with your voice: you're not
539 | used to hearing recordings of your voice, so you'll listen more critically
540 | to recordings.
541 |
542 | - You will build an intuition for the way your voice sounds
543 |
544 | The more recordings you take, the less you will depend on them. After a
545 | while you will build a pretty solid intuition for the way your voice
546 | sounds to others without having to record your voice.
547 |
548 | I personally use Vocal Pitch Monitor on Android for this purpose.
549 |
550 | ### Get an app for long-term recordings
551 |
552 | You also need to create more permanent recordings of yourself to listen to
553 | days/weeks/months later
554 |
555 | These long-term recordings serve several purposes:
556 |
557 | - Newer recordings can help you find a "misplaced" voice
558 |
559 | If you record yourself when your voice is "on fire", listening to that
560 | recording can help you recover that voice if you "misplaced" it.
561 |
562 | - Older recordings can improve your morale
563 |
564 | Sometimes when I feel like I'm not making progress I listen to an old
565 | recording and realize how far I came since then. It's like "progress
566 | pics", but for your voice.
567 |
568 | - Audio notes are much more effective than written notes
569 |
570 | Sometimes you will figure out a new trick or a new voice to play with
571 | and it's much easier to document what you learned by recording it.
572 |
573 | I personally use QuickTime on macOS for this purpose.
574 |
575 | ### Bonus: Record videos of yourself speaking effeminately
576 |
577 | If you use QuickTime you can also easily record and play back videos of
578 | yourself speaking. This might not seem like a big deal, but for me it
579 | went a long way towards internalizing my voice as "mine". Seeing my
580 | face speaking effeminately helps when I want to cement any new speaking
581 | habits.
582 |
583 | ### Take notes
584 |
585 | I prefer most of my notes to be audio recordings (organized by date), but
586 | written notes are okay, too, and can help supplement those recordings.
587 |
588 | The main purpose of taking notes is to force yourself to *think* about
589 | what you are doing. Remember that you will progress more quickly if
590 | you mentally engage with the voice feminization process.
591 |
592 | A secondary purpose of taking notes is to help yourself revisit an
593 | older voice or trick that worked well for you in the past, especially
594 | when you "misplace" your voice.
595 |
596 | ### You will be far more critical of your own voice than others
597 |
598 | You don't want to go too overboard when critically listening to your own
599 | voice. At some point you will begin to become more critical of your voice
600 | than even strangers would be. If other people tell you your voice is
601 | great or strangers on the phone stop misgendering your voice, then trust
602 | their judgment.
603 |
604 | Truthfully, the femininity of your voice doesn't really matter that much
605 | around friends and family. Whatever voice you use will always sound normal
606 | to them after enough time because in their mind it's neither a masculine
607 | nor feminine voice; it's just "your voice".
608 |
609 | Vocal feminization makes a bigger deal when interacting with strangers when
610 | you don't want to be misgendered. However, even then it can be easy to get
611 | carried away. There's actually a lot more overlap between the natural range
612 | of feminine voices and masculine voices than people acknowledge and as you
613 | actively train your voice you will become more conscious of this overlap
614 | and (hopefully) more forgiving of your own voice.
615 |
616 | ### Keep learning new things
617 |
618 | I've mentioned this already, but it's important to keep experimenting with new
619 | things for another reason: the more tricks you learn to feminize your voice
620 | the less you will strain your voice.
621 |
622 | Why? Because you won't lean so heavily on any one change to feminize your
623 | voice.
624 |
625 | For example, if resonance is all that you know for how to feminize your
626 | voice, then you will lean too hard on resonance and likely strain your
627 | larynx.
628 |
629 | Similarly, if pitch is one of the few tools in your toolbox then you might
630 | lean too heavily on pitch to feminize your voice and strain your vocal
631 | cords.
632 |
633 | There are actually a large number of ways to improve the perceived
634 | femininity of your voice, including:
635 |
636 | - Articulation
637 | - Tongue control
638 | - Word selection
639 | - Intonation
640 | - Body language!
641 |
642 | Body language is an interesting one because it can work even if the listener
643 | cannot see you (e.g. a telephone conversation). Just moving your body in
644 | a more effeminate way as you speak can actually mentally prime you to
645 | feminize your voice.
646 |
647 | Anyway, use all the tools at your disposal to feminize your voice because a
648 | well-rounded voice is a more comfortable voice.
649 |
650 | ### Code switching might make things harder
651 |
652 | By "code switching" I mean what this video is describing:
653 |
654 | [9 Difference Voices Women Use](https://www.youtube.com/embed/VlYFl83RwmU)
655 |
656 | Code switching made it harder for me to feminize my voice because I had to
657 | "relearn" some things in different social contexts. For example, there
658 | would be many contexts where I could feminize my voice very confidently
659 | and then other contexts where I struggle, because my mind would basically
660 | be like "this is not at all the same thing".
661 |
662 | Anyway, I mention this to note that it's totally fine if your feminine voice
663 | doesn't "transfer" easily between contexts. That will get better as you
664 | gain more experience feminizing your voice in each context.
665 |
666 | ### Find a safe way to train out loud
667 |
668 | Many transfems who begin to feminize their voice do so before they come
669 | out (myself included). Unfortunately, this can make it hard to find a safe
670 | place to train without accidentally outing oneself.
671 |
672 | You can partially mitigate this by focusing on practicing resonance first.
673 | Many resonance-related exercises can be done under your breath or without
674 | even speaking at all, which makes them safe to use in even hostile
675 | environments.
676 |
677 | Or, you might find an environment where you can speak out loud, but not
678 | too loud. For example, you might train in the privacy of your own room if
679 | you're quiet enough.
680 |
681 | However, you don't want to do this for too long, for the following reasons:
682 |
683 | * You will learn a bad habit of speaking with not enough airflow
684 |
685 | If you're always speaking quietly or under your breath you won't learn how
686 | to recruit enough air and you will consequently strain yourself once you
687 | try to graduate to more advanced stuff (especially varying pitch).
688 |
689 | * You will lean too hard on resonance to feminize your voice
690 |
691 | … which will also strain your voice. You want to cultivate a more
692 | well-rounded voice in order to keep your feminine speech comfortable.
693 |
694 | So, it's really worth investing in finding a place where you can practice
695 | "for real" free of any volume constraints or inhibitions.
696 |
697 | Some places that might work for you:
698 |
699 | * Your car (if you own one)
700 |
701 | You can drive to some parking lot and then sit in your car and train.
702 | Or you can train your voice while driving.
703 |
704 | Along the same lines, if you own a motorcycle you can also train your voice
705 | while driving.
706 |
707 | * Middle of nowhere
708 |
709 | If you know a secluded place (e.g. along a trail, a park, or the
710 | wilderness) where you're unlikely to meet other people, you can use that.
711 |
712 | * A music practice room
713 |
714 | If you play an instrument, you can rent/reserve a practice room and train
715 | your voice while you practice your instrument. If the rooms are
716 | sufficiently sound-proof and/or your instrument is loud enough then nobody
717 | will notice.
718 |
719 | * A public place where nobody will recognize you
720 |
721 | You might not be scared to practice your voice in public if it is around
722 | complete strangers (if all you are worried about is friends and family
723 | finding out).
724 |
725 | Additionally, you can also try just gradually feminizing your voice, even
726 | around people you know. If you feminize it slowly enough they won't even
727 | notice you're doing it for quite a while. People are generally pretty
728 | self-absorbed and won't notice stuff like that until it hits them in the
729 | face.
730 |
731 | ## Conclusion
732 |
733 | Let me know if you disagree with any of the advice here. I'm pretty open to
734 | being corrected or using more guarded language if I spoke too confidently.
735 |
736 | Also, feel free to submit changes if there's anything you'd like to add.
737 |
--------------------------------------------------------------------------------