Exercism exercises in JavaScript.
MIT License
417
23
492

Hi, I'm learning JS and I feel like the closure concept & exercise have too little information, as a beginner it's very hard to understand what the exercise needs to achieve. Is there anyone who likes to improve this concept

Getting Started

Here you can read about what Concept Exercises are and how they are structured:

If you have not done so yet, it is probably also helpful to do a couple of "Learning Exercises" (this is how they are called on the site) yourself. You can also look at the code of an existing concept exercise like bird-watcher (concept for-loops) for reference.

See the documentation above (general documentation), as well as How to implement a Concept Exercise in JavaScript.

Main Task

Currently, the exercise only associated with the concept callbacks. Arrow functions are only mentioned briefly at the end of that concept. Since being able to read and write arrow functions properly is important, they should get their own concept arrow-functions. So after this change the fruit picker exercise will unlock 2 concepts, callbacks and arrow-functions.

The new concept should explain the most important syntax variants. The introduction.md should not explain the details of what happens to this as there will be a separate concept later.

Possible resources that might help:

The exercise could probably stay as is but if you have a good idea how to improve it so it incorporates the new content even better, feel free to do changes.

Don't forget to adjust the design.md file to incorporate the new content and to add the new concept in the global config.json file.
Also remove arrow functions from the callbacks concept and make sure the introduction.md of the exercise includes both concepts.

Bonus Tasks

  • Fix the JSDoc/typing errors that show in the test file.
  • Proof-read the existing concepts, exercise docs etc.
  • Note down potential analyzer comments in the design.md file, see design.md in Amusement Park for an example

How to proceed

  1. First accept this issue by saying "I'd like to work on this" (no need to wait for a response, just go ahead).
  2. Use this issue to discuss any questions you have, what should be included in the content and what not and to collect reference material.
  3. Create a PR and set "exercism/javascript" as reviewers. Additionally you can write in #maintaining-javascript on Slack that your PR is ready for review. Once you incorporated any critical feedback that the reviewer might give you and the PR is approved, it will be merged by a maintainer.

We hit an error trying to sync the latest commit (a7c1183) to the website.

The error was:

Mysql2::Error::TimeoutError: Lock wait timeout exceeded; try restarting transaction

