Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[V3] Lucian's Lucious Lasagna: fix everything around this exercise #1018

Merged
merged 15 commits into from
Mar 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 48 additions & 4 deletions concepts/basics/about.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,21 @@

JavaScript is a dynamic, prototype based language. It has a few [primitives][mdn-primitive], and everything else is considered an object.

While it is most well-known as the scripting language for Web pages, many non-browser environments also use it, such as Node.js. The language is actively being developed; and because of it's multi-paradigm property, allows for many styles of programming.
While it is most well-known as the scripting language for Web pages, many non-browser environments also use it, such as Node.js. The language is actively being developed; and because of it's multi-paradigm property, allows for many styles of programming. JavaScript is a dynamic language, supporting object-oriented, imperative, and declarative (e.g. functional programming) styles.
SleeplessByte marked this conversation as resolved.
Show resolved Hide resolved

## Constants, `const` and immutability
## (Re-)assignment

The `const` keyword is mentioned _both_ for variables and constants. Another concept often mentioned around constants is [(im)-mutability][wiki-mutability].
Variables in JavaScript can be defined using the [`const`][mdn-const], [`let`][mdn-let] or [`var`][mdn-var] keyword. A variable can reference different objects over its lifetime when using `let` or `var`, but can not be reassigned when using `const`. For example, `myFirstVariable` can be defined and redefined many times using the `=` operator:

```javascript
let myFirstVariable = 1;
myFirstVariable = 'Some string';
myFirstVariable = new SomeComplexClass();
```

## Constant assignment

The `const` keyword is mentioned _both_ for variables and constants. Another concept often mentioned around constants is [(im)-mutability][wiki-mutability]. Constants in JavaScript can only be defined using `const`. These are meant to be assigned only once.

The `const` keyword only makes the _binding_ immutable, that is, you can only assign a value to a `const` variable once. In JavaScript, only [primitive][mdn-primitive] values are immutable. However, [non primitive][mdn-primitive] values can still be mutated.

Expand All @@ -20,7 +30,9 @@ MY_MUTABLE_VALUE_CONSTANT;
// => { food: "pear" }
```

As a rule, we don't mutate values that look like `const SCREAMING_SNAKE_CASE`. When we _must_ to enforce this, use [`Object.freeze(value)`][mdn-object-freeze].
## Constant value (immutability)

As a rule, on Exercism, and many other organisations and project style guides, don't mutate values that look like `const SCREAMING_SNAKE_CASE`. Technically the values _can_ be changed, but for clarity and expectation management on Exercism this is discouraged. When this _must_ be enforced, use [`Object.freeze(value)`][mdn-object-freeze].

```javascript
const MY_VALUE_CONSTANT = Object.freeze({ food: 'apple' });
Expand All @@ -34,6 +46,21 @@ MY_MUTABLE_VALUE_CONSTANT;

In the wild, it's unlikely to see `Object.freeze` all over a code base, but the rule to not mutate a `SCREAMING_SNAKE_CASE` value ever, is a good rule; often enforced using automated analysis such as a linter.

## Function declarations

In JavaScript, units of functionality are encapsulated in _functions_, usually grouping functions together in the same file if they belong together. These functions can take parameters (arguments), and can _return_ a value using the `return` keyword. Functions are invoked using `()` syntax.

```javascript
function add(num1, num2) {
return num1 + num2;
}

add(1, 3);
// => 4
```

> 💡 In JavaScript there are _many_ different ways to declare a function. These other ways look different than using the `function` keyword. The track tries to gradually introduce them, but if you already know about them, feel free to use any of them. In most cases, using one of the other isn't better or worse.
SleeplessByte marked this conversation as resolved.
Show resolved Hide resolved

## Export and import

The `export` and `import` keywords are powerful tools that turn a regular JavaScript file into a [JavaScript module][mdn-module]. Apart from allowing code to selectively expose components, such as functions, classes, variables and constants, it also enables a whole range of other features, such as:
Expand All @@ -43,6 +70,23 @@ The `export` and `import` keywords are powerful tools that turn a regular JavaSc
- [Tree shaking][blog-tree-shaking], which reduces the size of the final code by eliminating side-effect free modules and even contents of modules _that are not used_,
- Exporting [_live bindings_][blog-live-bindings], which allows you to export a value that mutates everywhere it's imported if the original value mutates.

A concrete example is how the tests work on Exercism's JavaScript Track. Each exercise has at least one implementation file, for example `lasagna.js`, and each exercise has at least one test file, for example `lasagna.spec.js`. The implementation file uses `export` to expose the public API and the test file uses `import` to access these, which is how it can test the implementation's outcomes.

