├── 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 | *

I'd like to thank NFT community for stealing 13 pieces of my work and selling them as NFTs right now, without my consent. What a gift you got me.

— Robson Michel (@robmichel_art) December 26, 2021
82 | 83 | *

Sadly I'm going to have to completely shut down my entire @DeviantArt gallery as people keep stealing my art and making NFTs. I can't - and shouldn't have to - report each one and make a case, which is consistently ignored. Sad and frustrating. pic.twitter.com/oNH6yXQtyU

— Liam 'Sharpy' Sharp (@LiamRSharp) December 17, 2021
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 | *

NFTs have me convinced that I could just operate a Ponzi scheme. And be completely transparent about it. Lay out my plans in a prospectus. And heaps of people would buy into it.

— Oregano Jones, Legal Bystander (@OreganoJeauxns) January 1, 2022
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 | ![](https://camo.githubusercontent.com/6190c803f07b0c3380b4a2e3014a1e88c66c29ee/687474703a2f2f6c756b6578692e6769746875622e696f2f48616c69766544656d6f2e676966) 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 | --------------------------------------------------------------------------------