├── .github ├── ISSUE_TEMPLATE │ └── stories-launch-checklist.md ├── labels.yml └── workflows │ ├── ci.yml │ ├── pause-community-contributions.yml │ └── sync-labels.yml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── README.md ├── bin ├── lint_images.sh ├── lint_slugs.sh ├── lint_structure.sh └── lint_uuids.sh ├── config.json ├── config.json.schema.json ├── package.json ├── posts ├── 12in23-calendar.md ├── 12in23-feb-update.md ├── 14-increasingly-strange-ways-to-solve-hello-world.md ├── analytical-april.md ├── announcing-exercism-research.md ├── appy-august.md ├── automated-mentoring-support-project.md ├── bootcamp.md ├── call-for-maintainers-2020.md ├── coding-intentionally-in-bash-grains.md ├── community-tab.md ├── concurrency-parallelism-in-elixir.md ├── contribution-guidelines-nov-2023.md ├── december-diversions.md ├── dig-deeper.md ├── exercism-in-2019.md ├── exercism-io-is-now-exercism-org.md ├── exercism-is-the-official-go-mentoring-platform.md ├── exercism-v3-has-launched.md ├── finding-leap-years-with-cal.md ├── freeing-our-maintainers.md ├── functional-february.md ├── independent-mode-becomes-practice-mode.md ├── insiders-preview.md ├── inspiring-kids-with-clever-tykes.md ├── interview-with-erik-schierboom.md ├── interview-with-meade-kincke.md ├── interview-with-ryan-potts.md ├── introducing-48in24.md ├── introducing-community-comments.md ├── introducing-representers.md ├── introducing-the-exercism-blog.md ├── jurassic-july.md ├── mechanical-march.md ├── mindshifting-may.md ├── mozilla-supports-exercism-static-analysis.md ├── nibbly-november.md ├── object-oriented-october.md ├── oversubscribed-tracks.md ├── redesigning-tracks-in-partnership-with-chicago-university-and-sloan-foundation.md ├── september-2024-restructure.md ├── slimline-september.md ├── sorry-for-the-wait.md ├── summer-of-sexps.md ├── thank-you-by-erik.md ├── track-anatomy-project.md ├── unicode-matching-in-elixir.md ├── was-exercism-v2-worth-it.md ├── what-happens-if-my-mentor-disappears.md ├── whats-new-in-v3-with-angelika.md ├── whats-next-for-exercism-aug-2019.md └── xavdid-does-12in23.md ├── stories ├── abap-and-abap.md ├── beating-paralysis-and-printing-a-one-handed-keyboard.md ├── becoming-a-polyglot-developer.md ├── conquering-cancer-to-accessibility-activism.md ├── dont-be-too-productive.md ├── entrepreneurial-by-design.md ├── expeditions-elixir-and-exercism.md ├── learn-to-code-by-telling-the-story-of-a-program.md ├── problem-solving-your-way-into-being-a-tech-lead.md ├── programmer-by-accident.md ├── prolific-mentor-and-system-automater.md ├── push-off-with-python.md └── quantum-quests.md └── yarn.lock /.github/ISSUE_TEMPLATE/stories-launch-checklist.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "[STORIES] Launch Checklist" 3 | about: This is a checklist for items that need to be completed to launch a Community 4 | Story 5 | title: Community Story [Title] with [interviewee] 6 | labels: '' 7 | assignees: '' 8 | 9 | --- 10 | 11 | **Story Launch Checklist** 12 | 13 | - [ ] Confirm launch date and add to calendar. 14 | - [ ] Invite all team to launch date event 15 | - [ ] Create Folder in Dropbox with all the assets 16 | 17 | **Image Assets** 18 | 19 | - [ ] Youtube Thumbnail - 1280 x 720 / PNG or JPEG 20 | - [ ] Podbean thumbnail - 3000 x 3000 / PNG or JPEG 21 | - [ ] Get Interviewer headshot - Any Size / JPEG 22 | - [ ] Create 3 posts with interview quotes 23 | 24 | **Transcript** 25 | - send WAV to Erik to process transcript file 26 | 27 | **Video** 28 | 29 | - [ ] Download video files and save in Dropbox 30 | - [ ] Create and Edit video in iMovie 31 | - [ ] Export and Upload to Youtube 32 | 33 | **Audio** 34 | 35 | - [ ] Download WAV files from Descript 36 | - [ ] Import into Logic Pro and Bounce out 37 | - [ ] Upload to Podbean 38 | 39 | **Codebase Updates** 40 | 41 | - [ ] Update config.json file 42 | - [ ] Thumbnail URL link 43 | - [ ] Submit PR and tag Erik Schierboom / Jeremy Walker / Katrina Owen 44 | - [ ] Get subsequent PR merged prior to launch 45 | - [ ] Add Markdown transcript file to repo. 46 | 47 | **Posts** 48 | 49 | - [ ] Create Forum Post in #Exercism Tag: stories 50 | - [ ] Schedule release of assets in Buffer - www.buffer.com for Twitter, Linkedin etc 51 | - [ ] Create short URL - https://app.short.io/users/dashboard/501443/links 52 | 53 | **Team** 54 | 55 | - [ ] Like video 56 | - [ ] Like Podcasts 57 | - [ ] Like Forum post 58 | - [ ] Share to twitter and linkedin via personal social accounts 59 | -------------------------------------------------------------------------------- /.github/labels.yml: -------------------------------------------------------------------------------- 1 | # --------------------------------------------------------------- # 2 | # This is an auto-generated file - Do not manually edit this file # 3 | # --------------------------------------------------------------- # 4 | 5 | # This file is automatically generated by concatenating two files: 6 | # 7 | # 1. The Exercism-wide labels: defined in https://github.com/exercism/org-wide-files/blob/main/global-files/.github/labels.yml 8 | # 2. The repository-specific labels: defined in the `.appends/.github/labels.yml` file within this repository. 9 | # 10 | # If any of these two files change, a pull request is automatically created containing a re-generated version of this file. 11 | # Consequently, to change repository-specific labels you should update the `.appends/.github/labels.yml` file and _not_ this file. 12 | # 13 | # When the pull request has been merged, the GitHub labels will be automatically updated by the "Sync labels" workflow. 14 | # This typically takes 5-10 minutes. 15 | 16 | # --------------------------------------------------------------------- # 17 | # These are the Exercism-wide labels which are shared across all repos. # 18 | # --------------------------------------------------------------------- # 19 | 20 | # The following Exercism-wide labels are used to show "tasks" on the website, which will point users to things they can contribute to. 21 | 22 | # The `x:action/` labels describe what sort of work the contributor will be engaged in when working on the issue 23 | - name: "x:action/create" 24 | description: "Work on something from scratch" 25 | color: "ffffff" 26 | 27 | - name: "x:action/fix" 28 | description: "Fix an issue" 29 | color: "ffffff" 30 | 31 | - name: "x:action/improve" 32 | description: "Improve existing functionality/content" 33 | color: "ffffff" 34 | 35 | - name: "x:action/proofread" 36 | description: "Proofread text" 37 | color: "ffffff" 38 | 39 | - name: "x:action/sync" 40 | description: "Sync content with its latest version" 41 | color: "ffffff" 42 | 43 | # The `x:knowledge/` labels describe how much Exercism knowledge is required by the contributor 44 | - name: "x:knowledge/none" 45 | description: "No existing Exercism knowledge required" 46 | color: "ffffff" 47 | 48 | - name: "x:knowledge/elementary" 49 | description: "Little Exercism knowledge required" 50 | color: "ffffff" 51 | 52 | - name: "x:knowledge/intermediate" 53 | description: "Quite a bit of Exercism knowledge required" 54 | color: "ffffff" 55 | 56 | - name: "x:knowledge/advanced" 57 | description: "Comprehensive Exercism knowledge required" 58 | color: "ffffff" 59 | 60 | # The `x:module/` labels indicate what part of Exercism the contributor will be working on 61 | - name: "x:module/analyzer" 62 | description: "Work on Analyzers" 63 | color: "ffffff" 64 | 65 | - name: "x:module/concept" 66 | description: "Work on Concepts" 67 | color: "ffffff" 68 | 69 | - name: "x:module/concept-exercise" 70 | description: "Work on Concept Exercises" 71 | color: "ffffff" 72 | 73 | - name: "x:module/generator" 74 | description: "Work on Exercise generators" 75 | color: "ffffff" 76 | 77 | - name: "x:module/practice-exercise" 78 | description: "Work on Practice Exercises" 79 | color: "ffffff" 80 | 81 | - name: "x:module/representer" 82 | description: "Work on Representers" 83 | color: "ffffff" 84 | 85 | - name: "x:module/test-runner" 86 | description: "Work on Test Runners" 87 | color: "ffffff" 88 | 89 | # The `x:rep/` labels describe the amount of reputation to award 90 | # 91 | # For more information on reputation and how these labels should be used, 92 | # check out https://exercism.org/docs/using/product/reputation 93 | - name: "x:rep/tiny" 94 | description: "Tiny amount of reputation" 95 | color: "ffffff" 96 | 97 | - name: "x:rep/small" 98 | description: "Small amount of reputation" 99 | color: "ffffff" 100 | 101 | - name: "x:rep/medium" 102 | description: "Medium amount of reputation" 103 | color: "ffffff" 104 | 105 | - name: "x:rep/large" 106 | description: "Large amount of reputation" 107 | color: "ffffff" 108 | 109 | - name: "x:rep/massive" 110 | description: "Massive amount of reputation" 111 | color: "ffffff" 112 | 113 | # The `x:size/` labels describe the expected amount of work for a contributor 114 | - name: "x:size/tiny" 115 | description: "Tiny amount of work" 116 | color: "ffffff" 117 | 118 | - name: "x:size/small" 119 | description: "Small amount of work" 120 | color: "ffffff" 121 | 122 | - name: "x:size/medium" 123 | description: "Medium amount of work" 124 | color: "ffffff" 125 | 126 | - name: "x:size/large" 127 | description: "Large amount of work" 128 | color: "ffffff" 129 | 130 | - name: "x:size/massive" 131 | description: "Massive amount of work" 132 | color: "ffffff" 133 | 134 | # The `x:status/` label indicates if there is already someone working on the issue 135 | - name: "x:status/claimed" 136 | description: "Someone is working on this issue" 137 | color: "ffffff" 138 | 139 | # The `x:type/` labels describe what type of work the contributor will be engaged in 140 | - name: "x:type/ci" 141 | description: "Work on Continuous Integration (e.g. GitHub Actions workflows)" 142 | color: "ffffff" 143 | 144 | - name: "x:type/coding" 145 | description: "Write code that is not student-facing content (e.g. test-runners, generators, but not exercises)" 146 | color: "ffffff" 147 | 148 | - name: "x:type/content" 149 | description: "Work on content (e.g. exercises, concepts)" 150 | color: "ffffff" 151 | 152 | - name: "x:type/docker" 153 | description: "Work on Dockerfiles" 154 | color: "ffffff" 155 | 156 | - name: "x:type/docs" 157 | description: "Work on Documentation" 158 | color: "ffffff" 159 | 160 | # This Exercism-wide label is added to all automatically created pull requests that help migrate/prepare a track for Exercism v3 161 | - name: "v3-migration 🤖" 162 | description: "Preparing for Exercism v3" 163 | color: "e99695" 164 | 165 | # This Exercism-wide label can be used to bulk-close issues in preparation for pausing community contributions 166 | - name: "paused" 167 | description: "Work paused until further notice" 168 | color: "e4e669" 169 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | pull_request: 5 | workflow_dispatch: 6 | 7 | jobs: 8 | lint: 9 | name: Lint 10 | runs-on: ubuntu-22.04 11 | steps: 12 | - name: Checkout code 13 | uses: actions/checkout@e2f20e631ae6d7dd3b768f56a5d2af784dd54791 14 | 15 | - name: Setup nodejs 16 | uses: actions/setup-node@8c91899e586c5b171469028077307d293428b516 17 | with: 18 | node-version: 16 19 | cache: "yarn" 20 | 21 | - name: Install packages 22 | run: yarn install 23 | 24 | - name: Run linter 25 | run: yarn lint 26 | -------------------------------------------------------------------------------- /.github/workflows/pause-community-contributions.yml: -------------------------------------------------------------------------------- 1 | name: Pause Community Contributions 2 | 3 | on: 4 | issues: 5 | types: 6 | - opened 7 | pull_request_target: 8 | types: 9 | - opened 10 | 11 | permissions: 12 | issues: write 13 | pull-requests: write 14 | 15 | jobs: 16 | pause: 17 | if: github.repository_owner == 'exercism' # Stops this job from running on forks 18 | uses: exercism/github-actions/.github/workflows/community-contributions.yml@main 19 | with: 20 | forum_category: support 21 | secrets: 22 | github_membership_token: ${{ secrets.COMMUNITY_CONTRIBUTIONS_WORKFLOW_TOKEN }} 23 | -------------------------------------------------------------------------------- /.github/workflows/sync-labels.yml: -------------------------------------------------------------------------------- 1 | name: Tools 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | paths: 8 | - .github/labels.yml 9 | - .github/workflows/sync-labels.yml 10 | workflow_dispatch: 11 | schedule: 12 | - cron: 0 0 1 * * # First day of each month 13 | 14 | permissions: 15 | issues: write 16 | 17 | jobs: 18 | sync-labels: 19 | uses: exercism/github-actions/.github/workflows/labels.yml@main 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | ## Introduction 4 | 5 | Exercism is a platform centered around empathetic conversation. 6 | We have a low tolerance for communication that makes anyone feel unwelcome, unsupported, insulted or discriminated against. 7 | 8 | ## Seen or experienced something uncomfortable? 9 | 10 | If you see or experience abuse, harassment, discrimination, or feel unsafe or upset, please email [abuse@exercism.org](mailto:abuse@exercism.org?subject=%5BCoC%5D) and include \[CoC\] in the subject line. 11 | We will follow up with you as a priority. 12 | 13 | ## Enforcement 14 | 15 | We actively monitor for Code of Conduct (CoC) violations and take any reports of violations extremely seriously. 16 | We have banned contributors, mentors and users due to violations. 17 | 18 | After we receive a report of a CoC violation, we view that person's conversation history on Exercism and related communication channels and attempt to understand whether someone has deliberately broken the CoC, or accidentally crossed a line. 19 | We generally reach out to the person who has been reported to discuss any concerns we have and warn them that repeated violations will result in a ban. 20 | Sometimes we decide that no violation has occurred and that no action is required and sometimes we will also ban people on a first offense. 21 | We strive to be fair, but will err on the side of protecting the culture of our community. 22 | 23 | Exercism's leadership reserve the right to take whatever action they feel appropriate with regards to CoC violations. 24 | 25 | ## The simple version 26 | 27 | - Be empathetic 28 | - Be welcoming 29 | - Be kind 30 | - Be honest 31 | - Be supportive 32 | - Be polite 33 | 34 | ## The details 35 | 36 | Exercism should be a safe place for everybody regardless of 37 | 38 | - Gender, gender identity or gender expression 39 | - Sexual orientation 40 | - Disability 41 | - Physical appearance (including but not limited to body size) 42 | - Race 43 | - Age 44 | - Religion 45 | - Anything else you can think of 46 | 47 | As someone who is part of this community, you agree that: 48 | 49 | - We are collectively and individually committed to safety and inclusivity 50 | - We have zero tolerance for abuse, harassment, or discrimination 51 | - We respect people’s boundaries and identities 52 | - We refrain from using language that can be considered offensive or oppressive (systemically or otherwise), eg. sexist, racist, homophobic, transphobic, ableist, classist, etc. 53 | - this includes (but is not limited to) various slurs. 54 | - We avoid using offensive topics as a form of humor 55 | 56 | We actively work towards: 57 | 58 | - Being a safe community 59 | - Cultivating a network of support & encouragement for each other 60 | - Encouraging responsible and varied forms of expression 61 | 62 | We condemn: 63 | 64 | - Stalking, doxxing, or publishing private information 65 | - Violence, threats of violence or violent language 66 | - Anything that compromises people’s safety 67 | - Conduct or speech which might be considered sexist, racist, homophobic, transphobic, ableist or otherwise discriminatory or offensive in nature 68 | - The use of unwelcome, suggestive, derogatory or inappropriate nicknames or terms 69 | - Disrespect towards others (jokes, innuendo, dismissive attitudes) and towards differences of opinion 70 | - Intimidation or harassment (online or in-person). 71 | Please read the [Citizen Code of Conduct](https://github.com/stumpsyn/policies/blob/master/citizen_code_of_conduct.md) for how we interpret harassment 72 | - Inappropriate attention or contact 73 | - Not understanding the differences between constructive criticism and disparagement 74 | 75 | These things are NOT OK. 76 | 77 | Be aware of how your actions affect others. 78 | If it makes someone uncomfortable, stop. 79 | 80 | If you say something that is found offensive, and you are called out on it, try to: 81 | 82 | - Listen without interruption 83 | - Believe what the person is saying & do not attempt to disqualify what they have to say 84 | - Ask for tips / help with avoiding making the offense in the future 85 | - Apologize and ask forgiveness 86 | 87 | ## History 88 | 89 | This policy was initially adopted from the Front-end London Slack community and has been modified since. 90 | A version history can be seen on [GitHub](https://github.com/exercism/website-copy/edit/main/pages/code_of_conduct.md). 91 | 92 | _This policy is a "living" document, and subject to refinement and expansion in the future. 93 | This policy applies to the Exercism website, the Exercism GitHub organization, any other Exercism-related communication channels (e.g. Discord, Forum, Twitter, email) and any other Exercism entity or event._ 94 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # The Exercism Blog 2 | 3 | ## Want to write a blog post to feature on Exercism? 4 | 5 | Great! Please feel free to open an issue and we will discuss it with you. 6 | 7 | ## Images 8 | 9 | Each blog post can have an image. 10 | They follow the naming pattern of the slug for the post. 11 | We strongly maintain the right to control the images for quality/consistency. 12 | 13 | The images are uploaded to s3 by the maintainers of this repo. 14 | -------------------------------------------------------------------------------- /bin/lint_images.sh: -------------------------------------------------------------------------------- 1 | exit_code=0 2 | 3 | for thumbnail_url in $(jq -r '.stories[] | .thumbnail_url' config.json); do 4 | curl --head --silent --fail "${thumbnail_url}" 2>&1 1> /dev/null 5 | if [ $? -ne 0 ]; then 6 | echo -e "\033[0;31mThe image at ${thumbnail_url} is missing\033[0m" 7 | exit_code=1 8 | fi 9 | done 10 | 11 | exit $exit_code -------------------------------------------------------------------------------- /bin/lint_slugs.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | function check_slugs() { 4 | duplicate_slugs=$(jq -r --arg key $1 '.[$key][].slug' config.json | sort | uniq -d) 5 | if [ -n "$duplicate_slugs" ]; then 6 | echo -e "\033[0;31mThe following $1 slugs are not unique:\033[0m" 7 | echo "$duplicate_slugs" 8 | exit 1 9 | fi 10 | } 11 | 12 | check_slugs posts 13 | check_slugs stories 14 | -------------------------------------------------------------------------------- /bin/lint_structure.sh: -------------------------------------------------------------------------------- 1 | exit_code=0 2 | 3 | for post_slug in $(jq -r '.posts[].slug' config.json | sort); do 4 | post_markdown_file="./posts/${post_slug}.md" 5 | if [ ! -f ${post_markdown_file} ]; then 6 | echo "\033[0;31mMissing markdown file '${post_markdown_file}' for post '${post_slug}'\033[0m" 7 | exit_code=1 8 | fi 9 | done 10 | 11 | for story_slug in $(jq -r '.stories[].slug' config.json | sort); do 12 | story_markdown_file="./stories/${story_slug}.md" 13 | if [ ! -f ${story_markdown_file} ]; then 14 | echo "\033[0;31mMissing markdown file '${story_markdown_file}' for story '${story_slug}'\033[0m" 15 | exit_code=1 16 | fi 17 | done 18 | 19 | exit $exit_code 20 | -------------------------------------------------------------------------------- /bin/lint_uuids.sh: -------------------------------------------------------------------------------- 1 | duplicate_uuids=$(jq -r '.. | .uuid? | select(. != null)' config.json | sort | uniq -d) 2 | if [ -n "$duplicate_uuids" ]; then 3 | echo "\033[0;31mThe following UUIDs are not unique:\033[0m" 4 | echo "$duplicate_uuids" 5 | exit 1 6 | fi 7 | -------------------------------------------------------------------------------- /config.json.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema", 3 | "type": "object", 4 | "definitions": { 5 | "uuid": { 6 | "description": "A version 4 UUID", 7 | "type": "string", 8 | "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" 9 | }, 10 | "slug": { 11 | "description": "A kebab-case string (alphanumeric characters and dashes only)", 12 | "type": "string", 13 | "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$", 14 | "minLength": 1, 15 | "maxLength": 255 16 | }, 17 | "string": { 18 | "description": "A regular string", 19 | "type": "string", 20 | "minLength": 1, 21 | "maxLength": 255 22 | }, 23 | "text": { 24 | "description": "A more extensive string", 25 | "type": "string", 26 | "minLength": 1, 27 | "maxLength": 280 28 | }, 29 | "publication_date": { 30 | "description": "A publication date, which is specific to day/hour/minute (no seconds)", 31 | "type": "string", 32 | "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}$" 33 | }, 34 | "handle": { 35 | "description": "A handle, as used on GitHub", 36 | "type": "string", 37 | "pattern": "^[a-zA-Z0-9_-]+$", 38 | "minLength": 1, 39 | "maxLength": 255 40 | }, 41 | "url": { 42 | "description": "A URL", 43 | "type": "string", 44 | "pattern": "^https?://.+", 45 | "minLength": 1, 46 | "maxLength": 255 47 | }, 48 | "length_in_minutes": { 49 | "description": "A length in minutes", 50 | "type": "number", 51 | "minimum": 1 52 | }, 53 | "post": { 54 | "description": "A blog post", 55 | "type": "object", 56 | "properties": { 57 | "uuid": { "$ref": "#/definitions/uuid" }, 58 | "slug": { "$ref": "#/definitions/slug" }, 59 | "title": { "$ref": "#/definitions/string" }, 60 | "category": { "$ref": "#/definitions/slug" }, 61 | "language": { "$ref": "#/definitions/slug" }, 62 | "author_handle": { "$ref": "#/definitions/handle" }, 63 | "published_at": { "$ref": "#/definitions/publication_date" }, 64 | "image_url": { "$ref": "#/definitions/url" }, 65 | "youtube_id": { "$ref": "#/definitions/string" }, 66 | "marketing_copy": { "$ref": "#/definitions/text" } 67 | }, 68 | "required": [ 69 | "uuid", 70 | "slug", 71 | "title", 72 | "category", 73 | "published_at", 74 | "author_handle", 75 | "marketing_copy" 76 | ] 77 | }, 78 | "story": { 79 | "description": "A community story", 80 | "type": "object", 81 | "properties": { 82 | "uuid": { "$ref": "#/definitions/uuid" }, 83 | "slug": { "$ref": "#/definitions/slug" }, 84 | "title": { "$ref": "#/definitions/string" }, 85 | "blurb": { "$ref": "#/definitions/text" }, 86 | "language": { "$ref": "#/definitions/slug" }, 87 | "author_handle": { "$ref": "#/definitions/handle" }, 88 | "published_at": { "$ref": "#/definitions/publication_date" }, 89 | "thumbnail_url": { "$ref": "#/definitions/url" }, 90 | "image_url": { "$ref": "#/definitions/url" }, 91 | "length_in_minutes": { "$ref": "#/definitions/length_in_minutes" }, 92 | "interviewer_handle": { "$ref": "#/definitions/handle" }, 93 | "interviewee_handle": { "$ref": "#/definitions/handle" }, 94 | "youtube_id": { "$ref": "#/definitions/string" } 95 | }, 96 | "required": [ 97 | "uuid", 98 | "slug", 99 | "title", 100 | "blurb", 101 | "published_at", 102 | "length_in_minutes", 103 | "thumbnail_url", 104 | "image_url", 105 | "interviewee_handle", 106 | "interviewer_handle", 107 | "youtube_id" 108 | ] 109 | } 110 | }, 111 | "properties": { 112 | "posts": { 113 | "description": "The blog posts", 114 | "type": "array", 115 | "items": { 116 | "$ref": "#/definitions/post" 117 | } 118 | }, 119 | "stories": { 120 | "description": "The community stories", 121 | "type": "array", 122 | "items": { 123 | "$ref": "#/definitions/story" 124 | } 125 | } 126 | }, 127 | "required": ["posts", "stories"] 128 | } 129 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "license": "MIT", 3 | "dependencies": { 4 | "ajv-cli": "^5.0.0" 5 | }, 6 | "scripts": { 7 | "lint": "yarn lint-schema && yarn lint-uuids && yarn lint-structure && yarn lint-slugs && yarn lint-images", 8 | "lint-schema": "ajv validate -s config.json.schema.json -d config.json", 9 | "lint-uuids": "bin/lint_uuids.sh", 10 | "lint-structure": "bin/lint_structure.sh", 11 | "lint-images": "bin/lint_images.sh", 12 | "lint-slugs": "bin/lint_slugs.sh" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /posts/12in23-calendar.md: -------------------------------------------------------------------------------- 1 | Hi everyone, 2 | 3 | We’ve been blown away by the response to #12in23. Thousands of you have started the challenge and some of you have already completed it - which is an amazing achievement! 4 | 5 | I wanted to take a few minutes to tell you what we’ve got planned for the rest of the year and give you the opportunity to participate even further! 6 | 7 | The first thing to know is that we’re going to have a theme for each month where we encourage you to explore a certain paradigm, type of programming, maybe a specific point in time - for example trying really old languages or really new ones. 8 | 9 | During that month we’re going to be streaming people chatting about that month’s theme, solving exercises in various featuredlanguages, and just trying to push as much interesting, useful content your way as possible! If you’d like to get involved in this, please reach out to us - see the link in the description. 10 | 11 | Also, before I dig into what the year is going to look like, please hit subscribe so that you don’t miss any of the content as we release it through the year! 12 | 13 | OK! So we’ve put together a calendar that contains every one of the tracks on Exercism. Which was not an easy feat! I’ll walk you through what we’re going to do! 14 | 15 | ## The months 16 | 17 | So, first up we have Functional February, in which we’re exploring functional languages! We’ve just put the intro video for this together and I’m really excited to dig into this. Functional languages are super interesting and fun and teach you loads. There’s lots of functional languages but if you don’t know where to start, we’re specifically recommending trying Elixir, F# or Gleam. 18 | 19 | Next we have Mechanical March, in which we’re looking at more system-programming type languages. These are languages like C++ or Go or Nim. Things that tend to compile to machine code, might have some memory management for you to think about, or make you consider how the code is executed. Languages that get you a bit closer to the innards of what’s going on with the computer. 20 | 21 | For Analytical April we’re focussing on more sciency languages. The two big ones here are Python and Julia, but we also have a great R track. Obviously something like Python can go in lots of categories, but we think that the majority of non-beginners are learning it for its value as a data-science technology right now so we’ve put it here! 22 | 23 | May is going to be a fun one and we’ve called it Mindshifting May! We’re highlighting languages that do something different. Our favourite example of this is Prolog, which is a quite unique way to program but we’ll also be looking at Rust, TCL, and Unison - a very new language that takes a different approach to distributed programming that we’re excited and intrigued about. 24 | 25 | Into June and we’re taking a northern hemisphere approach to naming and calling this the Summer of Sexps. We’ll be exploring expression-based languages - focussing specifically on Common Lisp and Clojure, two great Exercism tracks! If you’ve never tried a Lisp, this will be a really fun month for you. And rather than being scared of the parentheses, you’ll come to appreciate them! 26 | 27 | As we move into July, we’re going old school for Jurassic July. We’re exploring old languages - those languages that have provided foundations for programming we know today. Think Fortran, COBOL, VB and C. If you’re a relative newcomer to programming, it might intrigue and shock you to see what coding used to be like! 28 | 29 | August is a month that will contain languages familiar to any of you as we focus on building websites and Apps. We’ll be looking at languages like JavaScript, Kotlin and Swift, but also some less well-used ones like Dart. We’ll also look at languages such as ABAP which are used for very specific purposes. 30 | 31 | Slimline September focusses on languages in which you can do a lot while typing very little. The sort of languages that people might use to play code golf! Think Perl, AWK, JQ and Bash. These languages can feel somewhat esoteric the first time you use them, but they are super-powerful ways to be productive if you put the effort into learning them. And also fun for your brain to explore! 32 | 33 | Month 10 is Object Oriented October. We’re exploring languages which focus heavily on Object Oriented Programming - languages like Ruby and C#, and lesser known languages like Crystal and Pharo. If you’ve always wanted to go deep into exploring OOP, this is the month for you! 34 | 35 | Our final themed month is Nibbly November - a month dedicated to the lowest level languages where you’ll be manipulating bits and bytes. We’re focussing on two languages: x86-assembly, the language that probably underpins the hardware you’re watching this on, and WebAssembly, the new kid on the block that allows you to run any programming language in your web browser. This won’t be an easy month, but will potentially be the most satisfying to achieve! 36 | 37 | Which brings us finally to December Diversions. These are the languages that we couldn’t fit anywhere else! Things like Groovy, Lua and Wren. Think of this as a wildcard month - you can choose anything you like to finish off the year in style! 38 | 39 | So that’s it - a year of new programming languages for you to explore and have fun with. Leave a comment on the video telling us what you’re excited to try! And if you’d like to stream yourself solving some exercises, please reach out to us and we’ll try to raise awareness of what you’re doing, and maybe even feature you on one of our official channels! 40 | 41 | Thanks for reading :) 42 | 43 | -------------------------------------------------------------------------------- /posts/12in23-feb-update.md: -------------------------------------------------------------------------------- 1 | Hey everyone! How’s your #12in23 going? 2 | 3 | I thought I’d put together a short update you all on what’s been going on, and how the shape of the year is evolving in our minds. 4 | 5 | So, #12in23 was just a random idea on January the 1st, where I thought “what would be a fun thing we could do to really make the most of Exercism’s platform and give people loads of fun and education through the year”. So I spiked the whole thing on January 3rd, put a video together, put it all live, and it pretty much took off. The rest of the team came back to work on the 4th and I had made a lot of work for everyone. But to be honest I hadn’t really thought much through beyond the basic idea when we launched. 6 | 7 | We came up the idea of the themed months, and that’s then evolved to include all sorts of fun stuff - especially lots of content - interviews with key people in languages, live-streaming, all sorts of stuff. 8 | 9 | I’m recording this towards the end of Functional February, and that’s gone really well. I had a great time interviewing José Valim, the creator of Elixir - if you’ve not watched that already, do check it out, and thanks for everyone who came along and joined in the AMA and the live chat. I’ve got another interview tomorrow, with Louis Pilfold, the creator of Gleam, which I’m excited about as Louis is lovely, and people are really enjoying Gleam. 10 | 11 | Thousands of people have been taking part, solving exercises, learning new languages. We’ve had some fun live-streaming sessions too. We’ve got our Functional February swag launching soon - we’ll leave it up for March as it’s come so late! - and we’ve also got a video more of the “Brief introduction to…” videos that Erik is making. He did the first one of those for F# - check it out if you’ve not already! - and he’s put another few together well that we’ll be editing and launching this week - Gleam, Scala, Haskell - maybe one other too. 12 | 13 | Erik’s been recording videos for Approaches as well. We launched approaches at the end of 2022 - sort of mini articles that you find after exercises that explore the different ways you could solve that exercise. We’ve got lots of them written across various tracks and exercises now, and also lots of accompanying videos that we’ve pulled in from the community, but Erik’s also been putting a few together specifically for the featured exercises. We’ve put a new Community YouTube channel together to hold this more “unofficial” content - see the description for a link - where we’ll be hosting videos that people make that they don’t have their own channel for. We’re also going to be putting live streams there too, alongside our official Twitch channel. 14 | 15 | If you’ve not checked the live-streaming yet, please do. We’ve had a variety of different people streaming throughout February. Some people solving exercises, some learning a language, some streaming themselves contributing to Exercism itself. If you’d like to do some live streaming on our Twitch or Community YouTube channels, ping Jonathan an email - link in the description again - and he’ll get you set up. We’re also hoping to set up some residencies - where people stream each week at a fixed time - so if you’re interested in that let Jonathan know too! 16 | 17 | We’re now getting set for Mechanical March. Erik and I are recording the video for this on Wednesday and we’ve chosen the featured exercises etc. The languages are C, C++, D - it’s like reading the alphabet - C, C++, D, Go, Nim, Rust, V and Zig - the last two both new on Exercism in the last couple of weeks. We’re hoping to get language interviews with someone from the Go team, someone from Rust and then the other languages hopefully too! 18 | 19 | We’re also creating a new badge that’s going to be quite exclusive. It’s for people who complete all of the featured exercises in a relevant language throughout the year. So for example, you’ll need to have completed the 5 exercises featured in February in a functional language, then the 5 exercises featured in March in a systems language, etc. You can do these whenever during the year, so if you come late to #12in23 that’s fine. And you’ll get awarded the badge at the end of the year. We’ll put a little status UI on the #12in23 page too - that page needs some proper work! 20 | 21 | I also want to say thank you to everyone that’s donated. I was feeling pretty down about Exercism at the end of 2022 - we had almost no-one supporting us financially and it felt pretty demoralising. The donations that have come in since the start of the year have been a massive boost to motivation and really reinvigorated me personally. I’m going to put another video together about this, but we have a long way to go still this year to get Exercism to a place where it’s sustainable, but I feel like your support has been a massive first step. So thank you all. 22 | 23 | There’s another few things we have bubbling away too. Some new additions to the website - including a strong rumour that we might finally be launching dark mode - as well as some improvements and tweaks in general. I’ll put something more information into an update in the coming weeks. 24 | 25 | Well, I think that’s me done. I’m excited to put the Mechanical March video together this week and get that launched. And also super excited for the interview with Louis tomorrow - don’t miss that! If you’ve not got your Functional February badge yet, don’t miss out! You’ve got 1 week left! 26 | 27 | Thanks for reading! 28 | -------------------------------------------------------------------------------- /posts/14-increasingly-strange-ways-to-solve-hello-world.md: -------------------------------------------------------------------------------- 1 | ## Introduction 2 | 3 | _For the purpose of this article, all the code will be in Python._ 4 | 5 | In their [#48in24 challenge](https://exercism.org/challenges/48in24), Exercism are exploring how the community approaches different coding challenges. 6 | "Hello, World!" is the most basic exercise on Exercism and was deemed too simple to make an official video for. 7 | But I'm not so sure, and thought it might be fun to look at some more interesting approaches to this simple exercise! 8 | 9 | ## Meet "Hello, World!" 10 | 11 | "Hello, World!" is probably the most famous program in the world. 12 | Virtually anybody who's learned to code has written it at least once. 13 | Its simplicity and the friendly message often signify the first step into the wonderful world of programming. 14 | 15 | On Exercism, you are provided with a function named `hello` that returns "Goodbye, Mars!". 16 | 17 | ```python 18 | def hello(): 19 | return 'Goodbye, Mars!' 20 | ``` 21 | 22 | Your task is to change it to return "Hello, World!" instead. 23 | 24 | ## The Traditional Approach 25 | 26 | First up, we have the most simple approach, and the one Exercism hopes you'll implement. 27 | With just a simple change of the string from "Goodbye, Mars!" to "Hello, World!", we can now safely return it! 28 | 29 | ```python 30 | def hello() -> str: 31 | return 'Hello, World' 32 | ``` 33 | 34 | ## Alternative Approaches 35 | 36 | I'm going to solve this exercise using all the various methods that I could think of. 37 | 38 | For narrative purposes, I will refer to this simple function as the "machine", a machine whose only job is to return a "Hello, World!" greeting. 39 | 40 | Let's see where this goes...! 41 | 42 | ### The Join 43 | 44 | The machine already knows some of the words, but it can't seen to string ah, eg, well, string them together. 45 | 46 | ```python 47 | def hello() -> str: 48 | words = ["Hello", " world!"] 49 | return ",".join(words) 50 | ``` 51 | 52 | ### The Title 53 | 54 | The machine's battery is a bit low today as all the words are lacking energy and are not being capitalized properly. 55 | 56 | ```python 57 | def hello() -> str: 58 | words = "hello, world!" 59 | return words.title() 60 | ``` 61 | 62 | ### The Reversal 63 | 64 | The machine somehow knows the greeting, but something about it looks a bit ..backward. 65 | 66 | ```python 67 | def hello() -> str: 68 | sdrow = "!dlroW ,olleH" 69 | return sdrow[::-1] 70 | ``` 71 | **Note:** [`Reverse String`](https://exercism.org/exercises/reverse-string) is a featured exercise for the #48in24 challenge. Remember to check out various approaches of how to do it in different languages! 72 | 73 | ### The Slice 'n Dice 74 | 75 | Maybe the machine needs to have its oil changed as the normal greeting message seems to be a bit mixed up. 76 | 77 | ```python 78 | def hello() -> str: 79 | w = "Holld, Werlo!" 80 | return f"{w[0]}{w[8]}{w[2:4]}{w[1]}{w[5:8]}{w[-2]}{w[-4:-2]}{w[4]}{w[-1]}" 81 | ``` 82 | 83 | ### The Curry 84 | 85 | Oh oh, some parts of the machine are in maintenance mode. 86 | It forgot the greeting message and can now only accept the message part by part. 87 | 88 | ```python 89 | def hello(greet: str): 90 | def world(location: str) -> str: 91 | return f"{greet}, {location}!" 92 | return world 93 | 94 | hello = hello("Hello") 95 | hello("World") 96 | ``` 97 | 98 | ### The ASCII 99 | 100 | You accidentally spilled some lemonade on the machine and now it only shows you these strange numbers instead of the usual characters in the message. 101 | 102 | ```python 103 | def hello() -> str: 104 | ascii = [72, 101, 108, 108, 111, 44, 32, 87, 111, 114, 108, 100, 33] 105 | return ''.join(chr(value) for value in ascii) 106 | ``` 107 | 108 | ### The Dictionary 109 | 110 | You watched the news and saw a snippet about a man being rescued using an S.O.S signal. 111 | "Maybe the machine should be able to handle Morse code as well!" - you thought, but you are not sure why. 112 | Its only job is to return the greeting message... 113 | 114 | ```python 115 | def hello(morse) -> str: 116 | morse_code = { 117 | "...." : "H", 118 | "." : "e", 119 | ".-.." : "l", 120 | "---" : "o", 121 | "--..--": ",", 122 | "/" : " ", 123 | ".--" : "W", 124 | ".-." : "r", 125 | "-.." : "d", 126 | "-.-.--": "!" 127 | 128 | } 129 | return "".join(morse_code[value] for value in morse.split()) 130 | 131 | print(hello(".... . .-.. .-.. --- --..-- / .-- --- .-. .-.. -.. -.-.--")) 132 | ``` 133 | 134 | ### The Functional 135 | 136 | With your current machine prone to changes and damage, you decide to build a smaller but immutable and indestructible machine that does the exact same thing. 137 | Whenever the regular machine is not working or acting up, it will activate the smaller one instead. 138 | Hang on, why don't we just use the smaller on from now on.. 139 | 140 | ```python 141 | def hi() -> str: 142 | return "Hello, World!" 143 | 144 | def hello() -> str: 145 | return hi() 146 | ``` 147 | 148 | ### The Permutation 149 | 150 | A strong thunderstorm passed by and your poor unlucky machine got struck by lightning. 151 | It still powers up, but now it is acting weird. 152 | All the characters to assemble the greeting message are still there, but they are not in order and the damage to the logic board means the machine can't get the order for the message right anymore. 153 | And just your luck, the incredibly reliable and *indestructible* smaller machine you built earlier was in fact stealable (yes, it's gone!). 154 | Therefore, you decide to just let your good ol' buddy try every possible way to scramble these letters into the correct message. 155 | After all, it is only 13 characters and the machine has a lot of memory. This should be quick... 156 | 157 | ```python 158 | from itertools import permutations 159 | 160 | def hello() -> str: 161 | chars = ['H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!'] 162 | 163 | all_permutations = permutations(chars) 164 | for perm in all_permutations: 165 | if ("".join(perm) == "Hello, World!"): 166 | return ''.join(perm) 167 | ``` 168 | 169 | ### The Search 170 | 171 | You decided to update the machine to allow it to greet in different languages. 172 | But its ONLY job is to say "Hello, World!" in English, so in its confusion it decides to download a bazillion ways of saying "Hello, World!", each with slightly different capitalized characters and placement. 173 | That left you confused and not sure which one to pick, but at least they are all in some sort of order. 174 | You have to tell the machine the correct way to phrase it, so it can find the phrase and be normal again (maybe). 175 | 176 | ```python 177 | def hello(my_fav_phrase) -> str: 178 | combinations = [ 179 | "HELLO, WORLD!", 180 | # many many many items later, 181 | "hello, world!" 182 | ] 183 | 184 | lower = 0 185 | upper = len(combinations) 186 | while lower <= upper: 187 | mid = (lower + upper) // 2 188 | mid_val = combinations[mid] 189 | 190 | if mid_val == my_fav_phrase: 191 | return combinations[mid] 192 | elif mid_val < my_fav_phrase: 193 | lower = mid + 1 194 | else: 195 | high = mid - 1 196 | return "Error: Can't find {my_fav_phrase}" 197 | 198 | hello("Hello, World!") 199 | ``` 200 | 201 | Your younger brother, who has been watching the whole thing, asked why you didn't just delete the whole mess and then give the machine the correct phrase for it to remember. 202 | You didn't reply and just glared at him. 203 | 204 | ### The Classy 205 | 206 | You decide to experiment and tweak the machine to behave differently based on what button is being pressed. 207 | You thought about making it a bit more casual, starting to say "Hi", but being a *classy* person, you decide to only ever use the `hello` method and tape over the other one. 208 | You realize you have quite a lot of time on your hands for these things.. 209 | 210 | ```python 211 | class Greeting: 212 | location = "World" 213 | 214 | def __init__(self) -> None: 215 | pass 216 | 217 | def hello(self): 218 | return f"Hello, {self.location}!" 219 | 220 | def hi(self): 221 | return f"Hi, {self.location}!" 222 | 223 | salutation = Greeting() 224 | salutation.hello() 225 | ``` 226 | 227 | ### The Recursion 228 | 229 | For some reason, you decided it would be funny if the machine lagged a bit and would only respond 10 seconds late. Your brother once again raises the question about the logic behind this feature, because according to him, you are the only one who uses the machine. 230 | 231 | ```python 232 | import time 233 | 234 | def hello(n=10): 235 | if n == 0: 236 | return "Hello, World!" 237 | else: 238 | time.sleep(1) 239 | return hello(n-1) 240 | ``` 241 | 242 | ### The Randomness 243 | 244 | Suddenly, one day you just feel tired of the same greeting over and over again, so you decide that you would let it greet you one last time and retire the machine for good, never to touch it again. 245 | As the machine has been with you through thick and thin and for a long time, you decide to let this final meeting between "friends" be in the hand of fate. 246 | You power it up one last time and just let it spin... 247 | 248 | ```python 249 | import random 250 | 251 | def hello(): 252 | chars = list("Helo,Wrld!") 253 | greeting = "" 254 | while (greeting != "Hello, World!"): 255 | greeting = "".join(random.choices(chars, k=13)) 256 | return greeting 257 | ``` 258 | 259 | ### The End 260 | 261 | That was a wild tour through my mind. 262 | I'm not sure it was useful, but it was definitely fun. 263 | 264 | Thanks for reading and happy coding! 265 | -------------------------------------------------------------------------------- /posts/announcing-exercism-research.md: -------------------------------------------------------------------------------- 1 | In August, we [announced our partnership](https://exercism.io/blog/redesigning-tracks-in-partnership-with-chicago-university-and-sloan-foundation) with James Evans and Gary Lupyan to carry out research into how people's programming experience affects how they learn languages. 2 | 3 | We spent some time earlier this month meeting with James and Gary and planning out how we achieve some of their wider research goals alongside the redesign of Exercism tracks I discussed in the [previous post](https://exercism.io/blog/redesigning-tracks-in-partnership-with-chicago-university-and-sloan-foundation). It was clear that there are many areas where Exercism will be able to help their research but that those might not fit directly into core Exercism product. We have therefore decided to create a new area of Exercism specifically centred around research, called (unimaginatively) Exercism Research. This subsite will host experiments that aim to gather data on a specific research goal. The experiments will also have the added benefit of allowing us to test out new technology on a less critical area of the site. 4 | 5 | The first experiment, which we aim to launch in the first week of January, will be centred around investigating how someone's previous programming experience impacts the reusability of the code they produce in different languages. The experiment will be structured as followed: 6 | - Users will be asked to complete a short survey outlining their programming experience (e.g. the languages they know, the order they learnt them, and their fluency in each). 7 | - Users will then be presented with a choice of X languages to participate in. It does not matter how well the user knows the language(s) they choose - a variety of previous knowledge will help the breadth of data gathered. 8 | - The user will be given an exercise to complete, which should take 10-15 minutes. 9 | - The user will then be given someone else's solution to a different exercise, and asked to extend it in a certain way. This should also take 10-15mins. After each step we will ask the user questions about how difficult they found the exercise/extension. 10 | 11 | Gary and James' teams will then crunch the data, investigating how the code submitted differs based on different backgrounds, and on how extensions changed based both on the initial submitter's background, and the extender's background. 12 | 13 | This experiment will be the first testbed for our new in-browser coding before that is integrated into the main site in 2020. We hope to have 5-10 languages that participate in the experiment. To take part a track will need to have a functional test-runner, and two exercises for the two parts, which we will help maintainers create. If you are a maintainer and interested in your language being part of this, please join the #experiment-1 channel on Slack and let us know. 14 | -------------------------------------------------------------------------------- /posts/automated-mentoring-support-project.md: -------------------------------------------------------------------------------- 1 | _Update: We're excited to announce that Mozilla have awarded us an Open Source Support Award for this project. You can [read more here](https://exercism.io/blog/mozilla-supports-exercism-static-analysis)._ 2 | 3 | This blog post marks the start of [Exercism's](https://exercism.io) **Automated Mentoring Support Project**, in which we will develop a framework that programmatically analyzes users' solutions in order to improve the feedback loop for learners and reduce the burden for mentors. Our aim in the short term is to automatically approve solutions that meet given acceptance criteria and provide feedback for commonly-seen improvements. 4 | 5 | The purpose of this post is to describe the problem we're trying to solve and the high-level plan for how we'll be tackling it over the next few months. We'll be following up with further posts which dig into the background of the problem and the history of automated analysis on Exercism, as well as more details about our implementation strategy. 6 | 7 | ## Why automated mentor support? 8 | 9 | Exercism's most significant barrier is being able to deal with scale. 10 | 11 | Our volunteer-mentors are crucial to Exercism’s success. They are responsible for reviewing learner’s solutions, analyzing whether they meet the success criteria of the exercise or need to be improved, empathetically understanding a learner’s thought process, providing encouraging and helpful feedback, and coaching people in a language’s idioms. Today, we are just about managing to keep up with the mentoring demand. If we want to grow, we need a better strategy than "add more mentors." 12 | 13 | For the core exercises that form the spine of an Exercism language track, we estimate that about 25% of submissions are good enough to be marked as complete on a first attempt. A further 55% of submissions have problems that fall into common buckets, which can be mentored by copy/pasting feedback snippets. Only about 20% of solutions require a mentor to be inventive and thoughtful in their feedback. 14 | 15 | The 80% of solutions that do not genuinely engage a mentor’s brain are a frustrating time-sink for people who are willing to volunteer their time helping others, and do not make the most of their expertise. 16 | 17 | Similarly, a learner might wait anywhere between a day and a week before receiving feedback and is unable to move forward on the track in the interim. For those who have submitted an iteration that falls within the 25% of perfectly valid solutions, this delay is exceptionally frustrating. To the remainder, it is suboptimal at best. Learners often lose momentum due to this delay and become frustrated at the process. 18 | 19 | By developing a system that can automatically analyze a solution and either approve it or provide stock feedback to known issues, we estimate we will be able to dramatically reduce mentors' workload by eliminating the "boring" parts, while significantly improving a learner's experience. As an added bonus, people will receive more consistent feedback when it comes to structural and stylistic questions, which sets them up to have more interesting conversations about the less clear-cut topics. 20 | 21 | ## How will it work? 22 | 23 | Our long-term goal is to develop deep-learning algorithms that can analyze the Abstract Syntax Trees (ASTs) of the nearly one million submissions that have been submitted since Exercism first launched in 2013. Such a tool might detect common patterns and related comments by mentors. In the near term, our goal is to use [static analysis](https://en.wikipedia.org/wiki/Static_program_analysis) to determine what feedback can be given based on the most commonly repeated errors seen by mentors. 24 | 25 | The project breaks down into roughly the following areas: 26 | 1) **Product changes:** We need to work out how this automated analysis fits with the current mentoring UI, how we communicate this feedback (system messages, a "bot," etc.), and then implement this for the Exercism website. 27 | 2) **Infrastructure:** We will design and build infrastructure that can efficiently support running static analysis across multiple languages. 28 | 3) **Static analysis prototype:** Develop a sample analyzer that will auto-approve good solutions to Ruby / Two-fer, and document this process so that the wider community can contribute. 29 | 30 | We aim to launch the initial prototype by mid-2019. Once we have the foundations in place, we expect to extend this to other languages than Ruby, and other exercises than Two Fer. While we won't have the framework in place to integrate other languages and exercises into the website until we've made progress on the prototype, if you want to start writing analyzers for your favorite languages and exercises, there's no reason to wait! Open an issue on [the GitHub repo for this project](https://github.com/exercism/automated-mentoring-support) and tell us what you're interested in doing. 31 | 32 | We are very excited to work with others in the Exercism community who have already been using static analysis to help with mentoring, such as 33 | [tehsphinx](https://exercism.io/profiles/tehsphinx) and [bitfield](https://exercism.io/profiles/bitfield) who have developed a [static analysis tool](https://github.com/tehsphinx/exalysis) for mentors on the Go track. The way that it has taken the track from having a massive backlog to being one of the most responsive language tracks on Exercism shows how impactful automated mentor support can be. 34 | 35 | Over the next few weeks, we'll be outlining more about these first key steps and how things will work. 36 | 37 | We'd love to answer any of your questions in the comments section below! :) 38 | -------------------------------------------------------------------------------- /posts/bootcamp.md: -------------------------------------------------------------------------------- 1 | # Bootcamp 2 | 3 | Hi everyone! 4 | 5 | I'm really excited to let you know that from January 2025, we're going to be running a **[Learn to Code Bootcamp](https://bootcamp.exercism.org)**! 6 | 7 | ## Some background 8 | 9 | I've been wanting to help total beginners for a long time. 10 | As I mentioned in the "[2M users but no money in the bank](https://exercism.org/blog/september-2024-restructure)" blog post in September, 11 | over 95% of people who try to learn to code give up, which I find unacceptable. 12 | 13 | We're building a new platform that will sit alongside Exercism which is going to be dedicated to beginners, which we'll be launching in mid-2025. 14 | We've already put a lot of effort into this and I'm really proud of how it's evolving. 15 | I'll be talking a lot more about it in the coming months. 16 | 17 | But before launching that, we're going to run a 6 month bootcamp, that will use some of the technology we're building. This will allow me to get super-close to students' learning experience, to refine and develop the platform as real people learn from it, and help me understand where students get stuck, and work out how to help them further. 18 | 19 | ## Some details 20 | 21 | The bootcamp will be in two parts: 22 | 1. Learn to code 23 | 2. Learn front-end web dev 24 | 25 | Students can take just the first part (3 months from Jan-March) or the whole course (6 months from Jan-July). 26 | I may also just offer the second part later, for existing developers who want to learn some web development skills. 27 | 28 | The bootcamp is remote, part-time, and priced as cheaply as possible, with 29 | pricing parity available along with discounts for students and those who are currently unemployed. 30 | 31 | The whole focus is on learning through doing. 32 | Like Exercism, people will learn by coding lots. 33 | We're going to start with smaller exercises and evolve into bigger projects. 34 | This is how I learnt 3 decades ago, and I strongly feel that learning by doing is the best way for a brain to really build an intuitive and natural understanding of how to do something. 35 | 36 | Rather than me regurgitating everything, it's probably best to scroll through the **[Bootcamp website](https://bootcamp.exercism.org)** for all the details! 37 | 38 | There are two ways that you can help! 39 | 40 | ## Help by spreading the word 41 | 42 | The biggest thing you can do to help is to encourage everyone you know to come and join! 43 | 44 | I've written many times about how valuable I think learning to code is for pretty much everyone today. 45 | Even if you don't want a career in tech, coding is a great skill to have. It nurtures critical thinking skills, helps you understand how so much of the world worlds, and, with the power of LLMs, it's increasingly easy for people to piece together different little bits of code to do useful things. 46 | 47 | We're setting up an affiliate scheme where your friends or followers can get a 20% discount, and you get a 20% "commission" on the sale (which you can choose not to take to support Exercism if you prefer!) 48 | If you're interested in this, please [let me know](mailto:bootcamp@exercism.org). 49 | 50 | Lifetime Insiders will also get one free ticket to use for a friend or to give away as they see fit. 51 | I'll contact Lifetime Insiders seperately! 52 | 53 | ## Help by mentoring 54 | 55 | Exercism works best when the community comes together to make things possible that would be impossible individually! 56 | 57 | One of the areas I'd love your help with is in supporting our bootcamp students by answering their questions and helping them get unstuck - similar to the support that happens currently on Discord and the forum, but in a more ordered way. 58 | 59 | We're going to be taking a very specific approach to learning, where we introduce concepts in a specific order and let the students internalize the ideas through lots and lots of practice. 60 | We'll rely heavily on the [Lie to children](https://en.wikipedia.org/wiki/Lie-to-children) methodology, to ensure people don't get overwhelmed or drawn into areas that will complicate matters. 61 | 62 | If you would be interested in supporting/mentoring total newbies and are happy with the "Lie to Children" approach and working within the framework we're building, then I'd love to hear from you (please email me at [bootcamp@exercism.org](mailto:bootcamp@exercism.org)!). 63 | 64 | ## Conclusion 65 | 66 | I'm really, **really** excited for this. 67 | I hope it'll help a ton of people, help us refine a product I've passionate about, and bring a little money into Exercism to keep us afloat. 68 | It feels like a win win win. 69 | 70 | I'll be talking lots more about it over the next few months, but in the meantime, I'd massively appreciate your support in spreading the word and generating some hype! 71 | 72 | Thanks for reading 🙂 73 | -------------------------------------------------------------------------------- /posts/call-for-maintainers-2020.md: -------------------------------------------------------------------------------- 1 | **We're looking for new Track Maintainers. Interested? Read on!** 2 | 3 | Exercism is powered by the energy of many volunteers, especially the [track maintainers](https://exercism.io/team/maintainers) who are responsible for creating and managing our Language Tracks. 4 | 5 | We're about to start a big push towards version 3 (v3) of Exercism. Getting all the tracks ready for v3 is going to be a big community effort, and we're looking to add more maintainers to oversee and manage that task. 6 | 7 | In the push to v3, our maintainers will be responsible for: 8 | - **Designing the track:** Working out what someone needs to learn to become fluent in a language, and mapping this out as a pathway. 9 | - **Decision making:** Making design decisions around the tooling the track uses, the standards it conforms to, the defaults it uses, etc. 10 | - **Encouraging and supporting contributions:** Providing a welcoming environment for people that want to help out, answering their questions, etc. 11 | - **Reviewing PRs:** A lot of the actual work of building out v3 tracks will be done by the community. Maintainers act as gatekeepers, reviewing the work that the community does and ensuring the track's standards are enforced. 12 | 13 | This might all sound a bit daunting but with the work spread between a team of maintainers, individuals can do the bits that they feel best equipped for. Our more experienced maintainers will also help you get started and hold your hand as you learn the ropes. 14 | 15 | To be able to do the role you will: 16 | - Be able to commit an average of 3 hours per week (preferably spread over the week) for about 6 months. We know that life ebbs and flows though so fully understand that some weeks might work better than others for you to contribute. 17 | - Have used Exercism. 18 | - Preferably have contributed to Exercism - either as a mentor or having contributed to the codebase. While this isn't an absolute requirement, we find our maintainers enjoy the process more if they have some existing experience with Exercism. 19 | 20 | Maintainers are volunteers so don't get paid. The key motivation will ideally be you wanting to help people develop their programming skills, and help a non-for-profit organisation. Being an Exercism maintainer is also a great opportunity to work with some other smart people, learn more about your language of choice, and gain skills and experience that are useful for growing your career in the technical leadership direction. It also looks pretty good on a resume. 21 | 22 | If you're interested in becoming a maintainer, we'd love to hear from you. There is an issue on GitHub for each live track, where you can post a comment introducing yourself. You can find a [list of the issues here](https://github.com/exercism/exercism/issues/5161). 23 | -------------------------------------------------------------------------------- /posts/community-tab.md: -------------------------------------------------------------------------------- 1 | Exercism is all about community. Without our volunteers, mentors, and everyone that helps and supports our students, we'd be nothing. Yet, we always feel like we're just scratching the surface of all our community has to offer, and all we have to offer our community. 2 | 3 | So from today we're starting to focus more heavily on community, launching various initiatives to help bring our community together better and maximise the value of everything you all create! 4 | 5 | We’ve added four new parts to Exercism - and they all live under the new [Community tab](https://exercism.org/community). 6 | 7 | ## Forum 8 | 9 | For a long time we’ve wanted to add a forum, but not had the person-power to manage it. Now, after hiring Jonathan - our new community manager - we feel we have the resource to make it work. 10 | 11 | Our forum is split into four category: 12 | **Exercism:** A space to discuss everything Exercism - the product, plugins, mentoring, volunteering, and anything else you can think of. 13 | **Exercism Support:** A space for people to get support and help if they get stuck using Exercism or solving an exercise. Post-solving mentoring should still go through the normal mentoring UI, but this adds a layer before for when you struggle to get an exercise over the line. 14 | **Programming:** A general space to explore programming, specific languages, or questions/ideas around any of our exercises. 15 | **Social:** Finally we have a dedicated space to chat, ask questions, and get to know each other better. 16 | 17 | This is our first stab at how we feel a forum can work for Exercism, and it’s something we’ll definitely evolve over time. For now we’re using a pretty vanilla [Discourse](https://www.discourse.org/) installation, but eventually hope to bake the conversations into Exercism itself. If you’ve got suggestions about how we can evolve or improve the forum, open a new topic in the Exercism category! 18 | 19 | Finally on this, we’re really committed to making this forum a fun, safe, non-toxic space, and so we’ve put [Community Guidelines](https://forum.exercism.org/faq) in place to guide everyone to the type of interactions we’re desiring. We’re going to enforce these relatively strictly so please do take time to read them before posting. Thanks 🙂 20 | 21 | You can visit the forum at [https://forum.exercism.org](https://forum.exercism.org). 22 | 23 | ## Dig Deeper 24 | 25 | There’s a huge amount of knowledge about how to solve exercises locked in our community’s brains. Some of it is used be mentors to help students, some by maintainers when designing exercises, and some gets turned into walkthroughs and exploratory videos. Well now we’re bringing all that knowledge together into our new Dig Deeper section. 26 | 27 | Over the next few weeks, you’ll start to see the Dig Deeper tab appearing across exercises, with notes from mentors and maintainers, and walkthroughs that we’ve found on YouTube. And if you create your own walkthrough videos, we’ll happily incorporate it into the site. Either click the Add Video link on the Dig Deeper tab, or email [Jonathan](mailto:jonathan@exercism.org) and he’ll help you out! 28 | 29 | ## Community Stories 30 | 31 | We’ve got a community full of amazing people with amazing stories, and so we’re creating a space for those stories to be told. We’ll be releasing a new series of interviews with the community, both for YouTube and later for podcasting services, where you can get inspired and motivated listening to the technical journeys of others. 32 | 33 | If you’ve got an interesting story to tell, then email [Jonathan](mailto:jonathan@exercism.org) and we’ll see if we can feature it! 34 | 35 | [Subscribe on YouTube](https://www.youtube.com/c/Exercism-videos?sub_confirmation=1&feature=subscribe-embed-click) to make sure you don’t miss any of our videos! 36 | 37 | ## Swag 38 | 39 | Last but not least, we’re finally adding an Exercism Swag Store. This is something we’ve been wanting to do for years, but we wanted to make sure we had the time to do it well and ensure the quality of merchandise was up to scratch. Well, we’ve put some designs together, ordered some samples, and we’re really pleased with what we’ve got! 40 | 41 | We’ve tried to price Swag as close to cost as possible so that everyone can get some, but we’ve also added “Donation items” that you can add to your basket to help support Exercism. If you do have the ability to support us, please do - it’s only through your donations that we can do things like hire Jonathan and build tools to support our community further - so please do help out if you can! 42 | 43 | You can explore the swag store at [https://swag.exercism.org](https://swag.exercism.org). 44 | 45 | ## Final thoughts 46 | 47 | I’m really excited to start growing and nurturing our community more deliberately. Thank you to everyone that’s helped us get to this stage and tested things over the last few weeks - you’re all superstars 💖 48 | 49 | -------------------------------------------------------------------------------- /posts/contribution-guidelines-nov-2023.md: -------------------------------------------------------------------------------- 1 | _If you’re being pointed here from an automatically closed Issue/PR, please don’t panic or feel rejected. More often than not any work you’ve done will eventually be merged into Exercism, or your problem will be solved. We welcome and encourage contributions, but like to discuss things on our forum before jumping into code on GitHub. Opening a forum thread will move things forward._ 2 | 3 | --- 4 | 5 | For the last year, we’ve been experimenting with limiting contributions from non-maintainers in order to free up our core contributors time and allow them to make more significant improvements to tracks. 6 | This has worked pretty well. 7 | Compared to 2022, during 2023 we’ve **seen double the amount of new exercises added and three times the amount of syllabuses created.** 8 | The change of methodology has allowed for much larger contributions, less frustration and less distraction for our core contributors. 9 | 10 | However, I’m also aware that it’s created frustrations for new contributors who are committed to helping out, but feel blocked by our contribution process. 11 | So today, I want to put forward some new (or clarified) guidelines for how we’re going to move forward with contributions during the next few months. 12 | 13 | The fundamental rule to make sense of is that **we discuss ideas, bugs and issues on our forum and that we discuss the resulting changes to code on GitHub (in PR reviews).** 14 | The secondary rule is that (with the exception of maintainers who are autonomous) we discuss things before we do things. 15 | Our forum allows contributors and maintainers across tracks to share knowledge and wisdom on a wide range of languages and ideas without needing to subscribe to 300 different repositories on GitHub and overwhelming their notifications. 16 | 17 | ## Updated Guidance 18 | 19 | ### Getting support 20 | 21 | - If you are stuck on anything before solving an exercise (e.g. installing the CLI, running tests, stuck on the logic/requirements of an exercise), our support mechanisms are our “Exercism Support” category on the forum and the #get-help channel on our Discord server. 22 | - We do not use GitHub or email for support requests. 23 | - If you have solved an exercise but have questions about it, you should request mentoring on Exercism itself. 24 | 25 | ### Reporting bugs/issues 26 | 27 | - All bugs/issues should be opened on our forum where a wide range of people can help understand and solve the problem. 28 | - If the issue is to do with a language, please use the relevant Programming/xxx category. 29 | - If it’s a bug on the website, please use the “Bugs & Feature Requests” category. 30 | - GitHub issues will generally be automatically closed and the poster redirected to the forum (with a one-click link to copy/paste their issue, as is currently the case). 31 | - Track maintainers can choose to turn the auto issue-closer off, but the official pathway is still the forum. 32 | 33 | ### Opening Pull Requests 34 | 35 | - Pull Requests should be discussed on the forum before the work is done. 36 | - Pull Requests from non-org members will continue to be automatically closed, but will often be reopened once the work has been discussed on the forum. 37 | If the idea behind a PR has already been approved, please just add a link to the PR on the relevant forum thread and we’ll reopen it. 38 | - Track maintainers can choose to turn the auto PR-closer off, but we still recommend that all PRs are first discussed via the forum. 39 | 40 | ## Summary 41 | 42 | Our first priority remains protecting the time and mental capacity of our core contributors, without whom Exercism cannot operate. 43 | But we also want to ensure that Exercism remains a place where new people can get involved without overly prohibitive barriers, and where we can encourage and support those people to become core contributors themselves! 44 | 45 | I’m excited to see how these changes affect the contributions we see over the next few months. 46 | We’ll review things again in mid-2024. 47 | -------------------------------------------------------------------------------- /posts/dig-deeper.md: -------------------------------------------------------------------------------- 1 | Solving an exercise on Exercism is just the first step. 2 | The real learning comes next! 3 | 4 | This week we've launched the new "Dig Deeper" tab on exercises - designed as a way to help you go beyond the solving stage and explore the nuances and tradeoffs of an exercise, without needing to ask a mentor. 5 | 6 | ## Introduction 7 | 8 | The solutions to our exercises vary phenomenally. 9 | The most basic "proper" exercise in most tracks is `TwoFer`. 10 | A typical solution looks like this (this is Ruby, but it's similar for most langauges): 11 | 12 | ```ruby 13 | module TwoFer 14 | def self.two_fer(name='you') 15 | "One for #{name}, one for me." 16 | end 17 | end 18 | ``` 19 | 20 | However, out of the most recent 500 solutions that passed the tests, over 350 of them were unique 😲 21 | And even when you normalise things like whitespace and variable names, over half will still be actual unique solutions. 22 | 23 | Which makes it utterly fascinating to explore how everyone is solving things. 24 | But it's also entirely impractical. There are millions of solutions on Exercism and reading them all would quite literally take a lifetime. 25 | 26 | However! Having designed the exercises, and mentored hundreds of thousands of people through them, our team have a pretty good idea of the different approaches people take. 27 | So we've added the new Dig Deeper tab to highlight the different idiomatic (or non-idiomatic, but interesting) ways that an exercise can be solved. 28 | 29 | ## An example 30 | 31 | Let's take an example to show this in action. 32 | In C# there are various ways you can reverse a string. 33 | 34 | You can use the `Array.Reverse()` method: 35 | ```csharp 36 | var chars = input.ToCharArray(); 37 | Array.Reverse(chars); 38 | return new string(chars); 39 | ``` 40 | 41 | Or use a shorter, LINQ-based approach: 42 | ```csharp 43 | return new string(input.Reverse().ToArray()); 44 | ``` 45 | 46 | or use a `StringBuilder`: 47 | ``` 48 | var chars = new StringBuilder(); 49 | for (var i = input.Length - 1; i >= 0; i--) 50 | { 51 | chars.Append(input[i]); 52 | } 53 | return chars.ToString(); 54 | ``` 55 | 56 | or even go slightly less idiomatic (but more performant!) and use `Span`: 57 | 58 | ```csharp 59 | Span chars = stackalloc[input.Length]; 60 | for (var i = 0; i < input.Length; i++) 61 | { 62 | chars[input.Length - 1 - i] = input[i]; 63 | } 64 | return new string(chars); 65 | ``` 66 | 67 | We call each of these an Approach, and each has its own separate article explaining it. 68 | The Dig Deeper page for this exercise brings those together, and also comes with an article on performance that explores the tradeoffs. 69 | 70 | [👉🏾 Check it out](https://exercism.org/tracks/csharp/exercises/reverse-string/dig_deeper) (you will need to go incognito if you've not solved the exercise yet) 71 | 72 | ## But there's more! 73 | 74 | As well as having documents on these different approaches, there are thousands of videos that our community have produced exploring exercises, recording walkthroughs or streaming coding sessions, and diving into the depths of what makes idiomatic solutions. 75 | We're collating all those videos and bringing them onto the pages. 76 | 77 | ## Get involved 78 | 79 | Over the next few weeks, you’ll start to see the Dig Deeper tab appearing across exercises around the site. 80 | 81 | If you'd like to contribute an Approach, an exercise article, or tell us about your videos so we can add them, get in touch with [jonathan@exercism.org](mailto:jonathan@exercism.org) and he'll help you get started. 82 | 83 | And finally, tell us what you think and post your ideas and thoughts [in the forum post](https://forum.exercism.org/t/its-time-to-dig-deeper/459)! 84 | -------------------------------------------------------------------------------- /posts/exercism-in-2019.md: -------------------------------------------------------------------------------- 1 | 2019 is here and we're **really** excited about what we're going to achieve with Exercism. I wanted just to outline a few high level things that are on our radar to give people an idea of what we're focussing on. 2 | 3 | There are 4 key high-level objectives we have for this year: 4 | 1) Make mentoring as fun and rewarding as possible 5 | 2) Improve a learner's journey with improved structure and more/better content. 6 | 3) Make a bigger deal of our community and highlighting people's huge contributions 7 | 4) Explore how we can expand Exercism (or build something in partnership to it) to reach total beginners 8 | 9 | Exercism is about to hit 250,000 members and is growing faster than ever. That means more solutions submitted, which could result in more pressure on mentors, slower response times, and more frustration for learners. We are also still currently *only* growing by word-of-mouth and trying to keep Exercism on the down-low. By the end of this year, we want to be close a point where we *can* shout about what we're doing and be able to cope with the demand. Even a small amount of marketing would realistically result in 50k submissions/day, which means we need excellent systems/people in place to cope. And we want to thrive, not just cope. 10 | 11 | Achieving this is going to involve a mixture of clever technology (e.g. automatic analysis of solutions to recommend common improvements), tooling (e.g. mentor notes, cleverer mentor dashboard), content (e.g. articles on different approaches to a solution), expectation-management (e.g. estimated time to mentoring), community management (e.g. giving people a place to help get each other unstuck - forums?) and ensuring that our mentors/maintainers/contribute are energised by Exercism not burned out by it. And this in parallel with dealing with the 300 or so open issues that already exist :) 12 | 13 | In order to manage all this, we need to take Exercism from being a website to being an organisation. We need people working on Exercism full-time and need money to spend on things like servers. We have started this process by incorporating Exercism as a non-for-profit company and applying for a handful of grants. We are planning to invest a lot of energy into getting this part really right, being super-transparent to the community, making sure people's voices are clearly heard, and building an organisation that we are really proud of. 14 | 15 | One thing that we feel very strongly about is that we want to get there correctly more than we want to get there quickly. Exercism is a large, complex and ambitious project with dozens of repositories, over 3,000 contributors, and a complicated and long-term set of goals. In order to achieve its potential (and for us to not burn out on the way) we need to take the time to make the right decisions and to ensure that we carry everyone with us as we go. I know that sometimes things can feel slow and that seemingly easy solutions aren't implemented quickly but please know that that is not because we don't care, but because we care so much and so want to ensure we get things right. 16 | 17 | Over the next few weeks, I'm going to be posting a few more updates about our near-future plans for how we address some of the things I've mentioned. In the meantime, I just want to thank you for reading this and for being part of Exercism. We are passionate about giving people opportunity through learning and improving their programming skills, and we are so grateful you're here as part of this journey. Thank you! 💙 18 | -------------------------------------------------------------------------------- /posts/exercism-io-is-now-exercism-org.md: -------------------------------------------------------------------------------- 1 | # Exercism has moved to exercism.org 2 | 3 | ## Exercism has a new home at exercism.org! 4 | 5 | For the last 8 years Exercism has lived at exercism.io and we decided it was time for a change! 6 | 7 | If you're interested, here are a few of the reasons why we made this decision. 8 | 9 | Primarily, we feel that the `.org` domain better represents what Exercism is. 10 | Most new projects begin with finding whatever domain is available, and `.io` was a nice fit as it's often associated with I/O. 11 | But as we've grown, evolved, and become a larger platform, we've felt for a while that it was time for a more "official" seeming domain. 12 | We own `exercism.com`, `exercism.net`, and a few others, but we feel that `exercism.org` best represents our not-for-profit mission and gives the best first impression. 13 | As we also look to raise donations from both our community and from organisations, we felt that the more professional `.org` also offers more trust, especially as our name can sometimes give a slightly jarring first impression… 14 | 15 | Secondly, being on an `io` domain gives a little less safety than using one of the original TLDs. 16 | Back in 2017 the [io authoritative nameservers were compromised](https://thehackerblog.com/the-io-error-taking-control-of-all-io-domains-with-a-targeted-registration/) using a pretty trivial method, and while mistakes happen and things were quickly rectified, this isn't the sort of thing that's going to happen to `.org` domains. 17 | We've also had sporadic issues with DNS resolving, with people being unable to access the site. 18 | We've never been able to track this down exactly, but our best understanding is that something occasionally goes wrong at the `.io` level, rather than the AWS level. 19 | 20 | There are also some questions about the ongoing ownership of the `io` TLD, and the potential consequences of that, which derive from the origins of the `.io` TLD and who benefits from it. 21 | If you're interested in reading more on that, [this article](https://gigaom.com/2014/06/30/the-dark-side-of-io-how-the-u-k-is-making-web-domain-profits-from-a-shady-cold-war-land-deal/) outlines some of the information. 22 | 23 | All things together, we felt that moving to `.org` was the right step for us. 24 | It's something we've been planning for a couple of years now, and felt that with the upheaval of launching v3, the time was right to do it. 25 | If you hate all of these reasons, feel that we've betrayed our roots, have no principles, and have sold out, sorry for spoiling your day. 26 | To everyone else, I hope you enjoy our new home! 27 | -------------------------------------------------------------------------------- /posts/exercism-is-the-official-go-mentoring-platform.md: -------------------------------------------------------------------------------- 1 | I'm really proud to announce that as of today, Exercism is becoming the official mentoring platform for GoBridge and the Go Developer Network (GDN). 2 | 3 | GoBridge's mission is to enable minorities in tech to use Go as a tool to learn and teach programming and, ultimately, to empower underrepresented groups in tech to help increase diversity in the Go community. 4 | That fits perfectly with our mission of providing opportunity through the development of programming, and so we're really excited to be able to launch this partnership. 5 | GoBridge and the GDN will be promoting Exercism across their networks, and we'll be hoping for a large influx of both Go mentors and students. 6 | 7 | As part of this partnership, GoBridge is also donating to Exercism to help fund improvements to our interactivity, specifically allowing us to lay the foundations of student-mentor interactions **within** the new Exercism editor. 8 | This is something we're really excited about developing, and will form the center of Exercism Teams, which we'll be launching in 2022. 9 | 10 | We've put a special landing page up for this partnership, which you can access at [https://exercism.org/partners/gobridge](https://exercism.org/partners/gobridge). 11 | If you've not tried Go before, it's a very interesting language and we've got a [solid track](https://exercism.org/tracks/go) on Exercism, with some great [Learning Exercises](https://exercism.org/tracks/go/concepts). 12 | 13 | A massive thank you to GoBridge and the GDN, especially William Kennedy who has been the driving force behind this! 14 | I really hope this is the start of an exciting next phase for both organisations! 🙂 15 | -------------------------------------------------------------------------------- /posts/exercism-v3-has-launched.md: -------------------------------------------------------------------------------- 1 | After two years, we're finally launched. 2 | Watch the video above to hear our thoughts on everything and explore a little about where we're going next. 3 | 4 | We've been working on this for a long time and the big challenge for us has been when to launch. 5 | What does ready look like? 6 | Well, it looks like this! 7 | We got to the point where v3 was "good enough" to launch with, and said "let's do it" 8 | There's loads of rough edges we want to polish, a few half-finished features, and some that didn't make the cut. 9 | There are definitely going to be some bugs. 10 | But it's already a huge step forward from v2, and we think it's a great experience right now. 11 | 12 | So today is just the start, the beginning of the journey of exciting things to come, but it's also an exciting step in itself and something we're proud of. 13 | 14 | Here are a few answers to questions I've been asked: 15 | - **Badges:** We've launched with just a handful of Badges, but will be rolling lots more out over the next few weeks. 16 | So keep checking back to see if you get awarded anything! 17 | - **Reputation:** All reputation has so far been automated generated. 18 | Some people are owed reputation for things that aren't automated. 19 | We will sort this in the next couple of weeks. 20 | - All data has been carried over from v2 to v3. 21 | We've done lots of reshaping and migrating, and we might have made mistakes. 22 | If something is wrong, please open an issue on [GitHub](https://github.com/exercism/exercism). 23 | - **Exercism Teams:** Teams is offline for the rest of 2021. 24 | We're going to take some time to rebuild it properly, and have a whole load of really exciting features in stored. 25 | Watch this space in early 2022. 26 | - **Exercism Research:** The Research subsite is now offline, but we are still working with the researchers in Chicago, and will be adding in more experiments into the site in the coming months. 27 | Look out for more information in a vlog soon. 28 | - **Mentoring:** All your mentoring discussions should be available for you to see. 29 | In v2, mentoring was automatically requested on submission. 30 | In v3, requesting mentoring is a deliberate step. 31 | To try and clear things up and give the mentors a fresh slate, we've cancelled all (implicit) mentor requests from before August. 32 | If you've been waiting for ages, I'm sorry. 33 | But we felt it was more likely that we can encourage more mentors to get involved if they're not being asked to mentor old solutions that the student might not reply to. 34 | 35 | I really hope you enjoy v3! 36 | -------------------------------------------------------------------------------- /posts/finding-leap-years-with-cal.md: -------------------------------------------------------------------------------- 1 | # Finding Leap Years with cal 2 | 3 | _This post originally appeared on [Stephen's website](https://www.strangeleaflet.com/blog/finding-leap-years-with-the-cal-command) and is republished here (slightly rewritten) with permission_ 4 | 5 | ## Introduction to cal 6 | 7 | Did you know that there's a calendar in the macOS and Linux command line? 8 | 9 | ```bash 10 | $ cal 11 | 12 | July 2021 13 | Su Mo Tu We Th Fr Sa 14 | 1 2 3 15 | 4 5 6 7 8 9 10 16 | 11 12 13 14 15 16 17 17 | 18 19 20 21 22 23 24 18 | 25 26 27 28 29 30 31 19 | ``` 20 | 21 | A quick check of `tldr` shows how useful this utility can be 22 | 23 | ```bash 24 | $ tldr cal 25 | 26 | cal 27 | 28 | Prints calendar information. 29 | 30 | - Display a calendar for the current month: 31 | cal 32 | 33 | - Display previous, current and next month: 34 | cal -3 35 | 36 | - Display a calendar for a specific month (1-12 or name): 37 | cal -m month 38 | 39 | - Display a calendar for the current year: 40 | cal -y 41 | 42 | - Display a calendar for a specific year (4 digits): 43 | cal year 44 | 45 | - Display a calendar for a specific month and year: 46 | cal month year 47 | 48 | - Display date of Easter (Western Christian churches) in a given year: 49 | ncal -e year 50 | ``` 51 | 52 | But there's one thing it doesn't have. Leap years! 53 | 54 | Cal _knows_ about leap years of course, it wouldn't be much of a calendar otherwise. But it doesn't have a way to list them. 55 | 56 | ## Recognizing leap years, hackishly 57 | 58 | Let's build it ourselves! Sure we could use a real programming language with a calendar library but building things by assembling command line components is fun and it's not like we're going to put this calculation into production. 59 | 60 | First off, let's agree that February is the indicator for a leap year. 61 | 62 | ```bash 63 | $ cal 02 2021 64 | 65 | February 2021 66 | Su Mo Tu We Th Fr Sa 67 | 1 2 3 4 5 6 68 | 7 8 9 10 11 12 13 69 | 14 15 16 17 18 19 20 70 | 21 22 23 24 25 26 27 71 | 28 72 | 73 | $ cal 02 2020 74 | 75 | February 2020 76 | Su Mo Tu We Th Fr Sa 77 | 1 78 | 2 3 4 5 6 7 8 79 | 9 10 11 12 13 14 15 80 | 16 17 18 19 20 21 22 81 | 23 24 25 26 27 28 29 82 | ``` 83 | 84 | Could we search for "29" and have it recognize leap years? Maybe! 85 | 86 | ```bash 87 | $ cal 02 2020 | grep -q 29 && echo "LEAP" || echo "normal" 88 | 89 | LEAP 90 | 91 | $ cal 02 2021 | grep -q 29 && echo "LEAP" || echo "normal" 92 | 93 | normal 94 | ``` 95 | 96 | So far so good? But I bet you see the problem. 97 | 98 | ```bash 99 | $ for year in {2020..2030}; do 100 | printf "$year "; 101 | cal 02 "$year" | grep -q 29 && echo "LEAP" || echo "year"; 102 | done 103 | 104 | 2020 LEAP 105 | 2021 year 106 | 2022 year 107 | 2023 year 108 | 2024 LEAP 109 | 2025 year 110 | 2026 year 111 | 2027 year 112 | 2028 LEAP 113 | 2029 LEAP 114 | 2030 year 115 | ``` 116 | 117 | 2029 is NOT a leap year. It's only matching because of the 29 in 2029. 118 | 119 | ```bash 120 | $ cal 02 2029 121 | 122 | February 2029 123 | Su Mo Tu We Th Fr Sa 124 | 1 2 3 125 | 4 5 6 7 8 9 10 126 | 11 12 13 14 15 16 17 127 | 18 19 20 21 22 23 24 128 | 25 26 27 28 129 | ``` 130 | 131 | We could remove that troublesome result by removing the entire line with "February" from consideration. 132 | 133 | ```bash 134 | $ cal 02 2029 | grep -v Feb 135 | 136 | Su Mo Tu We Th Fr Sa 137 | 1 2 3 138 | 4 5 6 7 8 9 10 139 | 11 12 13 14 15 16 17 140 | 18 19 20 21 22 23 24 141 | 25 26 27 28 142 | ``` 143 | 144 | Now I hold that if we find a "29" in the result then it REALLY is a leap year. 145 | 146 | ```bash 147 | $ for year in {2020..2030}; do 148 | printf "$year "; 149 | cal 02 "$year" | grep -v Feb | grep -q 29 && echo "LEAP" || echo "year"; 150 | done 151 | 152 | 2020 LEAP 153 | 2021 year 154 | 2022 year 155 | 2023 year 156 | 2024 LEAP 157 | 2025 year 158 | 2026 year 159 | 2027 year 160 | 2028 LEAP 161 | 2029 year 162 | ``` 163 | 164 | Does that match up with actual leap years? 165 | 166 | [Wolfram Research's Leap Year](https://scienceworld.wolfram.com/astronomy/LeapYear.html) page has this list as the leap years in the first half of the 21st century. 167 | 168 | ```bash 169 | 2000 170 | 2004 171 | 2008 172 | 2012 173 | 2016 174 | 2020 175 | 2024 176 | 2028 177 | 2032 178 | 2036 179 | 2040 180 | 2044 181 | 2048 182 | ``` 183 | 184 | Let's see how we do 185 | 186 | ```bash 187 | $ for year in {2000..2051}; do cal 02 "$year" | grep -v Feb | grep -q 29 && echo $year; done 188 | 2000 189 | 2004 190 | 2008 191 | 2012 192 | 2016 193 | 2020 194 | 2024 195 | 2028 196 | 2032 197 | 2036 198 | 2040 199 | 2044 200 | 2048 201 | ``` 202 | 203 | Done! 204 | 205 | But this grepping for 29 is too easy. Let's get weirder! 206 | 207 | ## Recognizing leap years, even more hackishly 208 | 209 | The difference between a leap year and a normal year is that extra day of the 29th. Could we check the number of characters in the output from `cal` to recognize leap years? 210 | 211 | Yes we can. But there's a gotcha to get through first. Let me show you what I mean. 212 | 213 | We know 2020 is a leap year and 2021 is not a leap year. Let's check the difference between the number of characters output for February of each of those years. We'll do that with the handy `wc` utility, specifically `wc -c` to count the byte characters. 214 | 215 | ```bash 216 | $ printf "hello" | wc -c 217 | 218 | 5 219 | ``` 220 | 221 | 5 characters in "hello" (using `printf` instead of `echo` because otherwise we'd have a newline character as well). Great! 222 | 223 | ```bash 224 | $ cal 02 2020 | wc -c 225 | 226 | 184 227 | ``` 228 | 229 | ```bash 230 | $ cal 02 2021 | wc -c 231 | 232 | 184 233 | ``` 234 | 235 | There's the stumbling block. Each month has different output (2020 has that 29th day) but they both have the same number of characters because cal adds spaces to ensure consistent formatting. Spaces are countable characters just as much as numbers. 236 | 237 | What can we do? 238 | 239 | We can remove all the spaces! That would leave only the characters we want to count. 240 | 241 | A great utility for removing characters is the `tr` command. The `tr` command translates string data. For example, it can change all `a` characters into `A` characters. 242 | 243 | ```bash 244 | $ echo "aardvark" | tr a A 245 | 246 | AArdvArk 247 | ``` 248 | 249 | It can also delete all specified characters which is exactly what we want. 250 | 251 | In our case we want to delete all whitespace characters, no matter what they are (spaces, tabs, newlines, etc). There's a useful grouping called a character class which allows us to do exactly that. The characater class `[:space:]` will target all of those different kinds of whitespace characters. 252 | 253 | ```bash 254 | $ cal 02 2020 | tr -d '[:space:]' 255 | 256 | February2020SuMoTuWeThFrSa1234567891011121314151617181920212223242526272829 257 | ``` 258 | 259 | ```bash 260 | $ cal 02 2021 | tr -d '[:space:]' 261 | 262 | February2021SuMoTuWeThFrSa12345678910111213141516171819202122232425262728 263 | ``` 264 | 265 | Great! Can we count the number of characters to find leap years now? We sure can! 266 | 267 | ```bash 268 | $ cal 02 2020 | tr -d '[:space:]' | wc -c 269 | 270 | 75 271 | ``` 272 | 273 | ```bash 274 | $ cal 02 2021 | tr -d '[:space:]' | wc -c 275 | 276 | 73 277 | ``` 278 | 279 | Now let's output some leap years! 280 | 281 | ```bash 282 | $ for year in {2000..2051}; do 283 | cal 02 "$year" | 284 | tr -d '[:space:]' | 285 | wc -c | 286 | grep -q 75 && echo "$year"; 287 | done 288 | 289 | 2000 290 | 2004 291 | 2008 292 | 2012 293 | 2016 294 | 2020 295 | 2024 296 | 2028 297 | 2032 298 | 2036 299 | 2040 300 | 2044 301 | 2048 302 | ``` 303 | 304 | Hacks on hacks and it works! 305 | 306 | Which do you think is faster? Yeah I have no idea either. The "remove February" path is maybe faster? But I'd be surprised if there's a huge difference. 307 | 308 | Let's not be surprised. Let's find out! 309 | 310 | There's a great utility called `hyperfine` that allows evaluating the performance of multiple command line calls 311 | 312 | ## Which is faster? Hyperfine will tell us 313 | 314 | Here's the flags I'm giving to hyperfine along with the two commands. 315 | 316 | ```bash 317 | --style basic 318 | Plain output styling 319 | --export-markdown hyperfine.md 320 | Export results as markdown 321 | --warmup 5 322 | Do five runs before benchmarking 323 | --ignore-failure 324 | Ignore non-zero exits 325 | ``` 326 | 327 | We're only concerned with benchmarking the calculation of a year and not the time required to generate the loop of years. So I'll only benchmark checking the leap year for a specific year with each approach. 328 | 329 | ```bash 330 | $ hyperfine --style basic --export-markdown hyperfine.md --warmup 5 --ignore-failure "cal 02 2050 | grep -v Feb | grep -q 29" "cal 02 2050 | tr -d '[:space:]' | wc -c | grep -q 75" 331 | 332 | Benchmark #1: cal 02 2050 | grep -v Feb | grep -q 29 333 | Time (mean ± σ): 1.8 ms ± 0.3 ms [User: 0.7 ms, System: 1.9 ms] 334 | Range (min … max): 1.0 ms … 3.6 ms 493 runs 335 | 336 | Warning: Command took less than 5 ms to complete. Results might be inaccurate. 337 | Warning: Ignoring non-zero exit code. 338 | 339 | Benchmark #2: cal 02 2050 | tr -d '[:space:]' | wc -c | grep -q 75 340 | Time (mean ± σ): 1.9 ms ± 0.4 ms [User: 0.9 ms, System: 2.7 ms] 341 | Range (min … max): 0.7 ms … 5.9 ms 811 runs 342 | 343 | Warning: Command took less than 5 ms to complete. Results might be inaccurate. 344 | Warning: Ignoring non-zero exit code. 345 | 346 | Summary 347 | 'cal 02 2050 | grep -v Feb | grep -q 29' ran 348 | 1.07 ± 0.28 times faster than 'cal 02 2050 | tr -d '[:space:]' | wc -c | grep -q 75' 349 | ``` 350 | 351 | | Command | Mean [ms] | Min [ms] | Max [ms] | Relative | 352 | | :-------------------------------------------------------- | --------: | -------: | -------: | ----------: | 353 | | `cal 02 2050 \| grep -v Feb \| grep -q 29` | 1.8 ± 0.3 | 1.0 | 3.6 | 1.00 | 354 | | `cal 02 2050 \| tr -d '[:space:]' \| wc -c \| grep -q 75` | 1.9 ± 0.4 | 0.7 | 5.9 | 1.07 ± 0.28 | 355 | 356 | As expected, practically no difference between them as far as wall clock time, BUT the "remove February" path may be _slightly_ faster. 357 | 358 | That brings this command line tool assembly journey to an end. 359 | 360 | ## Wrap up 361 | 362 | - You can build new command line features by assembling existing tools into a data pipeline 363 | - A bit of creativity can get surprisingly complex results from simple pieces 364 | - Hyperfine is a useful tool for benchmarking command line commands 365 | 366 | ## Next steps 367 | 368 | - Explore using the `cal` command. 369 | - Try building a pipeline that counts all the non-space characters for an entire year: `cal 2020` 370 | - Try running that entire year counting pipeline for each of the years from 1750 to 1759: notice anything odd? 371 | -------------------------------------------------------------------------------- /posts/freeing-our-maintainers.md: -------------------------------------------------------------------------------- 1 | **Important: This information is now outdated. Please see our [newer blog post](https://exercism.org/blog/contribution-guidelines-nov-2023) for up to date details.** 2 | 3 | --- 4 | 5 | _TL;DR; We're spending a few months redesigning our volunteering model and giving our key volunteers a break from the work of reviewing community contributions. 6 | If you use Exercism purely to learn or mentor, there’s nothing here you need to know (although please read if you’re interested!). 7 | If you are a track maintainer, wish to contribute to Exercism, or wish to report a bug/problem, then consider this essential reading 🙂_ 8 | 9 | --- 10 | 11 | Over the last 6 months we’ve spent a lot of time exploring the future of Exercism, imagining what it would look like for every language track to be the best it could be. 12 | We’re incredibly proud of what we have built so far. 13 | The 85,000 testimonials that have been given speak to the amazing work our community has done in building our language tracks and mentoring so many students through them. 14 | Most importantly, we believe we're just scratching the surface of what is possible. 15 | We have huge ideas, hopes, and excitement for all that Exercism can be. 16 | But to achieve them, we first need to resolve some fundamental problems that linger under the surface. 17 | 18 | Foremost of these is a need to solve the challenge of scaling our volunteer community in a healthy, sustainable way. 19 | Exercism has been built on the shoulders of hundreds of dedicated volunteers, but a large proportion of them now feel burnt out and many have left as a result. 20 | There’s a myriad of reasons for this, some directly related to Exercism, some down to the time-pressures of life, and some to the backdrop of all that’s happening in the world at the moment. 21 | But it’s become very clear to us that we need to design and develop a better way of building our platform together. 22 | 23 | We’ve historically tried to build Exercism with an Open Source Software (OSS) model of having maintainers who review contributions from the wider community. 24 | This has caused us a lot of problems and caused frustration for both maintainers and contributors. 25 | I explore this further below if you want detail, but the TL;DR; is that our key volunteers now spend their time acting as reactive gatekeepers rather than innovative creators. 26 | That’s a lot less fun for them, and means Exercism loses the magic those people have previously brought to the platform. 27 | 28 | There are two things we need to do to fix this: 29 | 1. We need to design a new system of volunteering that suits Exercism better than the traditional OSS model. 30 | We’ve spent a good chunk of energy trying to do this so far, and failed. 31 | So we’re going to take some time out to work with our volunteers to design this properly over the next few months. 32 | 2. We’re going to largely pause wider community contributions for the next few months to let our key volunteers focus on building and developing the tracks in the way they want (or to take a sabbatical if they just want to take a breather!) 33 | 34 | My hope is that by taking a step back and really designing this well, alongside fundraising in order to broaden our educational team, we can make Exercism a brilliant place to volunteer, and help secure its future. 35 | In the meantime, these changes should mean that the tracks can improve and grow more than they’ve been able to in the last year and that our maintainers stop burning out and instead feel happier, more energised and more connected from working on Exercism. 36 | 37 | ## Tangible changes 38 | 39 | There are three tangible changes that we are implementing. 40 | 41 | ### Use the Forum, not GitHub Issues 42 | 43 | We’re going to free up GitHub entirely for our maintainers to be working on the issues they want to work through. 44 | We’ll be closing a wealth of issues that we’ve previously created for the community to work on (and adding a tag so that they can be easily reopened in the future if we want to) whilst not allowing new unsolicited issues or PRs in the majority of repositories. 45 | If you’d like to discuss or report something, please use the [forum](https://forum.exercism.org) instead. 46 | If you open an unsolicited issue or a PR, it’ll be automatically closed and you’ll be pointed to the forum. 47 | 48 | ### Pausing wider community contributions 49 | 50 | Tracks will be split into three categories: 51 | - The majority of tracks with active maintainers will have community contributions paused, to allow the maintainers to be autonomous or to have a break. 52 | (Maintainers of these tracks can request to remove the compulsory one-review requirement. 53 | Please speak to Erik on Slack for this) 54 | - Some tracks with active maintainers who actively want to continue to accept community contributions, will remain open (If you’re a maintainer and would rather go into this mode than (1), please reach out to Jonathan Middleton on Slack to discuss). 55 | - For tracks where there are no active maintainers, track development will essentially be paused for this period. 56 | 57 | In all cases, Erik and I will continue to confidence-check PRs to Tooling repos before merge. 58 | 59 | The one exception is that we will continue to accept PRs for Approaches and Articles, and will implement an org-wide optimistic merging policy that aims to populate a baseline of Approaches across exercism, and allow for incremental improvements, using the following rules: 60 | 1. If the code solves the exercise and is syntactically and semantically idiomatic (i.e., it looks like $LANG code) it should be merged. 61 | If not, it should be fixed by the PR author. 62 | 2. If a maintainer wants to make changes to the content (e.g., to improve the advice, tweak things, highlight better/alternative/more-idiomatic approaches) then that should be done in a follow up PR. 63 | 64 | ### Designing a new volunteering system 65 | 66 | We’re going to put together a Community Board to co-design a sustainable, healthy volunteering framework for us moving forward, that unlocks Exercism’s potential. 67 | If you’re committed to the future of Exercism and want to be part of this process, please get in touch with [Jonathan](mailto:jonathan@exercism.org). 68 | 69 | We’re going to run with these actions for the next few months. 70 | We’ll be considering everything throughout the period, and plan to make some new decisions by June 2023. 71 | If you’ve any thoughts, please start a topic on the [forum](https://forum.exercism.org)! 72 | 73 | ## Postfix: Why our OSS model is broken 74 | 75 | Our historic model has been built around the OSS model. 76 | It’s relied on volunteers who have come into Exercism, done great work on building tracks and then been given maintainer privileges, in which they can then accept contributions from our wider user base to improve them. 77 | 78 | While this seems great on paper, it has some significant problems. 79 | At the foremost of these is that the people who add the most magic to Exercism end up not having any time to code or create Exercism because their time gets spent responding to community contributions. 80 | This is almost never why the maintainers got involved in Exercism in the first place, and not work they enjoy. 81 | It’s a little like someone who loves developing being “promoted” to be a team-leader, where they manage people instead of coding. 82 | It might seem like a nice promotion at the time, but often it turns out that people don’t enjoy being managers half as much as they enjoy coding. 83 | 84 | It also relies on the assumption that the sum of wider community contributions is greater than the individual contribution that a given maintainer could otherwise make. 85 | But in Exercism, that’s almost never the case. 86 | Exercism is complex, and education is hard, and together they make contributing to Exercism a complex and hard thing to build. 87 | There’s loads to learn and understand about both how Exercism works technically and its approach to education, and so this means that most first contributions are people finding their way. 88 | This means their initial contributions are relatively small but also that they nearly always need lots of work in reviewing and tweaking. 89 | This is time-consuming work for maintainers. 90 | In fact, the total time spent in reviewing (as well as the context-shifting required) means the maintainer generally puts more effort into reviewing the PR than if they’d just made it themselves. 91 | There are, of course, some exceptions to this, but it’s true in 99% of cases. 92 | And frequently this is even more painful to the maintainer as the problem the PR solves was not near the top of their priority list, meaning the things that they know are really essential don’t get done as a result. 93 | 94 | Finally, the OSS model relies on contributors starting off small and eventually becoming knowledgeable and regular enough that they can become maintainers. 95 | In OSS projects like software libraries, this works relatively well (e.g., someone is using a library in production and keeps adding improvements to it, to the point they eventually have as much knowledge as the original creator). 96 | However, for Exercism, that’s just not happened. 97 | Despite merging PRs from thousands of contributors in the last 12 months, only a tiny handful have gone on to be regular contributors and even fewer have become maintainers. 98 | This is again mainly due to the complexity of Exercism, but also because it’s not a contained piece of software, where this model traditionally work. 99 | 100 | All of this is incredibly demoralising for maintainers and detrimental to Exercism. 101 | 102 | Tracks have stalled and our core volunteers, who had passion for building, largely lost that passion when their job became that of reviewing others’ work, negotiating competing priorities, and fielding unexpected requests. 103 | During the build of v3, maintainers were able to work with relative autonomy as their work was largely behind-the-scenes, which led to a huge level of productivity, and meant the majority of people really enjoyed contributing. 104 | Since the launch of v3, despite many volunteers dedicating just as much time to Exercism, it’s been a much less enjoyable and productive period, largely due to how much energy has gone into responding to others’ contributions or issues. 105 | Our volunteers now spend their time acting as reactive gatekeepers rather than innovators, and that’s a lot less fun. 106 | 107 | These are the challenges we need to fix, and they’re hard ones. 108 | We need to find a way for people who want to spend hundreds of hours building Exercism’s language tracks to be able to do that and love doing it. 109 | We need to find a way for bug fixes and small contributions to get into our codebase without those key volunteers’ attention. 110 | And we need to find a way to entice new volunteers into Exercism, and support them should they choose to commit to ongoing contributions. 111 | We need to reduce gatekeeping in general while also respecting that those who have put so much effort into tracks have strong and very well considered opinions. 112 | We need to make it fun to manage and run that whole volunteering setup. 113 | And we need to solve a host of other things as well. 114 | It’s going to take time, and be a challenge, but when we pull it off, it’ll be amazing. 115 | 116 | -------------------------------------------------------------------------------- /posts/functional-february.md: -------------------------------------------------------------------------------- 1 | Hi everyone! Welcome to Functional February - the first themed month of the #12in23 Challenge. 2 | 3 | If you have no idea what I’m talking about when I say #12in23, I’ll link to a couple of videos in the description to give you more info, but fundamentally we’ll challenging you to try out 12 different languages during 2023. Each month has a different theme and this month is functional programming languages. 4 | 5 | So firstly, the aim of the month! Well it’s for you to try out functional languages, or if you’ve already worked with them before then to go a little deeper! Explore the ideas unique to functional languages - things like pattern matching, immutability, higher-order functions - learn how to think in a functional way, and most importantly have fun. 6 | 7 | We’ve selected 9 languages that we’re focussing on this month, and we’re recommending that you start with one of Elixir, F#, or Clojure - all of which have great Learning Modes on Exercism! Elixir in particular is one of most detailed and refined tracks on the whole site - with 57 concepts to learn. Then the other 6 languages are Erlang, Haskell, OCaml, Scala, StandardML and the newest language on Exercism - Gleam! 8 | 9 | Now for many people the most important question is how to get the Functional February badge! Well it’s pretty simple! Choose one of those languages I just mentioned and solve and publish five exercises in it! You can choose any exercises to solve other than “Hello World”, but we’re recommending five in particular that you try at some point during the month. Those are Hamming (to explore higher order functions), Collatz-conjecture (to practise recursion), Robot Simulator (to play with immutability), and both Yacht and Protein Translation (for pattern matching and higher order functions). All those are listed on the #12in23 page so you can check that later! 10 | 11 | So, aside from solving Exercises, what else do we have in store for you? Well, firstly, we have a couple of big interviews planned. Top of the list is a chat with Jose Valim, the creator of Elixir. I’m going to be chatting to Jose, exploring why he chose to make Elixir a functional language, and putting your question to him. The secondly, I’m going to be speaking to Louis Pilfold, the creator of one of the newest functional languages - Gleam. Louis’ also going to be live streaming himself solving some Gleam exercises on Exercism, so you can see how he thinks about functional programming! 12 | 13 | We really want this to be a month where we’re learning together and as part of that we want to encourage the community to share their experiences of functional programming. Throughout the month we’re going to be live streaming a mixture of walkthroughs and exercise-solving sessions with contributors across all of our featured languages. All of our streaming is going to be on our brand new channel on Twitch - https://twitch.tv/exercismlive - so please subscribe there so you don’t miss anything. We’ll also be adding a widget to the main site dashboard which you can keep an eye on! 14 | 15 | On the Exercism forums, as well as just general conversations about functional languages and helping each other when we get stuck, we’re going to be having an official thread putting together all the best resource for learning and understanding functional programming languages. If you’re a seasoned functional programming dev, please come along and tell us the resources that helped you when you were learning! 16 | 17 | We’re also going to have some exclusive Functional February swag only available this month! So keep an eye out for when we launch that. 18 | 19 | Two quick things before we jump into the conversation with Erik. 20 | 21 | Firstly, not enough people are requesting mentoring, and if you’re not, you’re massively missing. When you solve an exercise in a language you don’t know well, mentoring should be the first thing you’re reaching for! Having someone more experienced than you giving you personalised pointers and tips is an unbelievable way to level up, and on Exercism’s totally free and lots of fun. So this month, when you solve something and you’re not sure if you’ve written it like a functional programming pro, request mentoring! 22 | 23 | Secondly, Exercism needs donations to survive. We’re a not-for-profit organisation trying to help as many people as possible and to do that we keep things free so that anyone in any situation can learn. If you’re fortunate enough to find yourself in a good financial situation right now and you spare a little money to support our work, please do consider donating. Frankly, if people don’t support us, we won’t survive. If you can’t afford to support us, then that’s absolutely fine - that’s why we’re free, so that we can help people that couldn’t afford to buy a product like Exercism! And finally if you’ve already donated - thank you. It’s means the world to us. 24 | 25 | Watch the full video to see the interview with Erik. 26 | 27 | Thanks for watching! 28 | -------------------------------------------------------------------------------- /posts/independent-mode-becomes-practice-mode.md: -------------------------------------------------------------------------------- 1 | Exercism tracks can be solved in two ways: 2 | 1. A focus on learning a new language, where you are guided by mentors and work through a structured set of exercises. We call this Mentored Mode. 3 | 2. A focus on practicing a language, choosing whichever exercises look most interesting, and only reaching out to mentors for help when required. We've called this Independent Mode. 4 | 5 | As of today, we are renaming "Independent Mode" to "Practice Mode" to better reflect its intention. 6 | In Practice Mode you're not alone - you can still reach out to a mentor and get help when needed, but the focus in on working at your own pace and practicing a language, not learning it from scratch. 7 | 8 | In the future we may rename "Mentored Mode" too, but we'll defer that for later. 9 | -------------------------------------------------------------------------------- /posts/insiders-preview.md: -------------------------------------------------------------------------------- 1 | # Exercism Insiders Preview 2 | 3 | I want to tell you a little about two new things we’re adding to Exercism to help make it financially sustainable. The second - Exercism Insiders - is something I think you’re going to be especially excited about. And make sure to read this to the end as I announce two special features, one of which is only available for early adopters. 4 | 5 | So firstly, a bit of background. When Katrina first created Exercism 10 years ago she had absolutely zero desire for it to turn into any sort of big product. It was a simple platform that she was using with her students. But by a joyous accident, it became a thing. And 10 years later, we now have millions of visitors per month. We’ve got to this stage on a ridiculously small budget. In fact, in the 8 years of Exercism up to the launch of v3, we spent under $500k - only $60k per year. During that time, we’ve rebuilt the platform from scratch twice, created 65 language tracks, had millions of submissions, discussions, iterations… We’ve built automated feedback systems that have given feedback over 800,000 times. We’ve done a lot. On very little. 6 | 7 | And a big part of the reason that’s been possible is obviously because of the fact that we’re open source. Thousands of people have contributed to Exercism, and a few hundred especially wonderful folks have done the work of building out and maintaining our content. But with the success of the v3 launch, we hit a point where we needed an actual full time team working on Exercism to keep it functioning. We were also given an incredibly generous donation of $500k at this time, which meant we could hire a small team. So we hired Aron to do front-end work, Jonathan to grow and manage the community side, and Loretta to work on fundraising and partnerships. 8 | 9 | The result of that work has actually been pretty amazing. Day-to-day usage of the site has grown by about 250% year-on-year. We’ve added a load of automated mentoring features that mean we’ve now instantly given feedback on over 800,000 solutions. We have the community live streaming on Twitch on a daily basis. We have a vibrant forum and Discord server. We’ve also increased our monthly donations from pretty much zero to over $6k per month. Which is huge. However, our work on trying to get companies to support us via their CSR budgets has gone less well, and while £6k/month is amazing, it’s only actually 1/5th of what we need and the majority of donations are one-off gifts rather than recurring support. So, we’re running out of time to be sustainable with our current team, and without that team, we don’t have the resources to actually run Exercism - as much as I wish there were 400 hours in a week for me to do all the things, there’s not. And I can’t. So we need to find a way to be able to pay for everyone, and quickly. 10 | 11 | But also, I want Exercism to grow. Those of you that have spent time talking to me over the last few years know all the ideas and hopes and ambitions I have for Exercism - the stuff I think we can do that would be amazing. But to do that, we need both a larger team, and we need to be able to pay more competitive salaries. So… we need to find a way to fix things. 12 | 13 | And there’s two things we’re going to try. 14 | 15 | The first is to add some sponsorship to the site. We’re going to seek out partners who we feel offer great products and services to developers and invite them to sponsor tracks and also areas like our emails and infrastructure. Sponsorship will be a long-term thing - companies will need to commit to probably a minimum of 12 months support. And we do really want to treat these as win-win partnerships. I’m thinking that we can do things like co-create really great content, do some interviews with senior people in their companies, and also get them to offer discounts or free trials to our power-users - but more about that in a minute! 16 | 17 | There’s a few things we won’t be doing. This won’t be advertising in the pay-per-click sort of world. We won’t be adding any tracking stuff onto the website, sharing any people’s details, or anything at all like that. We’re purely looking for organisations who want to support free education, support open source, support grass-roots initiatives like ours, and in exchange we tell you all that they’re doing it, and hopefully encourage you to at least take a look at their products. I also hope that many of these organisations will also choose to donate to Exercism via their Corporate Social Responsibility arms as well. We’ll see. 18 | 19 | And as an interlude here, if you work for a company that offers products or services to developers, maybe they’d be interested in sponsoring exercism. If you could make an introduction, put us in touch with the relevant person, or even just anonymously tell us who we should be approaching, that would be huge. So please email Loretta (her email’s in the description below) and we’ll work out what works best! 20 | 21 | I started out a bit dubious about all this, but I’m actually really excited for it now. I think true partnerships could be a real level-up for Exercism and provide some great extra benefits for all our members. 22 | 23 | So that’s the first part. The second part is something I’m definitely excited about and have been for ages and that’s Exercism Insiders. 24 | 25 | Exercism Insiders is going to be our new rewards program for people who actively support Exercism. We’re going to be giving you more behind-the-scenes access, more involvement in the future of Exercism, extra fun features, and also, we’re going to be asking all the companies we’re speaking to about sponsorship to offer free trials or discounts to our Insiders. 26 | 27 | To be an Insider the general rule is that you need to actively be supporting Exercism. For the most part that means either you’ve been actively contributing to our codebase, actively mentoring, or have made a recent donation. We’re still finalising the details, but my thinking is loosely that every time you earn a certain amount of reputation, or donate to us, that extends your access by 30 days from that point. If you’re a regular donator or a regular contributor, then we’ll probably also give a bit more of a grace period, so if you’ve not been around for 30 days, but have been for the previous 9 months, you don’t just lose access. And we’ll also be giving life-long membership to people who have made huge contributions in the past but aren’t currently active. 28 | 29 | Insiders will also give you a badge that appears next to your name on the website, flare on the forum and a Discord role that gives you access to special private channels. It will also mean that on things like our community calls, you’ll be able to attend and actively participate, rather than just watching them back. It will give access to behind-the-scenes vlogs and interviews, and we’re also considering things like prioritising questions from Insiders in the AMAs we’re hosting. Basically, if you’re part of what makes Exercism a success, we want to celebrate you and really bring you along for the ride. 30 | 31 | I mentioned at the beginning that we’ve got two special features for early adopters. The first of these is Dark Mode. I know this is something that a lot of you have been wanting forever, and well it’s finally here. We’re going to be launching it at the same time as Insiders and it's only going to be available to Insiders for the first 3 months. So if you want access to it, go and earn some reputation by contributing or mentoring, or sign up as a regular donor. 32 | 33 | The second feature is what we describe in the UK as marmite - you’ll either love it or hate it. We’re going to be integrating ChatGPT into our site, so if you get stuck on an exercise you can ask it for help, and when you finish an exercise you’ll get automated feedback from it. In our experiments so far, ChatGPT has been awesome about half the time, and useless the other half, so we’re treating it as a purely fun feature at this stage, but we think it is going to be a lot of fun to experiment with. This is going to be an Insiders-only feature for the foreseeable future, and for the month of May, only those people who were Insiders on Insiders launch-day will get access, so if you want to play with this, you need to have earned Insiders access before we launch. We’re also going to be adding a special badge for people who supported us before we launched Insiders, and the little Insiders tag next to your name on the site will permanently reflect your early support. 34 | 35 | We’ll be launching a landing page the next week with exact details and your pending Insiders status, but making a donation now guarantees you access, and it would be amazing to see some donations rolling in before we launch, so please consider doing that if you’re able to! 36 | 37 | One thing I want to clarify is that none of our educational features are going to start getting walled off. Insiders is going to be full of fun features, extra UI juice, and behind-the-scenes access. It’s not going to be extra content, or production-ready features. So if you can’t afford the time or money to access Insiders you’re not going to get a worse educational experience as a result - that’s a really important red-line for us. 38 | 39 | OK - so those are the two things: sponsorship and Insiders. Our hope is that through these, both companies and individuals choose to financially support Exercism, and we can both get ourselves to a more sustainable point and start to see a future where we can really thrive and start to build out some of the exciting ideas we have. 40 | 41 | So thanks for reading. I hope you’re really too, especially by Insiders. I look forward to telling you more in the coming weeks! 42 | 43 | -------------------------------------------------------------------------------- /posts/inspiring-kids-with-clever-tykes.md: -------------------------------------------------------------------------------- 1 | _Nicole chatted to Jodie and Ben Cook who have a series of storybooks including one that inspires children to learn to code._ 2 | 3 | **Hello! Could you give us a quick overview of your Clever Tykes books?** 4 | 5 | Yes! The [Clever Tykes storybooks](https://clevertykes.com/) and resources aim to inspire children to develop positive, resourceful and creative behaviour. The series of four storybooks - Walk-it Willow, Code-it Cody, Change-it Cho and Write-it Ryan - follow characters who turn something they enjoy doing into a venture of their own. That's how we enable children ages 6-9 to experience the entrepreneurial process and encourage them to think and behave in a more enterprising way. 6 | 7 | Of specific interest to Exercism's members is the second in the series and by far our most popular, [Code-it Cody](https://clevertykes.com/code-it-cody/), based on a computer whizz who starts coding at school. 8 | 9 | **We'll come back to Code-it Cody, but first—what gave you the idea for the series?** 10 | 11 | Sure. After noticing that many entrepreneurs came from families of other entrepreneurs, we began to research the impact of role models. Turns out, role models are integral in shaping someone's aspirations, and especially influential in their future choice of career. We looked at the role models that exist in current media and weren't satisfied with the selection, so we decided to write our own! 12 | 13 | **I love the idea of encouraging children to think in enterprising ways. Could you tell us a little about the idea behind Code-it Cody?** 14 | 15 | We see Code-it Cody as being how we inspire children to want to learn more about coding, regardless of their parents' knowledge or what their school happens to teach. There are several tools available that teach children how to code. Many of the parents of budding coders will know of a few. However, we don't want it to only be the children with parents already tuned in to the world of programming to be the ones that go on to be great programmers. Code-it Cody gives readers the inspiration to begin. 16 | 17 | **Why did you decide that coding was such an important skill to base one of the stories around?** 18 | 19 | We felt it important to give the stories modern context, so technology plays a role across the series. When thinking about essential skills for the future of work, coding was naturally one of the first we thought of. It's well-documented that there is a growing skills gap in this area and coding is not yet embraced by all schools. 20 | 21 | There are very few barriers to entry for kids to take their interest in coding further. They can pretty much start learning at any time and this kind of accessibility was really important to us. 22 | 23 | **This is right up our street! What about the other characters? How did you choose which topics to focus on?** 24 | 25 | Change-it Cho is a social entrepreneur who champions healthy eating and exercise, something we're both big fans of. Write-it Ryan is about thinking creatively and how to channel a strong imagination into producing content for an audience. We centred Walk-it Willow on a service-based business because our experience of enterprise programmes in schools is that they focus on products. Kids are taught that a viable business is buying and selling; inventing products and holding cake sales, or even lemonade stands, but less about a service they can provide for their community. The story of Walk-it Willow's venture has the lowest barriers to entry for someone to replicate and the story involves cute dogs which readers seem to enjoy! 26 | 27 | **So in the stories the messages about enterprise are subtle, but there is an element of competition and commercial awareness there. How did you strike the right balance between fiction and non-fiction?** 28 | 29 | We're not trying to create child businesspeople, we're trying to introduce the mindset and behaviours associated with entrepreneurship to open up future opportunities. The goal is to create a mindset shift and to encourage resilient and resourceful behaviour, not just teach certain skills. 30 | 31 | The presence of competition plays a role in large parts of many peoples lives, especially in their work. We feel that equipping children with a comfortableness around competition is an important way to prepare them for their future. 32 | 33 | Commercial awareness is something else we address because it's important to understand that in order for an enterprise to be sustainable, there must be market demand and a viable business model. Of course, we don't use that kind of language in the story, itself, but the concepts are there for kids to grasp on a basic level and parents to continue the discussions. 34 | 35 | **What has been the impact on children so far?** 36 | 37 | Storytelling is an incredibly powerful tool to help influence beliefs, affinities and actions. Cody is a likable and believable main character which means readers really buy into him and his love of problem solving and computer games. 38 | 39 | From the feedback we've received from parents, teachers and kids, Cody and his story resonates with children who begin to share his passion and desire to learn how to code. We've been thrilled when parents have told us that their kids have asked to start coding lessons after reading the book! It's also given parents a way of opening up discussions about what their child wants to be when they grow up. 40 | 41 | **Cody is an interesting character, he has some traits that are considered typically introverted and is hearing impaired - can you tell us more about your thinking behind these decisions?** 42 | 43 | Yes, Cody is fairly reserved and he likes to assess a situation quietly before he contributes. Cody is hearing impaired to demonstrate to readers to not let things hold them back! He certainly doesn't allow it to stand in his way. We found there are very few characters in kids books with disabilities of any sort. Cody's hearing impairment can be a metaphor for any obstacle in life; the learning is to accept that it's there and move beyond it. 44 | 45 | Within the storybook there are characters from a range of backgrounds with very different personalities. We hope that we can help reaffirm the belief that difference is something to celebrate. The attendees of Code Club are all very supportive of each other's efforts! 46 | 47 | **It's so refreshing to read about some multidimensional characters in children's storybooks! Let's get into the business side now, how are you spreading the word about your books?** 48 | 49 | After we had finalised the storybooks, website and distribution, and ecommerce sales were at a good level, we set about finding sponsors for the books. We are well aware that the kids who the stories benefit the most aren't the ones whose parents are able to buy them books. The first sponsorship we secured was from a technology publishing company based in Birmingham, called Packt Publishing. Packt sponsored 300 copies of Code-it Cody and gave them out to parents across the city. 50 | 51 | After that, we set our sights on gifting the books to every primary school in the UK, all 24,000 of them! We managed to secure sponsorship with Lloyds Banking Group to do exactly this in January 2017. Every primary school received a set of the Clever Tykes storybooks along with access to an online portal with resources and teaching materials for enterprise education. 52 | 53 | At the moment we're working on replicating this in the USA. 54 | 55 | **We'll certainly be keeping our eye on this! It's seems to be the dream of a lot of people to write books, especially children's storybooks, do you have any advice for readers who are considering putting pen to paper?** 56 | 57 | The main thing is just to get started! Do some research to see what else is out there on a similar topic to get an idea of where your story might fit in, then get planning and writing. Don't underestimate the value of having a great editor and illustrator and don't underestimate the challenge of marketing your book once it's produced. 58 | 59 | There are so many things to consider when planning, writing, producing and selling children's books. We are asked about this a lot, so we put everything we know in an article called [How to Sell Thousands of Children's Storybooks Without a Publisher](https://medium.com/@cookiewhirls/how-to-sell-thousands-of-childrens-storybooks-without-a-publisher-898ff9544ef9). 60 | 61 | **Where can we find the Clever Tykes books?** 62 | 63 | They are available for the USA [here](http://clevertykes.com/amazonusa), the UK and Europe [here](https://amazon.co.uk/clevertykes), Japan [here](https://www.amazon.co.jp/dp/0992691389), and the rest of the world [here](http://clevertykes.com/). 64 | 65 | ![Clever Tykes characters on a book](https://assets.exercism.io/blog/inspiring-kids-with-clever-tykes.jpg-book.jpg) 66 | -------------------------------------------------------------------------------- /posts/interview-with-erik-schierboom.md: -------------------------------------------------------------------------------- 1 | _An interview with [Erik Schierboom](https://exercism.io/profiles/ErikSchierboom) in which he and [Jeremy Walker](https://exercism.io/profiles/iHiD) discuss functional programming, maintaining Exercism tracks, and the upcoming static analysis of Exercism solutions._ 2 | 3 | **Hi Erik. Thanks for featuring in the first Exercism Contributor Spotlight! We wanted to highlight your work because it feels like you contribute to every bit of Exercism and have some great insights from working across the whole project!** 4 | 5 | **So for a bit of background, how did you first get involved in Exercism?** 6 | 7 | In 2014, I did a functional programming course that used Scala as its language. After finishing that course, I looked for resources to further improve my Scala skills and found Exercism. It didn't take long before I was hooked and also started to do other language tracks on Exercism. Having benefited greatly from comments people left on my solutions, I then started commenting on solutions in the C# track. At some point, I was asked to become a maintainer of the C# track, which I accepted gladly. Five years later, I'm now a mentor in the C# and F# tracks, a maintainer of the C#, F# and Scala tracks and help work on the cross-track problem specifications. 8 | 9 | **Nice. So you got into Exercism really early in its life. For those who are unaware, could you explain what it means to be an Exercism maintainer, please?** 10 | 11 | Sure. Abstractly speaking, an Exercism maintainer is responsible for a track's "health." In practice, that can mean a great many things, like implementing new exercises, updating existing exercises or reviewing pull requests from other maintainers. Another important aspect is correctly ordering a track's exercises, to ensure students have the best possible learning experience. Note that being a maintainer does _not_ mean one has to engage in all of the aforementioned activities; it is perfectly valid for a maintainer to only focus on one or two activities. 12 | 13 | **Thanks! So as well as your focus on C#, F# and Scala, you've pretty much worked through every language track on Exercism. Do you have particular favorites from a learner's point-of-view?** 14 | 15 | Although I've learned tons from every track I worked through, my favorite track must be the Haskell track. Not only is it a great language with lots of interesting concepts, the quality of its mentors was absolutely stunning. Other favorites are the Kotlin and F# tracks, with Kotlin and F# being extremely well-designed and pragmatic languages that I love programming in. 16 | 17 | **Yeah, I hear a lot of great things about the Haskell mentors! I imagine working through so many tracks gave you a whole load of interesting insights into coding. Were there any things specifically that you learnt from that experience?** 18 | 19 | Oh yes, tons of things! Working with a wide variety of languages exposes one to many different ways of approaching problems. These different approaches have all influenced my coding style in some way, although the functional languages have probably influenced me the most. I now find that I use functional concepts whenever I can, even in non-functional languages (which are slowly incorporating functional features). 20 | 21 | I've also learnt that while every language is different, many are actually quite similar. As a result, learning a new language becomes a lot easier once you know a couple of them. For example, knowing Haskell means that one could probably pick up F# or Scala relatively quickly. Learning new languages could thus also be a good career move, as you'll be able to switch between languages more easily. 22 | 23 | Finally, I've learnt that having mentors guide you while learning a language makes the process so much more enjoyable and effective. 24 | 25 | **I've found the same. Learning from others is such a multiplier! From a practical point of view, how did you deal with all the setups for the different languages. I often find the thought of learning a new IDE a bit intimidating. Did you stick to an editor you knew while you worked through the languages, or vary it in order to try and get a more idiomatic experience?** 26 | 27 | For some languages, setting up a new development environment used to be a bit of a hassle, but nowadays most languages are fairly easy to setup. I then try to find an IDE that gives me the best experience for that specific language. As I alternately work on Windows and Mac OS, the IDE should also be cross-platform. An example of a great, cross-platform IDE is [Visual Studio Code](https://code.visualstudio.com/), which I use for the [Haskell](https://exercism.io/tracks/haskell), [JavaScript](https://exercism.io/tracks/javascript), [TypeScript](https://exercism.io/tracks/typescript), [Elm](https://exercism.io/tracks/elm) and [Elixir](https://exercism.io/tracks/elixir) tracks. For the other tracks, I use a [JetBrains IDE](https://www.jetbrains.com/products.html?fromMenu): [Rider](https://www.jetbrains.com/rider/) for [C#](https://exercism.io/tracks/csharp) and [F#](https://exercism.io/tracks/fsharp), [IntelliJ IDEA](https://www.jetbrains.com/idea/) for [Java](https://exercism.io/tracks/java), [Scala](https://exercism.io/tracks/scala) and [Kotlin](https://exercism.io/tracks/kotlin), and finally [RubyMine](https://www.jetbrains.com/ruby/) for [Ruby](https://exercism.io/tracks/ruby) (note: these are also cross-platform IDE's). As you can see, I use multiple editors to get the best experience for each language (although the Jetbrains IDE's are obviously quite similar). 28 | 29 | Pro tip: if you are core contributor to an open-source project, Jetbrains allows you to apply for a [free open-source license](https://www.jetbrains.com/buy/opensource/)! 30 | 31 | **That's super useful. Thank you! So, you're a maintainer for C#, F# and Scala. What particularly draws you to those languages?** 32 | 33 | C# immediately became my favorite language when it was released in 2002. It is a well-designed, elegant language with great tooling and documentation. The language also evolves quite rapidly, which means that there are always new things to learn! One last plus is that it runs on the excellent .NET (Core) framework. 34 | 35 | F# was also love at first sight. With elegant syntax and a rich set of (functional) language features, I found that I could do more with less code, particularly when doing domain modeling. It is also a very pragmatic language, with object-oriented features and great interop with existing .NET code (it runs on the same .NET (Core) framework that C# does). An additional strength is its tooling, which is amongst the best available for functional languages. As a bonus, it also has one of my favorite language introductions ever in the [fsharpforfunandprofit](https://fsharpforfunandprofit.com/) website. 36 | 37 | Scala was the language that introduced me to functional programming, so for that reason it holds a special place in my heart. Like F#, it is a pragmatic language, for much the same reasons. With its integration into Java's ecosystem, it has really helped popularize functional programming. 38 | 39 | **It's interesting that you got started with functional programming through Scala, mentor F#, but rate Haskell as the best track. For someone who wants to take the dive into functional programming on Exercism, which of those would you recommend they try first?** 40 | 41 | Great question! My vote goes to F#, as I feel it is the easiest language to pick up. This is mainly due to the F# language being less complex than the other two. F#'s excellent tooling and documentation are also a big plus when getting started. That said, I do highly recommend also joining the Haskell track once you're done with the F# track, as Haskell has some fantastic, advanced features that F# doesn't have. 42 | 43 | **You've been privy to quite a lot of our plans for the future of Exercism. Is there anything you're particularly excited about for the project?** 44 | 45 | Of all the improvements being planned, I'm most excited about the static analysis of solutions. The idea is that we'll setup a system that can automatically comment on submitted solutions, by programmatically analyzing those solutions for common issues/suggestions. This should help mentors a lot, as they would no longer have to comment on these common issues/suggestions and can focus on more interesting problems. 46 | 47 | If you're interested, check out my (early) prototype of a [C# track analyzer](https://github.com/erikschierboom/exercism.analyzers.csharp), which uses the [.NET Compiler Platform](https://docs.microsoft.com/nl-nl/dotnet/csharp/roslyn-sdk/) to statically analyze C# code. 48 | 49 | **Yes, the static analysis is pretty much the most exciting thing for me too. It's awesome to see that you already have a prototype together. I think the speed improvements that static analysis will give us will dramatically improve Exercism, and I'm really excited about how we can extend it to teach total beginners to code. I think it's a real game-changer.** 50 | 51 | **Final question, do you have any personal projects or causes that are close to your heart, which you'd like to give a shoutout too?** 52 | 53 | To me, getting involved in Exercism, contributing to its open-source code base and mentoring people has been an incredibly rewarding experience. I've learned tons of things, got to know some pretty great people and feel I have been able to help many people. 54 | 55 | I would like to encourage people to see if they can get involved too. If you have a language you are passionate about and want to help people learn—sign up as a mentor on Exercism. If you prefer writing code, choose an open-source project and contribute. I promise it is far less scary than it sounds and you'll feel great doing it! 56 | 57 | **Awesome! Thank you for taking the time to chat and for all your work on Exercism!** 58 | 59 | -------------------------------------------------------------------------------- /posts/interview-with-meade-kincke.md: -------------------------------------------------------------------------------- 1 | _An interview with [Meade Kincke](https://exercism.io/profiles/TheDarkula) in which he and Katrina Owen talk about the Rust compiler, a GUI that uses scientific colourspaces to determine the colour of beer, and his book 'A Practical Guide To Rust'._ 2 | 3 | **Hey Meade. Thanks for chatting. We wanted to talk with you because you’re the most prolific mentor that we have on the Rust track. You've helped over 400 students. How did you find out about Exercism?** 4 | 5 | Someone on Reddit's Rust subreddit posted about how Exercism's Rust track needed mentors, so I looked into it. I'm so glad that I did because it's immensely rewarding and everyone has been so nice and appreciative. I've made some wonderful connections with my Exercism students, and I love helping them. 6 | 7 | **Are there any particular stories that stand out?** 8 | 9 | Yes, there's one particular Rust exercise that has been very popular: the Pythagorean Triplet. 10 | 11 | The most common problem in this exercise tends to be performance. Most people solve it initially with nested `for` loops, which is at least O(n²) and is very inefficient. My goal is to get my students to a linear solution: O(n). 12 | 13 | My approach is to pose questions. I begin by asking if they want to learn Rust's iterator method because it has a ton of benefits, one of which is that you can use the Rayon library to parallelize your work. 14 | 15 | After answering, "Yes, please," one of my students mentioned that he is learning Rust because he's looking at using it for embedded control and then to process its massive data output. Thus, parallelism is important to him. He was pleased that I took a seemingly simple exercise to teach more complex and idiomatic bits of Rust. 16 | 17 | Now, thanks to Exercism, he's hired me on to teach him one-on-one, and we're going to work together on some experimental projects. I will also be teaching his entire team when he fully converts the company to Rust. 18 | 19 | I've really enjoyed working with the students that I've mentored, and I want it to continue growing. 20 | 21 | I like it so much that now I've volunteered to be a maintainer on the Rust track and help more behind the scenes. 22 | 23 | **That human connection is so important! You're the author of [A Practical Guide to Rust](https://www.kobo.com/us/en/ebook/a-practical-guide-to-rust). What is that about and what were your motivations for writing it?** 24 | 25 | I wrote this book to help others better understand certain aspects of [Rust](https://www.rust-lang.org/). There's not a whole lot of documentation out there on the language, and I felt there needed to be literature that had humor and explained the concepts of the language tangibly. It provides guides to some basic and advanced areas. I want people to get a solid sense of the practical, real-world use for the language. It gives real examples, not hypothetical ones. 26 | 27 | I always knew that I was going to write a book. When I found myself teaching a colleague how to program in Rust remotely, the framework just fell into place. He had never touched any code before, and I needed to explain terms and methods that us nerds take for granted in new perceivable ways. I used analogies like borrowing a book from the library vs. owning the book when discussing the concept of ownership in Rust. 28 | 29 | I also incorporated examples from my project [BrewStillery](https://gitlab.com/MonkeyLog/BrewStillery). It's a great way to see how things like structs and enums function in an actual program. It also shows how to use parallelism in a real way. 30 | 31 | When writing the book, I knew I wanted it to read like a story instead of just a reference guide. It builds on itself, but the elements do stand alone. It's the difference between cooking with a chemistry manual vs. watching an episode of Julia Child's "The French Chef." 32 | 33 | **Oh, that's intriguing. Who did you write your book for and what would the reader get out of it?** 34 | 35 | It's intended for anyone who wants to learn Rust. The equalizer with how I elaborate ideas is that it gives the reader a fundamental comprehension, whereas a great deal of other literature leans toward rote memorization. 36 | 37 | **I see you've received a lot of positive reviews. Are you planning on putting out a Volume II?** 38 | 39 | Yes! I will, of course, continue writing and plan on publishing more volumes. 40 | 41 | **Aside from teaching through mentorship and writing, you've also done some work on the Rust compiler. Can you tell me about that?** 42 | 43 | Of course! 44 | 45 | As a brief introduction to my work, there are essentially two places that a program can function: compile time and runtime. When a function is executed at runtime, everything in it has to be regenerated and recomputed. This critically means reallocating memory, which we always want to avoid. When a function is constant, it is loaded into memory when the program is started. The more we can do at compile time, the better our programs will perform. 46 | 47 | A while back, I heard that this idea of [compile time function execution (const fn)](https://en.m.wikipedia.org/wiki/Compile_time_function_execution), was being implemented in Rust, and I got really excited. I'm very passionate about getting things to be efficient and accurate. One thing I really like about `const fn` is that when it's complete, we can have wonderful things like mathematical constants determined elegantly. Currently, [pi](https://doc.rust-lang.org/src/core/num/f64.rs.html#83) is a hard-coded value. A lot of people would say that this is accurate enough, but I feel that it should use the entirety of the available numeric space. With `const fn`, we can use [Leibniz's formula](https://en.wikipedia.org/wiki/Leibniz_formula_for_%CF%80), which would fill the floating-point space completely. 48 | 49 | I did a bit more reading and came across a blog post saying that [MIRI](https://github.com/solson/miri) would make stabilizing `const fn` much easier. Time went by, and I didn't see any progress when new versions were released. I contacted the Rust team and got started hacking on the compiler. 50 | 51 | The great thing is the compiler itself is written in Rust. It was initially written in OCaml and then rewritten in Rust, which is called bootstrapping. Basically, the compiler parses all input in the [AST](https://en.wikipedia.org/wiki/Abstract_syntax_tree), which is then handed off to the [high-level intermediate representation](https://en.wikipedia.org/wiki/Intermediate_representation) (HIR), then medium-level (MIR), and then low-level (LIR), which is handled by [LLVM](https://en.wikipedia.org/wiki/LLVM). As we walk through all those steps, we get closer and closer to machine code. 52 | 53 | Something to understand is that the compiler is just a program, but a very elaborate one. Rust takes quite a while to compile and especially to run all of the tests for it. So you don't just slap some code in and get to say, "I'm done." 54 | 55 | My first work on the compiler was on the HIR. It involved a tremendous amount of reading through the standard library (both stable and nightly) and following rabbit holes. I had to recurse all the way down through every nested type in the compiler until I had exhausted all options. The nightly/compiler library has a ton of nested types. Keeping what thread you're following down requires a lot of focus. 56 | 57 | To make matters more complicated, the compiler is worked on by a distributed team, which means that we often end up with merge conflicts. 58 | 59 | It was so much fun. There's still a ton of work to be done, which I'll get to in the near future. 60 | 61 | **In addition to these open source contributions, I know you're CTO of a blockchain company. I associate blockchain with me losing lots of money on Etherium. What does it mean to you?** 62 | 63 | Blockchain has, unfortunately, become the buzziest buzzword that ever did buzz. 64 | 65 | It is much more than The City and Wall Street cashing in on a new trend for digital currency. We are actually not a “blockchain company”, we at [Chainetix](https://chainetix.com/) provide private ledgers to secure a company’s data securely. In fact, we don’t even deal in crypocurrency. The aim at Chainetix is to bring our expertise into the hands of everyone who has a basic understanding of programming. 66 | 67 | My work has involved mapping out our systems and infrastructure from scratch to create something rock-solid. I chose a project called [Habitat by Chef](https://www.habitat.sh/). I found out about it because it's written in Rust, which was intriguing coming from such a huge company like Chef. In contrast to plain Docker, Habitat creates images that can automatically update themselves and do amazing things like service bindings. I've also contributed quite a bit to Habitat's [core-plans](https://github.com/habitat-sh/core-plans/) repository. 68 | 69 | **Earlier you mentioned your project, BrewStillery. It sounds like it's important to you. Can you tell us a bit more about that?** 70 | 71 | Yes, it definitely is! 72 | 73 | [BrewStillery](https://gitlab.com/MonkeyLog/BrewStillery) is an open source, all-in-one beer, wine, and spirits tool that I wrote in Rust and [GTK3](https://gtk-rs.org/). I also added a CSS theme that is beautifully unique. In a sentence, it's an advanced calculator for anyone making spirits. 74 | 75 | I’ve created different tabs to separate the calculators that are specific to beer and champagne while having a general tab that applies to brewers, vintners, and distillers alike. If you look at most beer and wine bottles, you’ll see the percent of alcohol in that bottle—the Alcohol By Volume. Well, one of the things that BrewStillery does is determine that ABV. As you can probably guess, there’s a bunch of nerdy awesomeness involved here. The thing I'm most pleased about is calculating the beer color: 76 | 77 | ![BrewStillery Beer Tab Empty Glass](https://assets.exercism.io/blog/introducing-thedarkula-BrewStillery_Empty_Glass.png) 78 | 79 | ![BrewStillery Beer Tab Full Glass](https://assets.exercism.io/blog/introducing-thedarkula-BrewStillery_Full_Glass.png) 80 | 81 | These before and after images show what happens after you’ve entered amounts. The way I’ve done it is something that no one’s done previously. Another great feature is that it’s all calculated on the fly as you type. If you want the gritty details about colorspaces, hit me up at a conference and we can talk about it over pints! 82 | 83 | -------------------------------------------------------------------------------- /posts/interview-with-ryan-potts.md: -------------------------------------------------------------------------------- 1 | _An interview with [Ryan Potts](https://exercism.io/profiles/rpottsoh) in which he and [Jeremy Walker](https://exercism.io/profiles/iHiD) discuss Delphi, the things he's learnt from being a contributor to Exercism, and his experiences of programming in industries that are still "offline"._ 2 | 3 | **Hi Ryan. Thanks for taking the time to chat with me. You're the maintainer of the Delphi track on Exercism. How did you get into Delphi?** 4 | 5 | I work for a company that my father founded, which has been developing software since the 80's starting with Microsoft Pascal then later using Borland's Turbo Pascal. I came to work at the company in '96, about this time it was receiving requests to produce software that would run in Windows, instead of DOS. Conveniently enough Borland had recently released Delphi 1. This was a perfect fit for us as most of the units that had been developed over the years could still be used. No longer were we faced with having to start all over in VB or VC to support Windows. 6 | 7 | **And you still use Delphi day-to-day now?** 8 | 9 | Yes, where I work produces machines for R&D testing and small batch testing in the automotive industry; testing tires, car seats, airbag inflators, as well as crash testing. All of the systems produced are used by several car manufacturers around the world as well as by their suppliers. 10 | 11 | The software I work on is used for controlling these various types of machines. I develop the UI, figure out the test sequences for the automated portions of the tests, integrate the various input and output points, both analog and digital. It needs to be as user-friendly as possible so a person with minimal training can feel pretty comfortable using it. 12 | 13 | The work I do requires no web programming at all. Everything I do is in Delphi on Windows. Occasionally I have to whip up a small "custom command" in C++ that I then upload into the data acquisition processor board, which is a parallel computer that resides in a PCI slot in the computer; it has its own CPU, memory, and OS. 14 | 15 | **It's fascinating to chat with someone who does no web programming at all. That feels pretty unusual today, but I wonder if that's just the signal/noise ratio that I hear about day-to-day rather than a reflection of the industry.** 16 | 17 | Yeah, being involved in Exercism has allowed me to see a little bit into how the "other half" lives in the computer industry. I have learned a lot about Test Driven Development (TDD), navigating GitHub, and working on an open source project. A lot of what I have learned has improved the quality of the work I do on the job. 18 | 19 | **That's really great to hear. One of the things I love most about Exercism is that "how the other half live" vibe—realizing all your blind-spots and learning about things you had no idea even existed. I imagine being a track maintainer has enhanced that learning even more?** 20 | 21 | It has. I am writing more tests than I use to. It isn't always TDD per se, sometimes the tests come second instead of first. However, it has influenced how I structure code, removing unnecessary dependencies to make testing easier. 22 | 23 | I spend a lot of time reviewing issues and PRs in the problem-specifications repository, which is where we define Exercism exercises in a language-independent way. I've learned a lot from the discussions. Sometimes a suggested change seems straightforward on the surface, but the ensuing conversation uncovers issues. I've developed more patience. It's taught me to look for other potential angles to technical problems at work. 24 | 25 | I've also learned more about mentoring, in particular, the importance of knowing the underlying why as opposed to just the how. I work with a handful of other programmers. Even though I'm younger than most of them, I've been at the company longer than they have, and I can often point out a more efficient tack to take for sequencing the operation of a machine or explain why something needs to be performed in a particular way. 26 | 27 | **Wider than Exercism, you're also a Delphi MVP, which is pretty awesome! How did that come about? Is there a strong Delphi community that you're part of?** 28 | 29 | During the initial stages of setting up the Delphi track, I reached out to Mr. Jim McKeeth at Embarcadero to see if we could get an open source license for Delphi. This would permit us to use Delphi to develop new exercises and allow people to contribute via pull requests. Jim invited me to join the Embarcadero MVP Program in the course of our correspondence. 30 | 31 | [Delphi Praxis](https://en.delphipraxis.net) is an online community that I am familiar with. There is a lot of traffic on Google+, but it's on the way out, so we have to go elsewhere. 32 | 33 | **Have you built any open source apps in Delphi that others could take a look at?** 34 | 35 | I have! [Exercism's Windows CLI Installer](https://github.com/exercism/windows-installer/releases) is open source and written entirely in Delphi. It automatically determines the correct version (32/64 bit) of the Exercism CLI the student needs then downloads the CLI, extracts it, and puts it in the right place. The installer has been downloaded 15,000 times, which I'm pretty proud of! 36 | 37 | **That's a fantastic achievement! As someone who doesn't do much (if any) internet programming, what challenges did you face while creating the installer in Delphi?** 38 | 39 | The installer was initially written in C#. It was outdated, and I decided to see if I could improve on it. I had never attempted anything like this before but knew Delphi had the tools to get the job done. I started by studying the original C# code to gain an understanding of what sequence of events was taking place behind the scenes and then try to accomplish the same tasks in Delphi. I found sample code on Embarcadero's documentation site that helped explain how to properly string together the available components for creating a REST client. I also discovered a handy utility provided with Delphi called REST Debugger. It allowed me to input and thus test the various HTTP calls that are needed to make the installer successful. Once they're working the debugger will then create copies of the required components so that I could paste them into the code. 40 | 41 | **For someone looking to get deeper into Exercism, maybe someone who hopes to become a maintainer, can you tell us about what your journey was?** 42 | 43 | I am a member of a local MeetUp group called the Akron Code Club. About once a month we meet and usually pair off and work a code kata that has been suggested to the group. At the August 2016 meetup, we started working exercises provided by Exercism. As I used Exercism and some of the other teaching sites, I thought it would be nice if more of these online programming sites would offer Delphi or Pascal as an option. After looking around the Exercism site and Exercism GitHub repos, I discovered that Exercism is always interested in adding new language tracks. I wasn't quite sure how best to contact Katrina. I think I used Gitter to reach out to her in August '16) proposing the addition of Delphi. I received an apologetic response about two months later—which is when I realized she doesn't Gitter. Anyway, she wondered if I was still interested in working on adding a Delphi Pascal track and if so would get the ball rolling. 44 | 45 | Now there's a repository you can use to request a new language track, and you can always open issues in the exercism/exercism repository to get in touch with the maintainers of the project. 46 | 47 | **Great. Thank you for chatting to me, and for all your work on Exercism!** 48 | 49 | My pleasure! This has been fun. I enjoy taking part and doing what I can for Exercism. Learning by doing! 50 | -------------------------------------------------------------------------------- /posts/introducing-48in24.md: -------------------------------------------------------------------------------- 1 | New year, new challenge! 2 | 3 | It’s 2024 and I’m really excited to announce that we’re rolling out a whole new year-long challenge to keep you motivated on your programming journey - [#48in24](https://exercism.org/challenges/48in24)! 4 | 5 | Now, don’t panic, we’re not upping the game and asking you to learn 48 programming languages this year to replicate what we did with #12in23 - that would be ridiculous even by our standards. Instead, we’re challenging you to solve and dig into 48 different exercises throughout the year. 6 | 7 | Each week we’re going to be unveiling a new featured exercise for you to try out. And for each exercise you can earn three awards: 8 | Bronze: Completing the exercise in any language. 9 | Silver: Completing the exercise in any three languages. 10 | Gold: Achieving silver plus having completed (either historically or this year) the exercise in the three featured languages. 11 | 12 | You can complete the exercises at any time during the year. However, we’re going to try and mix up the difficulties and types of tasks throughout the year, so if you complete them in order, it should feel like a more interesting and varied experience! 13 | 14 | The aim isn’t just for you to solve the exercise, but to take the opportunity to really dig into the different ways the exercise can be solved - consider different tradeoffs and approaches, and ideally try it in different languages (e.g. try an OOP approach, a functional approach, a logic-based approach, etc). We’ll be encouraging people to request mentoring on the exercise and discuss it on the forum and Discord. 15 | 16 | We’re also going to be using this opportunity to focus our contributing community on adding content around each featured exercise. In advance of the weekly unveiling, we’ll be asking the community to write new Approaches and Articles, record walkthroughs, and ensure the exercise is up to date for that track. As a core team, we’ll also be checking and improving the exercise instructions and recording our own language-agnostic explorations of the exercises, looking at some of the interesting different ways they can be solved. 17 | 18 | Exercises will be released on Tuesdays and the first will be January 16th. We’ll then continue releasing one per week until we hit 48 in December, giving people the last couple of weeks of the year to tie up any loose ends (and have a holiday!) 19 | 20 | You can sign up for the challenge at [https://exercism.org/challenges/48in24](https://exercism.org/challenges/48in24) - see you inside! 21 | -------------------------------------------------------------------------------- /posts/introducing-community-comments.md: -------------------------------------------------------------------------------- 1 | Last year we rebuilt [Exercism](https://exercism.io) with a new focus around more formal mentoring. As part of that change we disabled the ability for the wider community to comment on each other's solutions. The logic for that was a desire to keep the learning experience in more private, safe spaces, and avoid random unsolicited comments from strangers. 2 | 3 | I'm now happy to announce that we've reintroduced community comments on solutions. Our rational for this is that others' solutions provide a valuable learning opportunity, and we want to give people the ability to ask questions about ideas or techniques they see in solutions. We actively don't want this to be a second-stage of public mentoring, and as such we've added a notice to remind commenters of the purpose of the box: 4 | 5 | ![Comment warning](https://assets.exercism.io/blog/introducing-community-comments-warning.png) 6 | 7 | We also know that many users do **not** want others to be able to comment on their solutions. They might still want to make them public, but don't want the extra interactions, or the "messiness" of having others' thoughts on their showcased work. We've therefore added an option to turn commenting on or off per solution, which can be accessed through the "Manage Public Solutions" option on your profile. To make this quicker, we've added a global option to set a default for new solutions. Next time you log in, you'll see a modal asking you what you would like to set your default to: 8 | 9 | ![Global commenting option](https://assets.exercism.io/blog/introducing-community-comments-option.png) 10 | 11 | In parallel, we've also replaced the "reactions" that we launched last year with a more simplified starring system. If you see a solution that you like you can quickly star it (top right of the page) and it will then appear on your "Starred Solutions" page available via the main menu under your avatar. We had initially introduced this feature as an interesting way to group solutions by different people's reactions, but we now have more extensive plans to group solutions using static analysis of the code, and so have decided to retire this feature and simplify the user experience. 12 | 13 | You can find others solutions via the "View community solutions" link once you've finished being mentored on a Core Exercise, or once you've submitted a Side Exercise. Keep an eye out for something like this: 14 | 15 | ![Link to community solutions](https://assets.exercism.io/blog/introducing-community-comments-link.png) 16 | 17 | We hope you'll get lots of enjoyment from community solutions and benefit from learning from others' work. If you run into any problems, please open an issue on our [GitHub issue tracker](https://github.com/exercism/exercism). Thanks for reading! 18 | -------------------------------------------------------------------------------- /posts/introducing-representers.md: -------------------------------------------------------------------------------- 1 | We've now fully launched the second part of our automated feedback strategy - Representers! 2 | This post gives a quick overview of how they work and why they're so useful. 3 | It's a little more technical than normal, so strap in tight! 4 | 5 | ## What is a Representer? 6 | 7 | A Representer is a piece of software that takes a student's solution and returns a normalized representation of it. 8 | We then use these representations to streamline automated feedback and classification. 9 | 10 | An example helps to explain Representers best. 11 | Let's presume two students submit two submissions to the `hello-world` exercise in Ruby: 12 | 13 | ```ruby 14 | # Student 1's submission 15 | def self.hello(name = 'World') 16 | "Hello, #{name}!" 17 | end 18 | ``` 19 | 20 | ```ruby 21 | # Student 2's submission 22 | def self.hello(nom='World') 23 | "Hello, #{nom}!" 24 | end 25 | ``` 26 | 27 | Although the code to these solutions is different (different indentation, variable names, and string syntax), they are essentially the same. 28 | So by creating a normalized representation of them, we can _treat_ them as the same for the purposes of providing feedback. 29 | 30 | ## Why is this useful? 31 | 32 | By creating these normalised representations, we can ensure that feedback given on one submission is automatically applied to other similar solutions. 33 | This means that as a student you're much more likely to get instant, highly-relevant feedback. 34 | And as a mentor you should now never need to give the same feedback twice to a similar solution - you do it once in the Automation UI and the rest works magically. 35 | 36 | We can also use Representers and our existing Analyzers together. 37 | Analyzers can comment on general points (such as variable names, linting, etc) and representations can focus on the wider changes that should be made. 38 | There's a huge amount of potential that we're only just scratching the surface of. 39 | 40 | ## Who can add feedback? 41 | 42 | The ability to add feedback to representations is limited to our super-mentors, about 150 individuals who have mentored hundreds of students and maintained a high mentor rating. 43 | 44 | If you're a super mentor, you should now find the "Automation" tab unlocked on your Mentoring Dashboard, which you can use to access solutions that can have feedback given to them. 45 | Please read the docs carefully as there's a lot of subtlety in doing this well! 46 | 47 | ## What's left to do? 48 | 49 | There are a few new features for Representers that we'll be rolling out over the coming weeks and months. 50 | We'll be posting information in our Forum (such as [this post on updating Representers](https://forum.exercism.org/t/updating-representers/442)) so keep an eye out there. 51 | 52 | ## Building a Representer 53 | 54 | If you are interested in building a Representer, checkout out the [Representer documentation](/docs/building/tooling/Representers) for more information, or start a new topic on [our forum](https://forum.exercism.org/c/exercism/building-exercism/125) if you want to ask questions! 55 | -------------------------------------------------------------------------------- /posts/introducing-the-exercism-blog.md: -------------------------------------------------------------------------------- 1 | Each day [Exercism](https://exercism.io) gets hundreds of new users, thousands of new submissions, and dozens of improvements across its language tracks and product. However, it's become apparent that few of you have visibility on that activity and all of the great stuff that's happening. Our [Contributors](https://exercism.io/team) work tirelessly improving tracks and mentoring people but unless you are on the Exercism team Slack room and read all the channels (which I'm pretty sure I'm the only person who does), you get very little insight into all the activity that's happening. Not only is this a bit sad, it gives the impression to many that Exercism is dead (when it's growing faster than ever) and it also means that the contributors have no way to tell their friends, colleagues or the wider world about all the work they're doing. 2 | 3 | To solve this we're launching the [Exercism blog](https://exercism.io/blog). It will contain a variety of content, including: 4 | - Updates on new features and improvements to the Exercism website 5 | - Interesting technical articles regarding the languages we support 6 | - Walkthroughs of interesting approaches to exercises 7 | - Interviews with members of the Exercism community 8 | - Insights into key changes happening on the tracks 9 | 10 | We are also planning to launch a weekly Exercism newsletter in the coming weeks, which will contain the most popular posts from our blog. 11 | 12 | If you'd like to write for our blog or have any ideas for articles, please open an issue at our [blog repository on GitHub](https://github.com/exercism/blog). 13 | 14 | We really hope you enjoy this! 15 | -------------------------------------------------------------------------------- /posts/jurassic-july.md: -------------------------------------------------------------------------------- 1 | # Jurassic July 2 | ## Introduction 3 | Hello. Welcome. Hope you’re all doing well 4 | June’s been a big month at Exercism with the launch of Premium and our 10 year anniversary. 5 | And I hope you’ve had fun playing with Lisps during the Summer of Sexps. 6 | Now onto Month 7 of 2023, and our 6th themed month - Jurassic July. 7 | 8 | What do we mean by Jurassic? 9 | Well, not that these languages are extinct - although you’re unlikely to be writing new software in COBOL now-a-days 10 | But these are some of the oldest languages - some over 60 years old. 11 | An incredible amount of software (especially enterprise software) has been written in them. 12 | They’re all incredibly successful languages. 13 | 14 | So what are the languages: Well we’re looking at C, C++, COBOL, Fortran and Visual Basic. 15 | We’re not going to be exploring C and C++ in this video as we already covered them in Mechanical March - so check that video out if you’re interested in those languages. But we’ll be looking at COBOL, Fortran and Visual Basic in a bit! 16 | 17 | ## The badges 18 | 19 | Get the badge by completing 5 exercises in one of those this month. 20 | And for the year-long badge, you need to complete: 21 | - **Bob**: work with strings and conditional logic 22 | - **Allergies**: work with strings, numbers and bitwise operations 23 | - **Reverse String**: iterate over the characters in a string 24 | - **High Scores**: iterate over arrays of numbers 25 | - **Armstrong Numbers**: work with numbers and looping/iteration 26 | 27 | ## Overviews 28 | 29 | ### Fortran 30 | - Initiated by John Backus at IBM in the 1950s to develop a more practical alternative to assembly language for programming their IBM 704 mainframe computer 31 | - Designed to be good at building scientific and engineering applications (name is short for Formula Translating System) 32 | - First high-level programming language (reduces lines of code by about a factor 20) 33 | - Also the first optimizing compiler (customers were reluctant to use a high-level programming language unless its compiler could generate code with performance approaching that of hand-coded assembly language) 34 | - Static and strongly typed language 35 | - Initially only supported imperative programming, but procedural programming was added soon after that. Later extensions added support for other paradigms, like object-oriented programming and array programming 36 | - Standardized, first in 1966 with Fortran 66, and last updated in 2018! 37 | - Highly influential, from Basic to ALGOL, inspiration for many languages. Much of the early programming language research aimed to help improve Fortran 38 | 39 | - Still being actively developed, with new features being added, whilst still having strong backwards compatibility guarantees (old code usually still compiles and runs) 40 | - Built-in parallelism using coarrays, a safe and efficient method of expressing parallelism. Functions can be marked as pure, which helps the compiler optimize for parallel computing 41 | - Safe memory handling using allocatable variables, where the compiler is responsible for freeing memory. 42 | - Built-in interoperability with C 43 | 44 | ### COBOL 45 | - Designed in 1959 by the CODASYL consortium (sponsored by the Department of Defense!) in an effort to lower the costs of developing business applications (name stands for Common Business-Oriented Language) 46 | - Became a standard in 1968, with the latest revision from 2014 47 | - Different implementations, such as IBM COBOL, GnuCOBOL (which compiles to C) and Micro Focus™ Visual COBOL, which runs on both the JVM and .NET runtime 48 | - Statically typed language 49 | - Multi-paradigm, supports imperative and object-oriented programming 50 | 51 | - Verbose (many keywords) but very human readable syntax. Benefits readability and maintenance 52 | - Good backwards compatibility, with a stable specification. Battle-tested 53 | - Good performance (used in finance) 54 | 55 | ### Visual Basic 56 | - Developed by Microsoft as successor of Visual Basic that runs on the .NET runtime (the .NET suffix was dropped after Visual Basic 2003) 57 | - First version was released in 2002 and the language was marked as “stable” in 2023. This means that no new syntax will be added to the language, but it is still a supported language 58 | - Mostly shares syntax with Visual Basic, but some changes were made 59 | - Statically typed language that supports strong and weak typing 60 | - Multi-paradigm language: primarily object-oriented, but also imperative and event-driven programming 61 | 62 | - Easy to learn (Visual Basic was designed to be easy to learn) 63 | - Excellent support for object-oriented programming 64 | - Runs on tried-and-tested .NET runtime, with access to all .NET libraries 65 | - Easy deployment with ClickOnce deployment 66 | 67 | ## Use cases 68 | 69 | ### Fortran 70 | Used in high-performance computing scenarios (supercomputers), such as weather forecasting, astronomy and structural engineering. It is also used in CAD software and many applications build on FORTRAN, e.g. various NumPy modules use FORTRAN 77 libraries 71 | 72 | ### COBOL 73 | Used a lot in finance, with many financial systems still running in large parts on COBOL software (estimates say around 80% of financial transactions are powered by COBOL), although it’s mostly maintenance nowadays. Also used for many business applications, and even a key/value store used at Walmart. 74 | 75 | ### Visual Basic 76 | Used for GUIs (e.g. interface to databases) and server-generated websites. Companies include Boeing, Wells Fargo and General Electric 77 | 78 | ## How do they differ from a programming perspective? 79 | 80 | ### Fortran 81 | Initially only supported imperative programming, but procedural programming was added soon after that. Later extensions added support for other paradigms, like object-oriented programming and array programming 82 | 83 | ### COBOL 84 | Multi-paradigm, supports imperative and object-oriented programming 85 | 86 | ### Visual Basic 87 | Multi-paradigm language: primarily object-oriented, but also imperative and event-driven programming 88 | 89 | ## Standout features 90 | 91 | ### Fortran 92 | - Performance. The Fortran language and its data types/data structures are designed to be efficient/have great performance. This being used in supercomputers 93 | - By default, supports many mathematical functions 94 | - Array programming is a very neat way to apply operations on arrays and sections of arrays without having to do any manual iteration or specifying array boundaries 95 | 96 | ### COBOL 97 | - Fixed-point arithmetic doesn't have rounding errors, unlike floating point numbers. This makes it great for finance 98 | - Great for reading from and writing to files (records) 99 | - COBOL built-in support for generating reports (which is another reason why it has been popular in business applications) 100 | 101 | ### Visual Basic 102 | - Excellent for building GUI applications using Windows Forms. Drag and drop WYSIWYG editor 103 | - Great IDE support, with refactorings, code completion and tons more 104 | 105 | ## Which to try? 106 | 107 | - If you’re interested in scientific computing or high performance, Fortran is an excellent choice 108 | - If you want a feel for how business applications used to be built, COBOL is great 109 | - If you are interested in building GUI applications or are already on the .NET platform, Visual Basic works really well 110 | - If you are interested in the history of programming, COBOL and Fortran are both nice tracks to check out 111 | 112 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /posts/mozilla-supports-exercism-static-analysis.md: -------------------------------------------------------------------------------- 1 | Last week we wrote a blog post announcing the [Automated Mentoring Support Project](https://exercism.io/blog/automated-mentoring-support-project) and discussed our plans for adding [static analysis](https://en.wikipedia.org/wiki/Static_analysis) to Exercism. Following on from that, we're incredibly excited to be able to now publically announce that we have been awarded a [Mozilla Open Source Support Award](https://www.mozilla.org/en-US/moss/) to support this project. 2 | 3 | The grant will help fund three key areas of our static analysis work: 4 | 1) The product design and development to allow static analysis to work alongside mentoring within the Exercism UI 5 | 2) The infrastucture required to run static-analysis and the integration of this into the submission pipeline 6 | 3) A proof-of-concept for Two Fer in Ruby that will give us reference documentation for other languages/exercises 7 | 8 | We're extremely grateful to Mozilla, and excited to be able to dedicate some full-time people-power to the product and infrastructure sides of the project, which will be so important moving forward. We feel that this addition of static analysis to [Exercism](https://exercism.io) will dramatically increase our ability to serve a wider community and make mentoring a more enjoyable and rewarding activity. 9 | -------------------------------------------------------------------------------- /posts/oversubscribed-tracks.md: -------------------------------------------------------------------------------- 1 | One of the biggest challenges we face is tracks getting too popular and our mentors being unable to cope with the volume of submissions. The wait time for students increases, and mentors have the very unsatisfying experience of seeing queues keep growing despite putting a huge amount of work in to try and keep on top. 2 | 3 | Solving this is far from trivial, but we believe we have some good solutions that will make things better (see our [recent blog post](https://exercism.io/blog/whats-next-for-exercism-aug-2019) for details). However, these will all take time to implement, and there is a very real problem today. 4 | 5 | We've therefore decided to add an "Oversubscribed" status to tracks, where when the median wait time for core exercises becomes too long, we: 6 | - Only allow students joining a track to use Practice Mode, not Mentored Mode 7 | - Stop students in Practice Mode from requesting mentoring on their solutions (they can continue to use Practice Mode independently) 8 | 9 | Once a track gets its median wait time back under control, the system will automatically allow new students to join Mentored Mode, and allow Practice Mode students to submit solutions for mentoring. 10 | 11 | These changes have no effect on students already working in Mentored Mode. 12 | 13 | There are lots of extra bits of functionality we could add to this (e.g. queues to join, notifications when tracks unlock), but for now we're just taking a somewhat brute-force approach to fix the main pain point. 14 | 15 | Hopefully this will give a better experience and more realistic expectations to students, remove the pain of ever-growing queues for mentors, and allow us to focus on implementing the bigger changes that will make a more long-term impact. 16 | -------------------------------------------------------------------------------- /posts/redesigning-tracks-in-partnership-with-chicago-university-and-sloan-foundation.md: -------------------------------------------------------------------------------- 1 | As we discussed in our [blog post last month](https://exercism.io/blog/whats-next-for-exercism-aug-2019), one of our key goals for the next year is to restructure tracks for both student enjoyment and ease of mentoring. We've made huge progress with this over the last year with the Track Anatomy project spearheaded by Maud de Vries, and out of this we've identified some fundamental problems with how tracks are structured, which we believe need addressing as a priority. Over the last two months, the leadership team have been discussing how we should approach this, and what needs to happen to bring our tracks into the necessary state to offer idiomatic learning of different languages in a timely manner. 2 | 3 | Today, I'm really excited to announce that we are launching a project in association with James Evans and Gary Lupyan from The University of Chicago, sponsored by the Sloan Foundation, which will allow us to put some serious focus and energy into rethinking Exercism's tracks from the ground up, and executing those changes in a number of languages. In addition, I'm delighted to announce that we've hired [Erik Schierboom](https://www.erikschierboom.com/about/) to lead the project. 4 | 5 | ### Background 6 | 7 | For the last two years, James and Gary have been investigating how the languages that a programmer uses affect their efficiency, creativity, and collaboration. Supported by [a grant from the Sloan Foundation](https://sloan.org/grant-detail/8001) they have determined that a crucial part of this research is understanding how programmers learn different languages, and how one's existing knowledge helps or hinders new learning. This is the exact question that we have been asking ourselves regarding language tracks on Exercism. How does someone's previous experience affect the pathways they need in our tracks and the style and substance of mentoring they respond best to? 8 | 9 | James, Gary, and The Sloan Foundation have decided to invest some of their resources into enabling Exercism to focus energy into redesigning our tracks to become more focused on a language's uniquenesses and to become more personalised based on the student's existing experience. 10 | 11 | ### The Project 12 | 13 | We will be blogging much more about this in the coming weeks and months, but I want to outline the main aims that we're hoping to achieve with this project, and how they will affect Exercism. 14 | 15 | **Rethinking the cores of Tracks:** Our tracks aim to teach programming languages, not programming itself. We intend to encode this into our tracks, rethinking our core pathways to focus them around, specifically teaching the idioms that make a language unique. We intend to design and develop new exercises that specifically focus on one idiom each. For example, in Ruby, we might have an exercise that teaches enumeration rather than looping, or in JavaScript the concept of Prototypes or Binding. 16 | 17 | **Develop comprehensive automated-analysis coverage of core exercises:** We want a student to be able to pass through the core of a track rapidly. In designing exercises, we will deliberately focus on how we can provide 95% automated analysis coverage to the possible solutions. This means that the interactions that mentors have will be with the 5% of students that really need their help, or on more interesting and varied side exercises. As part of this, we want to develop tools that enable our mentors to contribute to the automated analysers without having to dig into the codebase. 18 | 19 | **Offer bespoke automated mentoring and mentoring hints based on previous experience:** Once we have completed the previous steps, we want to explore tailoring the feedback that a student gets to their previous experience, either in terms of the automated responses they receive or in terms of hints we give to mentors. The feedback someone needs when learning a specific language depends heavily on their previous knowledge. Their anchor points are different, and their preexisting knowledge might be harder to unlearn, so by considering someone's previous experience, we can offer a personalised and more useful experience for students. 20 | 21 | **Adding in-browser coding support:** In parallel to the rethinking of core tracks, we are going to add one of our most-requested features: the ability to solve exercises in the browser. This will not replace using the CLI, which we believe is an incredibly valuable way to learn, but will offer people the ability to quickly try and explore languages without having to install that language and its tooling. 22 | 23 | ### The Funding 24 | 25 | The funding we are receiving from The Sloan Foundation via James and Gary will allow Jeremy, Nicole, Charles and Karlo to invest most of their time for the next 12 months into the product work, development work, and architecture required to achieve the aims above. 26 | 27 | It will also allow us to hire Erik to lead on the "curriculum" side of the project. Erik has been a significant contributor to Exercism since 2016, maintaining the C#, F# and Scala tracks, building analysers, designing exercises, contributing to project-specifications and mentoring. He is also passionate about programming languages and has completed a significant proportion of the tracks on Exercism. He is also crucially someone who is universally liked and respected amongst the Exercism community, and therefore perfectly positioned to help navigate us through understanding how we can design tracks and systems that allow the differences and similarities of 50 different programming languages to shine through. 28 | 29 | ### Getting involved 30 | 31 | We will be putting together a specific team to help with this project. This team will be responsible for defining the idioms across tracks, designing new core exercises, helping us design frameworks and standards for analyzers, and thinking through how incumbent knowledge affects learning. 32 | 33 | If you are an experienced mentor **and** maintainer and you'd like to get involved, we would love to hear from you. Please reach out to me on Slack. 34 | 35 | ### Conclusion 36 | 37 | We're really excited for this next phase. We believe it will help Exercism take huge steps forward and better serve both our students and mentors. We're extremely grateful to James, Gary, and the Sloan Foundation for their support. 38 | -------------------------------------------------------------------------------- /posts/september-2024-restructure.md: -------------------------------------------------------------------------------- 1 | # September 2024 Restructure 2 | 3 | _Update: This post went somewhat viral beyond the Exercism community. Thanks to everyone who's offered wishes of support and to the hundreds who have donated in response. I added a little more context and clarified a few things in a [Hacker News comment](https://news.ycombinator.com/item?id=41469477)._ 4 | 5 | --- 6 | 7 | Hi everyone! 8 | 9 | Last week we hit the huge milestone of **two million users**. 10 | Within a few hours, we also hit **45 million exercise submissions**. 11 | 12 | A day later, I paid the **final payroll** for me, Erik and Aron, and our bank account reduced down to the point we can't afford to pay another. 13 | 14 | I think this sums up Exercism's story pretty well. 15 | Over **1,200 people per day sign up** to Exercism. 16 | Tens of thousands solve exercises each day. 17 | But we don't have enough money to continue to work on the platform. 18 | 19 | We've tried a lot of things to change that. 20 | We've spoken to hundreds of funders and companies, but Exercism isn't the right fit for their support. 21 | It doesn't fit a niche that makes sense for them. 22 | By serving people everywhere, it seems we don't serve a narrow enough demographic that we align to funders' often narrow missions! 23 | 24 | The one area we have had some promising success is in advertising on the site. 25 | But the effort it takes to find advertisers and manage them, and my general desire not to flood Exercism with adverts, has meant that I feel this isn't a very sustainable strategy. 26 | 27 | I think it's fair to say that at this stage **I've lost faith in the nonprofit business model** working in a way that allows Exercism to reach any of its potential. 28 | Keeping something free for everyone relies on either the user being the product, or on significant donations, and without either, it's very hard to grow. 29 | 30 | ## Erik + OSS Restructure 31 | 32 | Probably the hardest thing about the situation right now, is that **we can no longer afford to pay Erik**, so he's leaving as an employee at the end of this week. 33 | 34 | Erik has been an absolute critical part of Exercism's growth and success over the last few years. 35 | He's also been a wonderful colleague and friend, and I'll really miss working alongside him. 36 | It goes without saying that I'm incredibly grateful to Erik for all his hard work and support. 37 | And I know many of you will feel the same (if so, please reach out and tell him!) 38 | 39 | Erik's a die-hard Exercism fan, and he's going to continue as a senior maintainer of a few tracks, and he'll hold onto his super-admin privileges, but the plethora of hidden (and often a bit boring) things that he does day-to-day need to get spread across the organisation. 40 | 41 | The one key thing we're enforcing is that **every PR in a live Exercism repository should get a review before it can be merged** (with only one exception outlined below). 42 | This has generally been the case anyway for a long time, but there are places where it's fallen through the cracks, so we've now scripted things to ensure this is always the case. 43 | 44 | To do this, we've come up with a new classification system for repos, and specific rules for each type: 45 | - `maintained`: A repo that has multiple maintainers. All PRs require reviews from a track maintainer. 46 | - `maintained-solitary`: A repo that has one maintainer. A new cross-track-maintainers team will get pinged to review all PRs. 47 | - `unmaintained`: A repo that has no maintainers. The cross-track-maintainers team will get pinged here too. 48 | - `maintained-autonomous`: A repo where all maintainers are also in the cross-track-maintainer team. This is the exception, where they can merge their own PRs. 49 | - `wip-track`: An unlaunched track. As it's not "live" yet, it doesn't have restrictions. 50 | 51 | We've created two new GitHub teams that enforce this. 52 | - `@exercism/guardians`: A team to check the safety of PRs to tooling repositories (test runners, analyzers, etc). Made up of a few longstanding polyglots. 53 | - `@exercism/cross-track-maintainers`: A new team made up of longstanding polyglots who are active on the site on a day-to-day basis, and who have the same level of reviewing-pedanticism that I do (ie they're not more strict or more flexible than me). This is important, as I want a consistent, responsive experience from this team. 54 | 55 | Both teams are invite-only. 56 | I'll review them sporadically. 57 | 58 | We've also invited new maintainers and "pruned" a lot of inactive maintainers as part of this. 59 | To those people who have been removed - thank you for all you've done, and please know you're very welcome back if you find the time/desire to contribute in earnest to Exercism again! 60 | 61 | ## So what's next? 62 | 63 | So this has all been a bit gloom and doom so far. 64 | Things don't always go as you hope in life, but you have to make lemonade from the lemons! 65 | 66 | Right now, we have about 800 monthly donors and about $7,500 in monthly donations. 67 | That **covers our server costs** pretty much exactly. 68 | So if you're donating right now, thank you. 69 | You are literally keeping our servers on. 70 | Our donor base is generally quite stable, so I'm not too worried about Exercism's existential prospects. 71 | 72 | (It would be really good to build a bit of a financial buffer, so if you can afford it, please consider making a [recurring or one-off donation](https://exercism.org/donate) 💙) 73 | 74 | We also have an **amazing community, maintainer team, and group of mentors** who keep adding new exercises (and tracks!), helping students, and numerous other things. 75 | Exercism has probably never been healthier as an organisation. 76 | It's **growing faster than ever**, more people are using it than ever, and I think the product and educational experience is better than ever. 77 | So I'm still deeply dedicated to growing and nurturing Exercism. 78 | 79 | For the last few months, I've been working on a new educational product teaching coding fundamentals that I'm going to launch in 2025. 80 | 96% of people who try to learn coding give up - which I find unacceptable, so I'm aiming to change that. 81 | My plan is to give beginners a rock-solid base, then funnel them into Exercism. 82 | I'm creating a new for-profit company for the new company, and going to use proceeds from that to keep Exercism growing. 83 | I've raised a little investment for this, which means I can continue to pay Aron's salary, so he'll be staying around, working on that with me, and tweaking Exercism as needed. 84 | 85 | I'm also planning (probably 90% certain) of running **a dedicated learn-to-code course** from Jan-March 2025, where I can test out some of what we've been building, and I can get my hands dirty working with the students who existing platforms don't serve. 86 | So keep out for an announcement about this soon. 87 | 88 | I'm exploring launching **a basic version of Exercism Teams**, as a way of making some extra revenue. 89 | There's [a forum post](https://forum.exercism.org/t/exercism-teams-coming-soon/12667) here where you can leave thoughts. 90 | I'd really appreciate any you have! 91 | 92 | But first, **I need a breather!** 93 | I'll be taking the next two weeks off, unplugging and recovering a little. 94 | 95 | Thanks for all your support - emotional and financial. 96 | Exercism's community is phenomenal and **I'm deeply grateful** to everyone involved in the project. 97 | -------------------------------------------------------------------------------- /posts/sorry-for-the-wait.md: -------------------------------------------------------------------------------- 1 | Our community are currently working hard on Exercism v3. We're making great progress but the downside is that a lot of time is being diverted away from mentoring. 2 | 3 | I made a [short video](https://www.youtube.com/watch?v=XiV_vYn1Ea8) to explain and ask for your patience during this period. 4 | 5 | Thanks for your understanding and support! 6 | -------------------------------------------------------------------------------- /posts/thank-you-by-erik.md: -------------------------------------------------------------------------------- 1 | # Thank you everyone! 2 | 3 | Hi everyone, 4 | 5 | For those of you who missed it: this is my **last day as an Exercism employee.** 6 | I'd like to take this opportunity to thank everyone who I've worked with during my time at Exercism. 7 | It may be a surprise to some, but it was not Exercism's many fantastic languages that got me hooked, but the community (i.e. the people)! 8 | 9 | Soon after working through the Scala track in September 2014 (which was still Exercism v1) I joined the Haskell track. 10 | I struggled a ton, but with the fantastic help of the Haskell "mentors" (they weren't officially called mentors then, but their comments were nothing less than mentorship), I managed to learn Haskell step by step (and developing a fondness for functional programming that is still with me to this day). 11 | Seeing how I had benefited so much from the mentoring on my Haskell solutions, **I started commenting on other people's C# solutions** (which also made me a much better programmer). 12 | 13 | Slowly but surely I was drawn into the maintainer part of Exercism. 14 | What started with a few humble contributions to the C# track **quickly became my favorite hobby**: working together with people from all over the world to help build Exercism. 15 | I spent many hours (even entire weekends) adding exercises to first the C# track, and later on the F# track. 16 | The next step was to engage in the discussions on the problem-specifications repo, which was just a wonderful experience. 17 | 18 | During my time as a C# maintainer, I got to build **a wildly over engineered test generator** for the C# track (which I thoroughly regret now!), but the work on the first C# analyzer prototype was, to me, the pinnacle of engineering fun. 19 | 20 | At a certain time in 2019, Jeremy asked me if I wanted to help build Exercism v3. I did not need much time to decide, quickly handed in my resignation letter and **started working at Exercism** in September 2019. 21 | The last five years I've been helping build out Exercism v3 and trying to streamline the inclusion of 70+ language tracks into the website. 22 | I've learnt dozens of new languages, some of which have become favorites of mine. **It has definitely made me a better programmer.** 23 | However, even more importantly, engaging with the community has **also made me a better person.** 24 | From the interactions with you all, I've learnt so much! 25 | 26 | Unfortunately, the Exercism employee part of the journey has come to an end. 27 | However, **I'm not disappearing** (I'm not a magician after all), I'm merely returning back to a previous state: one where I'm a regular member of the community (with admin permissions 🤭) and where I'm maintaining the C#, F# and Prolog tracks. 28 | That means you'll still be seeing me around, and I assume I'll still get asked a lot of questions for a long time. 29 | **I won't be as active responding to your questions** though and most of the reviews will be handled by our newly introduced maintainer teams. 30 | 31 | Overall, **it has been an incredible 5 years** and I wouldn't have missed it for the world. 32 | As I'll still be hanging around, I don't even have to say goodbye! 33 | I'd just like to say: **thank you all for being the wonderful people you are.** 34 | It has been my pleasure and honor working with you (especially Jeremy). 35 | -------------------------------------------------------------------------------- /posts/track-anatomy-project.md: -------------------------------------------------------------------------------- 1 | In September last year, we quietly started [Exercism's](http://exercism.io) **Track Anatomy Project**. Since then we've been telling more and more people about it, and have now decided that the time is right to publicly introduce the formal work that we are doing to improve the tracks and exercises on Exercism. 2 | 3 | To understand the purpose and need for the Track Anatomy Project we have to look back to Exercism's roots. Exercism started as a variety of language tracks, each with a set of overlapping exercises. There was no order or structure as such—anyone could choose any exercise that they felt looked interesting, solve it, upload their code, and hope someone found it and commented on it. At the core of our 2018 relaunch was recentering Exercism around a much more structured approach to both the tracks themselves and the learning that accompanied them. We decided to reform language tracks to consist of a fixed spine made up of required "core exercises," which unlocked optional "side exercises" as they were completed. We asked maintainers to structure the core spine to increase in difficulty as well as to design an unlocking sequence that was relevant to the techniques being practiced. Different maintainers took different approaches to this with varying levels of success. Some simply didn't have time, in which case we just chose ten relatively random exercises to form the initial core. 4 | 5 | It became clear very quickly that the design of the track made a tremendous difference to the success of that track. Over the first few months after launch, we made a series of critical observations: 6 | - Languages which started with an exercise that was too difficult would frustrate people and lead to a rapid drop-off. 7 | - The difficulty of mentoring an exercise was directly correlated to the complexity of the exercise rather than the difficulty of the exercise. 8 | - Exercises that could be solved in one typical way (e.g. "acronym"), or that have clear learning objectives were much quicker to mentor than those that had variety (e.g. "bob"). 9 | - The order that concepts are introduced matters—covering essential idioms in the first few exercises makes the subsequent exercises easier for both the learner and the mentor. 10 | 11 | Based on this, we realized that a large part of the success of mentoring on Exercism was going to be dependant on the quality of the "curriculum" of the tracks—having the right topics, covered explicitly in the right exercises, in a suitable order. We decided that we needed to develop a formal framework that we could use as a guide for maintainers, and create a track that we could use as a gold standard for other tracks. 12 | 13 | In parallel with all this happening, one of our mentors, Maud de Vries, who has been a professional coach for 20 years, had started regularly posting suggestions about how to improve the Ruby track. Her ideas were remarkably aligned with the realizations that we were also having. Quietly in the background, Maud was analyzing every Ruby exercise in turn and developing a map of how the exercises connect, the concepts they contained, and how they could be better arranged to form a track structure that was well-structured for learners and fun and engaging for mentors to work with. When she showed us some of her work, we decided that she was the right person to develop our track framework and that she could take the Ruby track and make it our exemplar. Since then, Maud has been working part-time for Exercism, redesigning the Ruby track, and developing a multi-stage framework for maintainers to work through to quickly replicate her learnings in other languages. Since October, Erik Schierboom has been working in his spare time as Maud's guinea pig, testing and using the framework to improve the C# track, which in turn has had a huge impact on the development of the framework itself. 14 | 15 | We are now getting close to the stage where we will be able to take our next tranche of maintainers through the framework progress and more rigorously test and refine it. Once we've completed this next round, we hope to publish a first version of the framework that can undergo more scrutiny from the broader community. We're really excited to reach that point and to showcase all of the work that's been going on behind the scenes. We feel this is a giant step forward for Exercism that will significantly improve both the learning experience and that of mentors. 16 | 17 | I want to finish this by saying a huge thank you to Maud who has tirelessly spearheaded this project, and to Erik who has given up so much of his free time to help out. 18 | -------------------------------------------------------------------------------- /posts/unicode-matching-in-elixir.md: -------------------------------------------------------------------------------- 1 | Exercises on Exercism are small, synthetic, and often seemingly trivial. It’s easy to imagine that experienced practitioners would have nothing to learn from them. However, solving these artificial problems can push you to learn and apply parts of your language that you may not have explored. This new learning can lead you to solve real-world problems more efficiently or more expressively. 2 | 3 | [Parallel Letter Frequency](https://exercism.io/tracks/elixir/exercises/parallel-letter-frequency) is a medium difficulty exercise on [Exercism's Elixir Track](https://exercism.io/tracks/elixir) that unpacks a surprising number of interesting lessons. A central challenge in solving the exercise is handling letters from multiple languages, as one of the test cases is in German and contains characters outside the English alphabet. If you spend most of your time developing applications for English speakers, this may be the first time you've had to deal with a requirement like this. The learning from this exercise has clear benefits for anyone writing a multilingual/non-English application, but could also help in many other areas, such as more robust username and password validations. 4 | 5 | To solve the exercise successfully, you need to implement a function, `Frequency.frequency/2` , that determines letter frequency in a list of strings that could be in any language: 6 | 7 | ```elixir 8 | iex> Frequency.frequency(["Freude", "schöner", "Götterfunken"], workers) 9 | %{ 10 | "c" => 1, 11 | "d" => 1, 12 | "e" => 5, 13 | ... 14 | "ö" => 2 15 | } 16 | ``` 17 | 18 | Let's start with the fundamental problem this function needs to solve and work our way up to a full implementation. 19 | 20 | ## Determine whether a character is a letter in Elixir 21 | 22 | How would you use Elixir to determine whether or not `"a"` is a letter? 23 | 24 | I think most people would apply a regular expression like `/[a-z]/`: 25 | 26 | ```elixir 27 | iex> String.match?("a", ~r/^[a-z]$/) 28 | true 29 | ``` 30 | 31 | What about `"A"`? 32 | 33 | Adding the `i` [(caseless) modifier](https://hexdocs.pm/elixir/Regex.html#module-modifiers) would probably be the easiest way: 34 | 35 | ```elixir 36 | iex> String.match?("A", ~r/^[a-z]$/i) 37 | true 38 | ``` 39 | 40 | Ok, now what about `"ö"`? 41 | 42 | When I first approached this problem, I wasn't sure of the best way --`/[a-z]/i` is definitely not going to work: 43 | 44 | ```elixir 45 | iex> String.match?("ö", ~r/^[a-z]$/i) 46 | false 47 | ``` 48 | 49 | Determining whether or not `"ö"` is a letter is a core part of solving this Exercism problem, as one of the texts in the tests is in German: 50 | 51 | ```elixir 52 | # parallel_letter_frequency_test.exs 53 | ... 54 | # Poem by Friedrich Schiller. The corresponding music is the European Anthem. 55 | @ode_an_die_freude """ 56 | Freude schöner Götterfunken 57 | ... 58 | """ 59 | ``` 60 | 61 | Maybe you could use a regular expression to check if a character **isn't** a special character, but it's likely to be long, inelegant and fragile. How confident can you be that you've covered every possible special character that might be passed as input to your function? I believe there's a better approach. 62 | 63 | ## Unicode regular expressions in Elixir 64 | 65 | A better approach to this problem is using the [`u` modifier in Elixir's `Regex` module](https://hexdocs.pm/elixir/Regex.html): 66 | 67 | > unicode (`u`) - enables Unicode specific patterns like `\p` and change modifiers like `\w`, `\W`, `\s` and friends to also match on Unicode. 68 | 69 | It turns out that the `u` modifier—and [specifically the `\p` pattern](https://www.regular-expressions.info/unicode.html)—is a really elegant solution. The `\p` pattern lets you match a grapheme (another name for a single Unicode character) in any of the [Unicode character categories](https://en.wikipedia.org/wiki/Unicode_character_property#General_Category). This not only includes specific categories like `Ll` ([Letter, lowercase](https://www.compart.com/en/unicode/category/Ll)) and `Sc` ([Symbol, currency](https://www.compart.com/en/unicode/category/Sc)), but also the parent categories like `L` (Letter) and `S` (Symbol). 70 | 71 | You can match _any_ letter of _any_ case in _any_ [human language covered by Unicode](https://www.unicode.org/faq/basic_q.html) with the pattern `\p{L}`. This allows for some [pretty powerful matching](https://www.toptechskills.com/elixir-phoenix-tutorials-courses/how-to-match-any-unicode-letter-with-regex-elixir/#more-cool-stuff-you-can-match-with-unicode). 72 | 73 | Basic Latin characters from English work as usual: 74 | 75 | ```elixir 76 | iex> String.match?("a", ~r/^\p{L}$/u) 77 | true 78 | iex> String.match?("A", ~r/^\p{L}$/u) 79 | true 80 | ``` 81 | 82 | Latin character variants with [umlauts](https://en.wikipedia.org/wiki/Umlaut_(linguistics)) and [acute accents](https://en.wikipedia.org/wiki/Acute_accent) are no problem either: 83 | 84 | ```elixir 85 | iex> String.match?("ö", ~r/^\p{L}$/u) 86 | true 87 | iex> String.match?("Á", ~r/^\p{L}$/u) 88 | true 89 | ``` 90 | 91 | Let's make sure it's not just returning a match for any character. How about some characters that look like letters but aren't: 92 | 93 | ```elixir 94 | iex> String.match?("$", ~r/^\p{L}$/u) 95 | false 96 | iex> String.match?("@", ~r/^\p{L}$/u) 97 | false 98 | ``` 99 | 100 | Very nice, but remember how I said _any_ language? No sweat: 101 | 102 | ```elixir 103 | # Chinese character for "you" 104 | iex> String.match?("你", ~r/^\p{L}$/u) 105 | true 106 | 107 | # Cyrillic capital letter "zhe" 108 | iex> String.match?("Ж", ~r/^\p{L}$/u) 109 | true 110 | ``` 111 | 112 | ## Applying Unicode matching to the problem at hand 113 | 114 | Now that we have a tool that can help us determine whether or not a grapheme is a letter, we can apply it to solve the problem. An initial implementation of the `Frequency.frequency/2` function might look like this: 115 | 116 | ```elixir 117 | def frequency(texts, _workers) do 118 | texts 119 | |> get_all_graphemes() 120 | |> count_letters() 121 | end 122 | 123 | defp get_all_graphemes(texts) do 124 | texts 125 | |> Enum.join() 126 | |> String.graphemes() 127 | end 128 | ``` 129 | 130 | All `count_letters/1` would need to do is apply the `String.match?(grapheme, ~r/^\p{L}$/u)` pattern we identified above to increment the count of each letter in the list of `graphemes`. Here's an example implementation taken from [my solution to this Exercism problem](https://exercism.io/tracks/elixir/exercises/parallel-letter-frequency/solutions/cc80004beded4749bce81b5dc0820952): 131 | 132 | ```elixir 133 | defp count_letters(graphemes) do 134 | Enum.reduce(graphemes, %{}, fn grapheme, acc -> 135 | if String.match?(grapheme, ~r/^\p{L}$/u) do 136 | downcased_letter = String.downcase(grapheme) 137 | Map.update(acc, downcased_letter, 1, fn count -> count + 1 end) 138 | else 139 | acc 140 | end 141 | end) 142 | end 143 | ``` 144 | 145 | This function accepts a list of graphemes, e.g. `["a", "A", "ö", "$"]`, and returns a map that counts only the letters while ignoring the case -- `%{"a" => 2, "ö" => 1}`. Considering that this function can handle input from any language, I would say it's a pretty powerful 9 lines of code. 146 | 147 | ## Conclusion 148 | 149 | It turns out that matching non-English letters becomes pretty simple when you know about Unicode matching, and luckily for us, it's a core feature in Elixir's `Regex` module. Before solving this Exercism problem I barely knew about this feature, but I would now consider it an indispensable part of my Elixir toolbox. 150 | 151 | You could use this new tool in many ways, and a few that spring to my mind are more robust validation of passwords and usernames, or even for determining whether an input string is a valid currency string without needing to manually list [all possible currency symbols](https://www.compart.com/en/unicode/category/Sc): 152 | 153 | ```elixir 154 | iex> currency_string_regex = ~r/\p{Sc}\d+\.\d{2}/u 155 | ~r/\p{Sc}\d+\.\d{2}/u 156 | 157 | iex> ["$1.00", "£1.00", "¥1.00", "€1.00", "&1.00"] \ 158 | ...> |> Enum.filter(&String.match?(&1, currency_string_regex)) 159 | ["$1.00", "£1.00", "¥1.00", "€1.00"] 160 | ``` 161 | -------------------------------------------------------------------------------- /posts/was-exercism-v2-worth-it.md: -------------------------------------------------------------------------------- 1 | A couple of weeks ago, I posted an issue about our upcoming journey towards Exercism V3. Someone [posted a comment](https://github.com/exercism/exercism/issues/5135#issuecomment-566125777) saying that they hoped the transition would be smoother than V1 to V2, and questioning whether a lot of changes we made were worth the hassle. Both are excellent points to raise and show that we've clearly not explained the impact that the V2 changes **did** have and why we believe they were worth it. I thought it would, therefore, be worth writing a short post outlining the changes we saw in the data, and also the metrics that we're targeting with the push to V3. 2 | 3 | _(Three notes on the numbers. Firstly, the metrics below are roughly ordered by the flow of the site, rather than of importance. Secondly, I've used a 17-month window on either side of the launch of V2 for comparisons. When I say "V1", I mean the final 17 months of V1. There's no entirely accurate way to do this, as V1 had many small changes in the 17 months prior to launch, and V2 had substantial improvements over the period since it launched. We also have outlier days, like the one during V1 when GitHub featured us, and we had 30x traffic for a day or so. I've not worried about that and just stuck to a fixed window either side, believing it to be the fairest way to measure things. Finally, there are many metrics that I could have used for each point. I've chosen ones that I feel represent the story that the numbers tell as a whole, and that were easy for me to work out across historic and modern data)._ 4 | 5 | ## V1 -> V2 Metrics 6 | 7 | ### Visitors signing up (Branding) 8 | 9 | One of our aims was to make Exercism feel more welcoming to people who might have been put off by the original (red + devil) branding. To many, this seemed like a minor change, because they **weren't** put off by the branding and so the effort seemed like a waste of time. However, we believed that Exercism didn't exude "welcoming, inclusive community" in V1, and it was important for us to put that right. 10 | 11 | How many people signed up to Exercism over the periods, and what was this as a percentage of new visitors? 12 | 13 | - V1: 62,618 (17% of new visitors sign up) 14 | - V2: 188,844 (48% of new visitors sign up) 15 | 16 | This first change was substantial. Our V2 landing page converts at 48% as opposed to 17% for V1. That's pretty much purely down to brand and clarity over what we do and who we are. So I strongly believe that the effort that went into rebranding Exercism was worth the effort. 17 | 18 | One caveat is that V2 probably encourages people to sign up who aren't yet ready for Exercism as it stands. V2 isn't set up for total beginners, yet the landing page for V2 is much more welcoming for total beginners, so we probably get a lot of users who aren't yet ready for Exercism. One way to account for this would be to consider not only the number of visitors signing up but rather how many visitors signed up _and_ managed to submit a solution. For this, we see: 19 | 20 | - V1: 26,194 (7% new visitors sign up and submit) 21 | - V2: 52,533 (13.9% new visitors sign up and submit) 22 | 23 | So from this, we can say that the branding has accounted for approximately a doubling of our true "conversion rate", which makes the rebranding effort definitely worthwhile. It's also worth noting that as we move forward to being beginner-friendly (V3.x), this caveat will go away altogether. 24 | 25 | ### Solutions getting feedback (Mentoring) 26 | 27 | The second thing we wanted to improve was the amount of mentoring per solution. In V1, it was a bit of a lottery - you might get comments, or you might not, purely dependent on whether someone noticed your submission. A big part of the formal mentoring of V2 was about making this fairer, consistent, and reliable. 28 | 29 | The metric I've used here is the percentage of solutions that receive a comment. 30 | 31 | - V1: 3.5% of all solutions 32 | - V2: 64% of solutions where mentoring has been requested (26% of all solutions) 33 | 34 | This is the phenomenal statistic in my eyes and the big indicator that V2 took us in the right direction. You're now 18x more likely to receive feedback on your solution in V2 than in V1. There's a lot we got wrong with mentoring in V2 (see the next section!), but I feel hugely proud and grateful to our mentors for the fact that Exercism offers a place where if you want mentoring, you'll more likely than not receive it. 35 | 36 | ### Stickiness 37 | 38 | Finally, we wanted to improve "stickiness" - the amount of usage of the site. If people are enjoying Exercism and finding it useful, they'll do more with it. There are two sides to this, the number of times someone comes back to the site and the number of solutions someone uploads. 39 | 40 | Returning users: 41 | - V1: 4.79 sessions / person 42 | - V2: 5.42 sessions / person 43 | 44 | Volume of uploads: 45 | - V1: 8.0 solutions / person 46 | - V2: 8.2 solutions / person 47 | 48 | Both held pretty much steady. This is one area where I hoped we'd see a big increase in V2, and we didn't. The wait times for mentoring, and the blocking mechanisms that stop progression without mentoring both made V2 a very slow experience. For someone wanting to quickly progress through a language, the huge mentor queues made it very difficult to learn at a reasonable enough rate. The experience here will be very track-dependent. For tracks with wait times longer than a day, the dropout rate is noticeable. For those with longer wait times (e.g., Rust, Python), the dropout rate is substantial. 49 | 50 | The changes in V3 are largely aimed at fixing this problem - making Exercism a place where you can quickly learn or practice a language, but where you can also have helpful asynchronous conversations with mentors without having your progress blocked. 51 | 52 | ## Moving towards V3. 53 | 54 | For V3, I hope to see all three of these metrics continue to rise. My aim is that people hear about Exercism and sign up, that they manage to submit solutions and get deep into tracks without feeling frustrated, and that when they want mentoring, they receive it. 55 | 56 | I hope that the statistics above demonstrate that we're moving in the right direction and that the work everyone has put into V2 has been worthwhile. There's going to be a lot of effort needed from the community to get us to V3, but I'm confident that when we take stock of Exercism 24 months from now, we will see similar increases and that all of the next phases of work will prove worthwhile. Exercism **is** our community - thank you all for everything you do. 57 | -------------------------------------------------------------------------------- /posts/what-happens-if-my-mentor-disappears.md: -------------------------------------------------------------------------------- 1 | Sometimes you're working away improving an exercise and your mentor disappears. Up until now, that's been a big problem, but this week we've implemented a string of small improvements to fix this problem. 2 | 3 | It's rare that a mentor disappears but when they do it's generally just a slip of the mind. They got the notification that you'd posted something, checked your new iteration, then life got in the way, and they forgot all about replying. Our first improvement is a simple prompt to the mentor after a few days of them not replying. We send them a friendly message reminding them that you're waiting on them and asking them to respond. 4 | 5 | If they still don't respond after this prompt, we move onto step two, removing the mentor from that post. We now automate this after 7 days of inactivity and put the solution back in the queue for another mentor to pick up. And importantly, it jumps straight to the top of the queue so you should hopefully get a quick response. In this situation, you'll see a nice little notification that tells you that the mentor has "timed out", so you know what's going on. 6 | 7 | ![New message example](https://assets.exercism.io/blog/what-happens-if-my-mentor-disappears-message.png) 8 | 9 | We ran some scripts to fix all the existing solutions that were in this state from the last nine months and discovered that there were only 350 that had been abandoned. That might sound like a lot, but when you consider we have over 1,000 submissions per day, it's a tiny amount! All of those are now fixed, so if your mentor **did** disappear, then you should find a new mentor appearing soon! 10 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | ajv-cli@^5.0.0: 6 | version "5.0.0" 7 | resolved "https://registry.yarnpkg.com/ajv-cli/-/ajv-cli-5.0.0.tgz#78956ed2934e6dde4c9e696b587be1c2998862e8" 8 | integrity sha512-LY4m6dUv44HTyhV+u2z5uX4EhPYTM38Iv1jdgDJJJCyOOuqB8KtZEGjPZ2T+sh5ZIJrXUfgErYx/j3gLd3+PlQ== 9 | dependencies: 10 | ajv "^8.0.0" 11 | fast-json-patch "^2.0.0" 12 | glob "^7.1.0" 13 | js-yaml "^3.14.0" 14 | json-schema-migrate "^2.0.0" 15 | json5 "^2.1.3" 16 | minimist "^1.2.0" 17 | 18 | ajv@^8.0.0: 19 | version "8.11.2" 20 | resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.11.2.tgz#aecb20b50607acf2569b6382167b65a96008bb78" 21 | integrity sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg== 22 | dependencies: 23 | fast-deep-equal "^3.1.1" 24 | json-schema-traverse "^1.0.0" 25 | require-from-string "^2.0.2" 26 | uri-js "^4.2.2" 27 | 28 | argparse@^1.0.7: 29 | version "1.0.10" 30 | resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" 31 | integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== 32 | dependencies: 33 | sprintf-js "~1.0.2" 34 | 35 | balanced-match@^1.0.0: 36 | version "1.0.2" 37 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" 38 | integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== 39 | 40 | brace-expansion@^1.1.7: 41 | version "1.1.11" 42 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 43 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== 44 | dependencies: 45 | balanced-match "^1.0.0" 46 | concat-map "0.0.1" 47 | 48 | concat-map@0.0.1: 49 | version "0.0.1" 50 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 51 | integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== 52 | 53 | esprima@^4.0.0: 54 | version "4.0.1" 55 | resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" 56 | integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== 57 | 58 | fast-deep-equal@^2.0.1: 59 | version "2.0.1" 60 | resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" 61 | integrity sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w== 62 | 63 | fast-deep-equal@^3.1.1: 64 | version "3.1.3" 65 | resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" 66 | integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== 67 | 68 | fast-json-patch@^2.0.0: 69 | version "2.2.1" 70 | resolved "https://registry.yarnpkg.com/fast-json-patch/-/fast-json-patch-2.2.1.tgz#18150d36c9ab65c7209e7d4eb113f4f8eaabe6d9" 71 | integrity sha512-4j5uBaTnsYAV5ebkidvxiLUYOwjQ+JSFljeqfTxCrH9bDmlCQaOJFS84oDJ2rAXZq2yskmk3ORfoP9DCwqFNig== 72 | dependencies: 73 | fast-deep-equal "^2.0.1" 74 | 75 | fs.realpath@^1.0.0: 76 | version "1.0.0" 77 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 78 | integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== 79 | 80 | glob@^7.1.0: 81 | version "7.2.3" 82 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" 83 | integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== 84 | dependencies: 85 | fs.realpath "^1.0.0" 86 | inflight "^1.0.4" 87 | inherits "2" 88 | minimatch "^3.1.1" 89 | once "^1.3.0" 90 | path-is-absolute "^1.0.0" 91 | 92 | inflight@^1.0.4: 93 | version "1.0.6" 94 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 95 | integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== 96 | dependencies: 97 | once "^1.3.0" 98 | wrappy "1" 99 | 100 | inherits@2: 101 | version "2.0.4" 102 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" 103 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 104 | 105 | js-yaml@^3.14.0: 106 | version "3.14.1" 107 | resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" 108 | integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== 109 | dependencies: 110 | argparse "^1.0.7" 111 | esprima "^4.0.0" 112 | 113 | json-schema-migrate@^2.0.0: 114 | version "2.0.0" 115 | resolved "https://registry.yarnpkg.com/json-schema-migrate/-/json-schema-migrate-2.0.0.tgz#335ef5218cd32fcc96c1ddce66c71ba586224496" 116 | integrity sha512-r38SVTtojDRp4eD6WsCqiE0eNDt4v1WalBXb9cyZYw9ai5cGtBwzRNWjHzJl38w6TxFkXAIA7h+fyX3tnrAFhQ== 117 | dependencies: 118 | ajv "^8.0.0" 119 | 120 | json-schema-traverse@^1.0.0: 121 | version "1.0.0" 122 | resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" 123 | integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== 124 | 125 | json5@^2.1.3: 126 | version "2.2.1" 127 | resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" 128 | integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== 129 | 130 | minimatch@^3.1.1: 131 | version "3.1.2" 132 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" 133 | integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== 134 | dependencies: 135 | brace-expansion "^1.1.7" 136 | 137 | minimist@^1.2.0: 138 | version "1.2.7" 139 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.7.tgz#daa1c4d91f507390437c6a8bc01078e7000c4d18" 140 | integrity sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g== 141 | 142 | once@^1.3.0: 143 | version "1.4.0" 144 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 145 | integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== 146 | dependencies: 147 | wrappy "1" 148 | 149 | path-is-absolute@^1.0.0: 150 | version "1.0.1" 151 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 152 | integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== 153 | 154 | punycode@^2.1.0: 155 | version "2.1.1" 156 | resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" 157 | integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== 158 | 159 | require-from-string@^2.0.2: 160 | version "2.0.2" 161 | resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" 162 | integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== 163 | 164 | sprintf-js@~1.0.2: 165 | version "1.0.3" 166 | resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" 167 | integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== 168 | 169 | uri-js@^4.2.2: 170 | version "4.4.1" 171 | resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" 172 | integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== 173 | dependencies: 174 | punycode "^2.1.0" 175 | 176 | wrappy@1: 177 | version "1.0.2" 178 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 179 | integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== 180 | --------------------------------------------------------------------------------