```javascript
// file.js
export const MY_VALUE = 10;

export function add(num1, num2) {
return num1 + num2;
}

// file.spec.js
import { MY_VALUE, add } from './file';

add(MY_VALUE, 5);
// => 15
```

[blog-live-bindings]: https://2ality.com/2015/07/es6-module-exports.html#es6-modules-export-immutable-bindings
[blog-tree-shaking]: https://bitsofco.de/what-is-tree-shaking/
[mdn-dynamic-imports]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#Dynamic_Imports
Expand Down
20 changes: 16 additions & 4 deletions concepts/basics/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

JavaScript is a dynamic language, supporting object-oriented, imperative, and declarative (e.g. functional programming) styles.

There are a few primary ways to assign values to names in JavaScript - using variables or constants. On Exercism, variables are always written in [camelCase][wiki-camel-case]; constants are written in [SCREAMING_SNAKE_CASE][wiki-snake-case].
There are a few primary ways to assign values to names in JavaScript - using variables or constants. On Exercism, variables are always written in [camelCase][wiki-camel-case]; constants are written in [SCREAMING_SNAKE_CASE][wiki-snake-case]. There is no official guide to follow, and various companies and organizations have various style guides. _Feel free to write variables any way you like_. The upside from writing them the way the exercises are prepared is that they'll be highlighted differently in the web interface and most IDEs.

## (Re-)assignment

Variables in JavaScript can be defined using the [`const`][mdn-const], [`let`][mdn-let] or [`var`][mdn-var] keyword. A variable can reference different objects over its lifetime when using `let` or `var`, but can not be reassigned when using `const`. For example, `myFirstVariable` can be defined and redefined many times using the `=` operator:

Expand All @@ -12,7 +14,9 @@ myFirstVariable = 'Some string';
myFirstVariable = new SomeComplexClass();
```

Constants in JavaScript can only be defined using `const`. These are meant to be assigned only once. For clarity, on Excercism they must start with capital letters and are normally written in block capitals with words separated by underscores. For example:
## Constant assignment

Constants in JavaScript can only be defined using `const`. These are meant to be assigned only once. For clarity, on Excercism please start constants with capital letters and continue writing the rest of the name using capitals with words separated by underscores. For example:

```javascript
const MY_FIRST_CONSTANT = 10;
Expand All @@ -22,7 +26,11 @@ MY_FIRST_CONSTANT = 20;
// => TypeError: Assignment to constant variable.
```

In JavaScript, units of functionality are encapsulated in _functions_, usually grouping functions together in the same file if they belong together. These functions can take arguments, and can return a value using the `return` keyword. Methods are invoked using `()` syntax.
> 💡 In a later Concept Exercise the difference between _constant_ assignment / binding and _constant_ value is explored and explained.

## Function declarations

In JavaScript, units of functionality are encapsulated in _functions_, usually grouping functions together in the same file if they belong together. These functions can take parameters (arguments), and can _return_ a value using the `return` keyword. Functions are invoked using `()` syntax.

```javascript
function add(num1, num2) {
Expand All @@ -33,7 +41,11 @@ add(1, 3);
// => 4
```

To make a `function`, constant, or variable available in _other files_, they need to be [exported][mdn-export] using the `export` keyword. Another file may then [import][mdn-import] these using the `import` keyword.
> 💡 In JavaScript there are _many_ different ways to declare a function. These other ways look different than using the `function` keyword. The track tries to gradually introduce them, but if you already know about them, feel free to use any of them. In most cases, using one of the other isn't better or worse.

## Exposing to other files

To make a `function`, a constant, or a variable available in _other files_, they need to be [exported][mdn-export] using the `export` keyword. Another file may then [import][mdn-import] these using the `import` keyword. This is also known as the module system. A great example is how all the tests work. Each exercise has at least one file, for example `lasagna.js`, which has the _implementation_. There is then at least one other file, for example `lasagna.spec.js`, which _imports_ the public API in order to test the implementation:

```javascript
// file.js
Expand Down
30 changes: 11 additions & 19 deletions concepts/basics/links.json
Original file line number Diff line number Diff line change
@@ -1,42 +1,34 @@
[
{
"url": "https://developer.mozilla.org/en-US/docs/Glossary/Primitive",
"description": "mdn-primitive"
},
{
"url": "https://en.wikipedia.org/wiki/Immutable_object",
"description": "wiki-mutability"
},
{
"url": "https://developer.mozilla.org/en-US/docs/Glossary/Primitive",
"description": "mdn-primitive"
},
{
"url": "https://developer.mozilla.org/en-US/docs/Glossary/Primitive",
"description": "mdn-primitive"
"description": "MDN Glossary: JavaScript Primitive"
},
{
"url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze",
"description": "mdn-object-freeze"
"description": "MDN: JavaScript Object freezing"
},
{
"url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules",
"description": "mdn-module"
"description": "MDN: JavaScript Module System"
},
{
"url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules#Renaming_imports_and_exports",
"description": "mdn-renaming-modules"
"description": "MDN: Renaming modules when importing or exporting"
},
{
"url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#Dynamic_Imports",
"description": "mdn-dynamic-imports"
"description": "MDN: JavaScript Dynamic imports"
},
{
"url": "https://en.wikipedia.org/wiki/Immutable_object",
"description": "About immutable objects"
},
{
"url": "https://bitsofco.de/what-is-tree-shaking/",
"description": "blog-tree-shaking"
"description": "About tree shaking"
},
{
"url": "https://2ality.com/2015/07/es6-module-exports.html#es6-modules-export-immutable-bindings",
"description": "blog-live-bindings"
"description": "About live bindings (JavaScript exports)"
}
]
5 changes: 3 additions & 2 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@
"status": "beta"
},
{
"slug": "basics",
"slug": "lasagna",
"name": "Lucian's Luscious Lasagna",
"uuid": "97bf898a-36fc-47fc-b870-01fc0c7fe554",
"concepts": ["basics"],
"prerequisites": [],
Expand Down Expand Up @@ -1510,7 +1511,7 @@
"uuid": "611d6b3d-1241-4432-90f6-8fcffb36917c",
"slug": "basics",
"name": "Basics",
"blurb": "TODO: add blurb for basics concept"
"blurb": "The minimal knowledge required to get started in JavaScript. Function declarations, variable assignment, and a few operators for numbers. "
},
{
"uuid": "791d215c-6813-479a-a126-d9ad9cdc49a9",
Expand Down
39 changes: 0 additions & 39 deletions exercises/concept/basics/.meta/exemplar.js

This file was deleted.

44 changes: 0 additions & 44 deletions exercises/concept/basics/basics.js

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ EXPECTED_MINUTES_IN_OVEN;

## 2. Calculate the remaining oven time in minutes

Implement the `remainingMinutesInOven` function that takes the actual minutes the lasagna has been in the oven as a parameter and returns how many minutes the lasagna still has to remain in the oven, based on the expected oven time in minutes from the previous task.
Implement the `remainingMinutesInOven` function that takes the actual minutes the lasagna has been in the oven as a _parameter_ and _returns_ how many minutes the lasagna still has to remain in the oven, based on the **expected oven time in minutes** from the previous task.

```javascript
remainingMinutesInOven(30);
Expand All @@ -24,7 +24,7 @@ remainingMinutesInOven(30);

## 3. Calculate the preparation time in minutes

Implement the `preparationTimeInMinutes` function that takes the number of layers you added to the lasagna as a parameter and returns how many minutes you spent preparing the lasagna, assuming each layer takes you 2 minutes to prepare.
Implement the `preparationTimeInMinutes` function that takes the number of layers you added to the lasagna as a _parameter_ and _returns_ how many minutes you spent preparing the lasagna, assuming each layer takes you 2 minutes to prepare.

```javascript
preparationTimeInMinutes(2);
Expand All @@ -33,7 +33,7 @@ preparationTimeInMinutes(2);

## 4. Calculate the total working time in minutes

Implement the `totalTimeInMinutes` function that takes two parameters: the `numberOfLayers` parameter is the number of layers you added to the lasagna, and the `actualMinutesInOven` parameter is the number of minutes the lasagna has been in the oven. The function should return how many minutes in total you've worked on cooking the lasagna, which is the sum of the preparation time in minutes, and the time in minutes the lasagna has spent in the oven at the moment.
Implement the `totalTimeInMinutes` function that takes _two parameters_: the `numberOfLayers` parameter is the number of layers you added to the lasagna, and the `actualMinutesInOven` parameter is the number of minutes the lasagna has been in the oven. The function should _return_ how many minutes in total you've worked on cooking the lasagna, which is the sum of the preparation time in minutes, and the time in minutes the lasagna has spent in the oven at the moment.

```javascript
totalTimeInMinutes(3, 20);
Expand Down
Loading