/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/mysql2-0.5.4/lib/mysql2/client.rb:148:in `_query'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/mysql2-0.5.4/lib/mysql2/client.rb:148:in `block in query'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/mysql2-0.5.4/lib/mysql2/client.rb:147:in `handle_interrupt'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/mysql2-0.5.4/lib/mysql2/client.rb:147:in `query'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activerecord-7.0.2.3/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:632:in `block (2 levels) in raw_execute'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.2.3/lib/active_support/concurrency/share_lock.rb:187:in `yield_shares'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.2.3/lib/active_support/dependencies/interlock.rb:41:in `permit_concurrent_loads'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activerecord-7.0.2.3/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:631:in `block in raw_execute'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.2.3/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `handle_interrupt'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.2.3/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `block in synchronize'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.2.3/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `handle_interrupt'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.2.3/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `synchronize'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activerecord-7.0.2.3/lib/active_record/connection_adapters/abstract_adapter.rb:765:in `block in log'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.2.3/lib/active_support/notifications/instrumenter.rb:24:in `instrument'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activerecord-7.0.2.3/lib/active_record/connection_adapters/abstract_adapter.rb:756:in `log'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activerecord-7.0.2.3/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:630:in `raw_execute'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activerecord-7.0.2.3/lib/active_record/connection_adapters/mysql/database_statements.rb:96:in `raw_execute'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activerecord-7.0.2.3/lib/active_record/connection_adapters/mysql/database_statements.rb:47:in `execute'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activerecord-7.0.2.3/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:207:in `execute_and_free'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activerecord-7.0.2.3/lib/active_record/connection_adapters/mysql/database_statements.rb:73:in `block in exec_delete'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.2.3/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `handle_interrupt'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.2.3/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `block in synchronize'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.2.3/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `handle_interrupt'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.2.3/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `synchronize'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activerecord-7.0.2.3/lib/active_record/connection_adapters/mysql/database_statements.rb:72:in `exec_delete'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activerecord-7.0.2.3/lib/active_record/connection_adapters/abstract/database_statements.rb:175:in `update'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activerecord-7.0.2.3/lib/active_record/connection_adapters/abstract/query_cache.rb:22:in `update'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activerecord-7.0.2.3/lib/active_record/persistence.rb:514:in `_update_record'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activerecord-7.0.2.3/lib/active_record/persistence.rb:822:in `update_columns'
/opt/exercism/website/app/commands/git/sync_practice_exercise.rb:11:in `call'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/mandate-2.2.0/lib/mandate/call_injector.rb:10:in `call'
/opt/exercism/website/app/commands/git/sync_track.rb:132:in `block in sync_practice_exercises!'
/opt/exercism/website/app/commands/git/sync_track.rb:114:in `each'
/opt/exercism/website/app/commands/git/sync_track.rb:114:in `each_with_index'
/opt/exercism/website/app/commands/git/sync_track.rb:114:in `sync_practice_exercises!'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/mandate-2.2.0/lib/mandate/memoize.rb:47:in `block (2 levels) in __mandate_memoize'
/opt/exercism/website/app/commands/git/sync_track.rb:40:in `call'
/opt/exercism/website/config/initializers/mandate.rb:6:in `perform'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activejob-7.0.2.3/lib/active_job/execution.rb:59:in `block in _perform_job'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.2.3/lib/active_support/callbacks.rb:118:in `block in run_callbacks'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/bugsnag-6.24.2/lib/bugsnag/integrations/rails/active_job.rb:38:in `block (2 levels) in included'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.2.3/lib/active_support/callbacks.rb:127:in `instance_exec'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.2.3/lib/active_support/callbacks.rb:127:in `block in run_callbacks'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/i18n-1.12.0/lib/i18n.rb:322:in `with_locale'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activejob-7.0.2.3/lib/active_job/translation.rb:9:in `block (2 levels) in <module:Translation>'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.2.3/lib/active_support/callbacks.rb:127:in `instance_exec'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.2.3/lib/active_support/callbacks.rb:127:in `block in run_callbacks'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.2.3/lib/active_support/core_ext/time/zones.rb:66:in `use_zone'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activejob-7.0.2.3/lib/active_job/timezones.rb:9:in `block (2 levels) in <module:Timezones>'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.2.3/lib/active_support/callbacks.rb:127:in `instance_exec'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.2.3/lib/active_support/callbacks.rb:127:in `block in run_callbacks'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.2.3/lib/active_support/callbacks.rb:138:in `run_callbacks'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activejob-7.0.2.3/lib/active_job/execution.rb:58:in `_perform_job'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activejob-7.0.2.3/lib/active_job/instrumentation.rb:20:in `_perform_job'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activejob-7.0.2.3/lib/active_job/execution.rb:46:in `perform_now'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activejob-7.0.2.3/lib/active_job/instrumentation.rb:14:in `block in perform_now'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activejob-7.0.2.3/lib/active_job/instrumentation.rb:25:in `block in instrument'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.2.3/lib/active_support/notifications.rb:206:in `block in instrument'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.2.3/lib/active_support/notifications/instrumenter.rb:24:in `instrument'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.2.3/lib/active_support/notifications.rb:206:in `instrument'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activejob-7.0.2.3/lib/active_job/instrumentation.rb:35:in `instrument'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activejob-7.0.2.3/lib/active_job/instrumentation.rb:14:in `perform_now'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activejob-7.0.2.3/lib/active_job/logging.rb:18:in `block in perform_now'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.2.3/lib/active_support/tagged_logging.rb:99:in `block in tagged'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.2.3/lib/active_support/tagged_logging.rb:37:in `tagged'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.2.3/lib/active_support/tagged_logging.rb:99:in `tagged'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activejob-7.0.2.3/lib/active_job/logging.rb:25:in `tag_logger'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activejob-7.0.2.3/lib/active_job/logging.rb:18:in `perform_now'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activejob-7.0.2.3/lib/active_job/execution.rb:24:in `block in execute'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.2.3/lib/active_support/callbacks.rb:118:in `block in run_callbacks'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activejob-7.0.2.3/lib/active_job/railtie.rb:54:in `block (4 levels) in <class:Railtie>'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.2.3/lib/active_support/execution_wrapper.rb:92:in `wrap'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.2.3/lib/active_support/reloader.rb:72:in `block in wrap'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.2.3/lib/active_support/execution_wrapper.rb:88:in `wrap'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.2.3/lib/active_support/reloader.rb:71:in `wrap'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activejob-7.0.2.3/lib/active_job/railtie.rb:53:in `block (3 levels) in <class:Railtie>'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.2.3/lib/active_support/callbacks.rb:127:in `instance_exec'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.2.3/lib/active_support/callbacks.rb:127:in `block in run_callbacks'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.2.3/lib/active_support/callbacks.rb:138:in `run_callbacks'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activejob-7.0.2.3/lib/active_job/execution.rb:22:in `execute'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activejob-7.0.2.3/lib/active_job/queue_adapters/sidekiq_adapter.rb:42:in `perform'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/sidekiq-6.4.1/lib/sidekiq/processor.rb:196:in `execute_job'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/sidekiq-6.4.1/lib/sidekiq/processor.rb:164:in `block (2 levels) in process'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/sidekiq-6.4.1/lib/sidekiq/middleware/chain.rb:138:in `block in invoke'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/bugsnag-6.24.2/lib/bugsnag/integrations/sidekiq.rb:24:in `call'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/sidekiq-6.4.1/lib/sidekiq/middleware/chain.rb:140:in `block in invoke'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/sidekiq-failures-1.0.1/lib/sidekiq/failures/middleware.rb:9:in `call'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/sidekiq-6.4.1/lib/sidekiq/middleware/chain.rb:140:in `block in invoke'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/skylight-5.3.2/lib/skylight/sidekiq.rb:33:in `block in call'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/skylight-5.3.2/lib/skylight.rb:150:in `block in trace'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/skylight-5.3.2/lib/skylight/instrumenter.rb:224:in `trace'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/skylight-5.3.2/lib/skylight.rb:149:in `trace'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/skylight-5.3.2/lib/skylight/sidekiq.rb:32:in `call'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/sidekiq-6.4.1/lib/sidekiq/middleware/chain.rb:140:in `block in invoke'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/sidekiq-6.4.1/lib/sidekiq/middleware/chain.rb:143:in `invoke'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/sidekiq-6.4.1/lib/sidekiq/processor.rb:163:in `block in process'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/sidekiq-6.4.1/lib/sidekiq/processor.rb:136:in `block (6 levels) in dispatch'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/sidekiq-6.4.1/lib/sidekiq/job_retry.rb:114:in `local'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/sidekiq-6.4.1/lib/sidekiq/processor.rb:135:in `block (5 levels) in dispatch'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/sidekiq-6.4.1/lib/sidekiq/rails.rb:14:in `block in call'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.2.3/lib/active_support/execution_wrapper.rb:92:in `wrap'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.2.3/lib/active_support/reloader.rb:72:in `block in wrap'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.2.3/lib/active_support/execution_wrapper.rb:92:in `wrap'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.2.3/lib/active_support/reloader.rb:71:in `wrap'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/sidekiq-6.4.1/lib/sidekiq/rails.rb:13:in `call'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/sidekiq-6.4.1/lib/sidekiq/processor.rb:131:in `block (4 levels) in dispatch'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/sidekiq-6.4.1/lib/sidekiq/processor.rb:257:in `stats'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/sidekiq-6.4.1/lib/sidekiq/processor.rb:126:in `block (3 levels) in dispatch'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/sidekiq-6.4.1/lib/sidekiq/job_logger.rb:13:in `call'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/sidekiq-6.4.1/lib/sidekiq/processor.rb:125:in `block (2 levels) in dispatch'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/sidekiq-6.4.1/lib/sidekiq/job_retry.rb:81:in `global'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/sidekiq-6.4.1/lib/sidekiq/processor.rb:124:in `block in dispatch'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/sidekiq-6.4.1/lib/sidekiq/job_logger.rb:39:in `prepare'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/sidekiq-6.4.1/lib/sidekiq/processor.rb:123:in `dispatch'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/sidekiq-6.4.1/lib/sidekiq/processor.rb:162:in `process'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/sidekiq-6.4.1/lib/sidekiq/processor.rb:78:in `process_one'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/sidekiq-6.4.1/lib/sidekiq/processor.rb:68:in `run'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/sidekiq-6.4.1/lib/sidekiq/util.rb:56:in `watchdog'
/opt/exercism/website/vendor/bundle/ruby/3.1.0/gems/sidekiq-6.4.1/lib/sidekiq/util.rb:65:in `block in safe_thread'

Please tag @exercism/maintainers-admin if you require more information.

Hi.
While I was learning concepts for JavaScript I found out that closures theory isn't very helpful for solving the suggested practical exercise: Coordinate Transformation.

I would like to propose to improve it by

  • adding a more advanced example with an explanation for using a function in return
  • explain how to work with its arguments then.

Let me know what do you think.
Connected links are here:
https://exercism.org/tracks/javascript/concepts/closures
https://exercism.org/tracks/javascript/exercises/coordinate-transformation

⚠️ If you have issues / are unsure, create ONE PR PER EXERCISE so it's easier to merge them as we can have discussions per exercise. If you're certain, it's fine to do a single one.

The idea is to split #960 into smaller chunks.

Here is the list of practices exercises to deal with for this part :

darts

roman-numerals

binary

hexadecimal

octal

square-root

trinary

all-your-base

minesweeper

queen-attack

react

zipper

Lately, for some PRs CI does not run at all for whatever reason.

Example (#1663):
image

Notice that it says "Checks 0" at the top.

When I close and open the PR, CI is triggered, all checks run as they should:
image

We also saw this happening on PRs when someone executed the format action via GitHub. CI was not triggered after that change was added.

Concept Roadmap

There are already a lot of ideas for additional concepts that we could cover with concept exercises in the future.
You can find a list in our roadmap document: Roadmap - Potential Future Concepts

We already created issues for the following new concepts/exercises:

Additionally some concept exercises that exist but need major improvements are not yet visible on the website (status "wip"), see #1415.

Purpose of this issue

  • Suggest additional concepts to cover that are not on the roadmap yet.
  • Comment on which concept from the roadmap you would like to see implemented first.
  • Volunteer for creating a certain concept exercise that does not have an issue yet, so a maintainer can write up an issue with some basic guidelines for you.
  • General discussion about how to divide concepts/ how to structure the concept tree.
  • etc

Getting Started

If you have not yet contributed to concept exercises before, this task requires some upfront reading to acquire the necessary background knowledge.

Here you can read about what Concept Exercises are and how they are structured:

If you have not done so yet, it is probably also helpful to do a couple of "Learning Exercises" (this is how they are called on the site) yourself. You can also look at the code of an existing concept exercise like bird-watcher (concept for-loops) for reference.

See the documentation above (general documentation), as well as How to implement a Concept Exercise in JavaScript.

Also be aware of these general guidelines.

Goal

The goal here is to create a new concept exercise to teach regular expressions. The concept needs to be written from scratch, the exercise can be ported from another track (see details below).

Concepts

The following concept needs to be created. You can use the introduction.md file of the concept also as introduction.md file of the exercise. No need to create different content at this point. Additionally, if you want to save some time it is ok to not have an extensive about.md for now. It can also be mainly the introduction.md content, maybe with some additions you would like to make.

  • regular-expressions

Learning Objectives

In the concepts the student should learn about the following topics and then practice them in the concept exercise.

  • which flavor of regex is used in JavaScript and any notable differences to other common implementations
  • how to create a regular expression
  • how to pass flags in both versions of creating a regular expression
  • how to use the most common regex related functions, with special focus on
    • when to use test and when to use match
    • understanding the different parts of the match result incl. capture results
  • using e.g. https://regex101.com/ to help with writing/reading regex
  • being aware of performance implications

Out of Scope

Explaining how to write regular expressions themselves is out of scope for the concept here but we should link to some good resource a student could read to learn about them from scratch, maybe Eloquent JavaScript for example. We don't do this as part of the concept because Exercism assumes the student is already fluent in another language and most languages include some form of regular expressions.

Prerequisites

  • arrays as this is the result of match etc.
  • classes to understand the new Regex syntax

Exercise Idea

C# "Parsing Log Lines" Exercise could serve as template.

In case you port that exercise, make sure to check all tasks make sense for JavaScript and whether some additional task needs to be added to cover some JavaScript specific content.

Resources

Here some links that might be helpful as a starting point and/or for the links section of the concept:

How to proceed

  1. First accept this issue by saying "I'd like to work on this" (no need to wait for a response, just go ahead).
  2. Use this issue to discuss any questions you have, what should be included in the content and what not and to collect more reference material.
  3. Create a PR and set "exercism/javascript" as reviewers. Additionally you can write in #maintaining-javascript on Slack that your PR is ready for review. Once you incorporated any critical feedback that the reviewer might give you and the PR is approved, it will be merged by a maintainer.

Getting started

Here you can read about what Concept Exercises are and how they are structured:

If you have not done so yet, it is probably also helpful to do a couple of "Learning Exercises" (this is how they are called on the site) yourself. You can also look at the code of an existing concept exercise like bird-watcher (concept for-loops) for reference.

Goal

The goal is to create new concept exercise that teaches the use of the rest and spread operator in the context of functions (rest parameters), arrays and objects.

Motivation

Currently, the concept exercise "Elyses Destructered Enchantments" teaches array destructing and the rest and spread operator (...) which also includes object related content. In the future we also want to teach object destructering as a concept. Since it would be too much to also add that into the same exercise, we want to have a new split. In the future, we want to change "Elyses Destructered Enchantments" so that it focuses on array and object destructering in the context of extracting individual elements/properties. In turn, rest and spread should be covered by a new exercise that the student will complete after "Elyses Destructered Enchantments".

Please note that updating the existing exercise "Elyses Destructered Enchantments" is out of scope for this issue. There will be a separate issue for that later.

Concepts

The concept rest-and-spread already exists but feel free to improve the content or add more advanced content to the about.md file as you see fit.

https://github.com/exercism/javascript/tree/main/concepts/rest-and-spread

Learning Objectives

The student should learn what is covered in the existing concept: https://github.com/exercism/javascript/blob/main/concepts/rest-and-spread/introduction.md

Prerequisites

The following things should be assumed and defined as prerequisites for the exercise.

  • functions
  • array-destructering (in the context of extracting individual elements, no rest operator)
  • Although this concept is not available yet, you can assume the student also already knows about object destructering (in the context of extracting individual properties)

Story

Here some hints what can help to come up with a story for the exercise.

  • Think about/write down some tasks you would like the student to do (just generic tasks, no story), sometimes that already sparks an idea for a story to wrap the tasks.
  • Browse through the existing stories https://exercism.org/docs/building/tracks/stories (click on the individual story in the menu on the left), usually you won't find an exact match but some story might spark your inspiration for some general theme.
  • In the end, you can make nearly every story fit every concept so just picking some theme and rolling with it also works.

Help

You can choose to do this solo-style, or collaborate with multiple people on this. The suggested approach is to

  1. First accept this issue by saying "I'd like to work on this" (no need to wait for a response, just go with it) and optionally request that someone works with you (and wait for a second person to accept your request).
  2. Use this issue to discuss any questions you have, what should be included in the content and what not and to collect reference material.
  3. Create a PR and set "exercism/javascript" as reviewers. Additionally you can write in #maintaining-javascript that your PR is ready for review. Once you incorporated any critical feedback that the reviewer might give you and the PR is approved, it will be merged by a maintainer.

I've noticed that there are a lot "error" cases in this exercise. IMO these two tests are superfluous : "close already closed account throws error" and "open already opened account throws error".

Indeed, IMO there is no functional problem with closing an already closed account. In a real world, I try to go by the "Define errors out of existence" principle from "A Philosophy of Software Design" by John Ousterhout. In this chapter, the author points out that throwing errors unnecessarily increase the complexity of the software. We shouldn't be throwing errors if there is no real problem.

⚠️ If you have issues / are unsure, create ONE PR PER EXERCISE so it's easier to merge them as we can have discussions per exercise. If you're certain, it's fine to do a single one.

The idea is to split #960 into smaller chunks.

Here is the list of practices exercises to deal with for this part :

anagram

acronym

high-scores

isogram

matching-brackets

phone-number

scale-generator

series

largest-series-product

transpose

grep

rectangles

spiral-matrix

ocr-numbers

saddle-points

forth

food-chain

house

isbn-verifier

pig-latin

Issue in updateScore function

const scoreBoard = {
      'Amil Pastorius': 99373,
      'Min-seo Shin': 0,
      'Jesse Johnson': 1337,
    };
const expected = {
      'Amil Pastorius': 99373,
      'Min-seo Shin': 1999,
      'Jesse Johnson': 2674,
    };
updateScore(scoreBoard, 'Min-seo Shin', 1999);
- const actual = updateScore(scoreBoard, 'Jesse Johnson', 1337);
+ const actual = updateScore(scoreBoard, 'Jesse Johnson', 2674);
expect(actual).toEqual(expected);
expect(Object.is(actual, scoreBoard)).toBe(true);

Issue described in this closed PR still exists: Falsy not truthy #1382

Content on line 34 of javascript/concepts/type-conversion/introduction.md

Note that because of the described rules, '0', 'false', [] and {} are thruthy in JavaScript.

This is an error as 0 and false are clearly present in the list of falsy values in the docs https://developer.mozilla.org/en-US/docs/Glossary/Falsy

⚠️ If you have issues / are unsure, create ONE PR PER EXERCISE so it's easier to merge them as we can have discussions per exercise. If you're certain, it's fine to do a single one.

The idea is to split #960 into smaller chunks.

Here is the list of practices exercises to deal with for this part :

collatz-conjecture

triangle

clock

meetup

etl

hamming

raindrops

nucleotide-count

scrabble-score

allergies

word-count

bank-account

difference-of-squares

perfect-numbers

complex-numbers

luhn

prime-factors

grains

pythagorean-triplet

palindrome-products

Due to a recent update to the test-runner, these messages do not show. Working on a fix. You can subscribe to the issue on the right side of the screen to get an update when it is fixed.

Related but not covered by #1818,

The hints have not been updated in #1725. For example, the first task:

- Use the imported API function checkStatus in your function.
- Pass a callback function to checkStatus. It should expect to receive a string argument.
- Return the result from the checkStatus API function.

But the correct implementation is:

export function onSuccess() {
  notify({ message: 'SUCCESS' })
}

The hints.md file can be found here: https://github.com/exercism/javascript/blob/main/exercises/concept/fruit-picker/.docs/hints.md

General information of how to write the hints.md file can be found here: https://exercism.org/docs/building/tracks/concept-exercises#h-file-docs-hints-md

Hi. I am working on the javascript track and am currently doing the translation exercise. I am using the online editor and receiving this error when ever i try to run tests We received the following error when we ran your code:

● Test suite failed to run

Cannot find module 'core-js/modules/es.array.push.js' from '../../api.js'

Require stack:
/api.js
/service.spec.js

Screenshot (6)

I have refreshed the page, flushed the browser cache,reverted the exercise to start and still this keeps appearing without adding any new code.. Any help will be greatly appreciated.

I have also noticed that all my exercises are unlocked even though I am in learning mode.

Task 3 of the concept exercise custom-signs states:

If the age is 50 or older, the sign will include the word mature, otherwise the sign will include the word young.

This made me believe that the tests would accept any message for the sign, as long as it included the word mature if the age is 50 or older, or the word young otherwise. However, that seems to not be the case, and the tests expect only very specific strings:

test('age is less than 50', () => {
expect(buildBirthdaySign(49)).toBe(
'Happy Birthday! What a young fellow you are.'
);
});
test('age is 50 or older', () => {
expect(buildBirthdaySign(51)).toBe(
'Happy Birthday! What a mature fellow you are.'
);
});

I think either the description should be changed to state the phrase accepted is the one on the example provided or alternatively the tests should be changed to accept any phrase, in which case they would only for the presence of young or mature in those phrases.

Shouldn't it be <slug>.js instead of <slug>.cs at line 93?

Note: The concept was already created, only the exercise is missing now.

Getting Started

If you have not yet contributed to concept exercises before, this task requires some upfront reading to acquire the necessary background knowledge.

Here you can read about what Concept Exercises are and how they are structured:

If you have not done so yet, it is probably also helpful to do a couple of "Learning Exercises" (this is how they are called on the site) yourself. You can also look at the code of an existing concept exercise like bird-watcher (concept for-loops) for reference.

See the documentation above (general documentation), as well as How to implement a Concept Exercise in JavaScript.

Also be aware of these general guidelines.

Goal

The goal here is to create a new concept exercise that teaches working with dates via Date.

The concept needs to be written from scratch, the exercise can be ported from another track (see details below).

Concepts

The following concept needs to be created. You can use the introduction.md file of the concept also as introduction.md file of the exercise. No need to create different content at this point. Additionally, if you want to save some time it is ok to not have an extensive about.md for now. It can also be mainly the introduction.md content, maybe with some additions you would like to make.

  • dates (maybe use "Date and Time" as display name in the config)

Learning Objectives

In the concepts the student should learn about the following topics and then practice them in the concept exercise.

  • how dates/timestamps are represented internally, see e.g. MDN link
  • how to create dates with new Date, incl. some of the commonly used variants
  • Date.parse
  • Date.now
  • getting and setting the date components (getMonth/setMonth etc.)
  • how to calculate a time difference
  • how to compare dates

The about.md file could additionally mention ...

Out of Scope

Prerequisites

  • classes

Other prerequisites should be added as needed to solve the specific exercise.

Exercise Idea

There are two options for exercises from other languages that could be used as a template.

If you port one of these exercises, make sure only to include tasks that actually make sense in JavaScript and add value for the student. Feel free to remove/replace/add tasks as needed.

Resources

Here some links that might be helpful as a starting point and/or for the links section of the concept:

How to proceed

  1. First accept this issue by saying "I'd like to work on this" (no need to wait for a response, just go ahead).
  2. Use this issue to discuss any questions you have, what should be included in the content and what not and to collect more reference material.
  3. Create a PR and set "exercism/javascript" as reviewers. Additionally you can write in #maintaining-javascript on Slack that your PR is ready for review. Once you incorporated any critical feedback that the reviewer might give you and the PR is approved, it will be merged by a maintainer.