From 0dce4a8bd4c51178461d815dace59faad1d90170 Mon Sep 17 00:00:00 2001 From: Cedd Burge Date: Sun, 7 Jan 2024 19:29:02 +0000 Subject: [PATCH 01/14] Add approaches for Leap --- .../.approaches/case-expression/content.md | 35 ++++++ .../.approaches/case-expression/snippet.txt | 11 ++ .../practice/leap/.approaches/config.json | 36 ++++++ .../leap/.approaches/if-expression/content.md | 45 ++++++++ .../.approaches/if-expression/snippet.txt | 17 +++ .../practice/leap/.approaches/introduction.md | 106 ++++++++++++++++++ .../.approaches/logical-expression/content.md | 32 ++++++ .../logical-expression/snippet.txt | 7 ++ 8 files changed, 289 insertions(+) create mode 100644 exercises/practice/leap/.approaches/case-expression/content.md create mode 100644 exercises/practice/leap/.approaches/case-expression/snippet.txt create mode 100644 exercises/practice/leap/.approaches/config.json create mode 100644 exercises/practice/leap/.approaches/if-expression/content.md create mode 100644 exercises/practice/leap/.approaches/if-expression/snippet.txt create mode 100644 exercises/practice/leap/.approaches/introduction.md create mode 100644 exercises/practice/leap/.approaches/logical-expression/content.md create mode 100644 exercises/practice/leap/.approaches/logical-expression/snippet.txt diff --git a/exercises/practice/leap/.approaches/case-expression/content.md b/exercises/practice/leap/.approaches/case-expression/content.md new file mode 100644 index 00000000..6a9b802f --- /dev/null +++ b/exercises/practice/leap/.approaches/case-expression/content.md @@ -0,0 +1,35 @@ +# Case expression + +```elm +isLeapYear : Int -> Bool +isLeapYear year = + let + isDivisibleByFour = (modBy 4 year) == 0 + isDivisibleBy100 = (modBy 100 year) == 0 + isDivisibleBy400 = (modBy 400 year) == 0 + in + case (isDivisibleByFour, isDivisibleBy100, isDivisibleBy400) of + (True, _, True) -> True + (True, False, _) -> True + _ -> False +``` + +## In this approach + +In this approach we use a [case expression][case-expression], and match on a [Tuple][tuple] +It turns out that, if we are careful to ask questions in the right order, we can always potentially attain certainty about the answer by asking one more question. +This is a [truth-table][truth-table] like approach, which can be easier to read for complicated logic. + +## When to use a case expression? + +Using a case expression with a `Tuple` is idiomatic in Elm, but Tuple's have a maximum of 3 values, so can't be used for anything larger than this. + +Strings and arrays can hold more values and can also be used with case statements, which are useful in many circumstances. Using an array with a case statement and recursion is especially common. + +[case-expression]: + https://exercism.org/tracks/haskell/exercises/leap/approaches/conditional-expression + "Approach: a conditional expression" + +[tuple] + https://elmprogramming.com/tuple.html + "Tuples in Elm" diff --git a/exercises/practice/leap/.approaches/case-expression/snippet.txt b/exercises/practice/leap/.approaches/case-expression/snippet.txt new file mode 100644 index 00000000..1932a51c --- /dev/null +++ b/exercises/practice/leap/.approaches/case-expression/snippet.txt @@ -0,0 +1,11 @@ +isLeapYear : Int -> Bool +isLeapYear year = + let + isDivisibleByFour = (modBy 4 year) == 0 + isDivisibleBy100 = (modBy 100 year) == 0 + isDivisibleBy400 = (modBy 400 year) == 0 + in + case (isDivisibleByFour, isDivisibleBy100, isDivisibleBy400) of + (True, _, True) -> True + (True, False, _) -> True + _ -> False diff --git a/exercises/practice/leap/.approaches/config.json b/exercises/practice/leap/.approaches/config.json new file mode 100644 index 00000000..1ebf99cb --- /dev/null +++ b/exercises/practice/leap/.approaches/config.json @@ -0,0 +1,36 @@ +{ + "introduction": { + "authors": [ + "MatthijsBlom" + ] + }, + "approaches": [ + { + "uuid": "a89d3a43-affc-4dc7-97b7-d5ce9353a8d5", + "slug": "logical-expression", + "title": "Logical expression", + "blurb": "Use logical operators to combine several tests into one.", + "authors": [ + "MatthijsBlom" + ] + }, + { + "uuid": "a6fbc4d9-911b-42cc-aa88-e015dd1f03b0", + "slug": "guards", + "title": "Guards", + "blurb": "Use a sequence of guards.", + "authors": [ + "MatthijsBlom" + ] + }, + { + "uuid": "708be8e8-0a2e-437d-8b39-6df37326890f", + "slug": "conditional-expression", + "title": "Conditional expression", + "blurb": "Use a single conditional expression.", + "authors": [ + "MatthijsBlom" + ] + } + ] +} diff --git a/exercises/practice/leap/.approaches/if-expression/content.md b/exercises/practice/leap/.approaches/if-expression/content.md new file mode 100644 index 00000000..52465e1e --- /dev/null +++ b/exercises/practice/leap/.approaches/if-expression/content.md @@ -0,0 +1,45 @@ +# If expresion + +```elm +isLeapYear : Int -> Bool +isLeapYear year = + let + divisbleBy number = + modBy number year == 0 + in + if divisbleBy(400) then + return True + + else if divisbleBy(100) then + return False + + else if divisbleBy(4) then + return True + + else + return False + +``` + +An _if expression_ (`if … then … else …`) is a compound expression that uses a test to determine which of two alternatives to evaluate to. +Many other languages feature a similar construct, often termed 'ternary operator'. + +## In this approach + +This approach uses exactly two tests to determine whether a year is a leap year. + +The first test is for divisibility by 100. +Once we know if the year is a multiple of 100, we know which further test to perform. + +- If the year is evenly divisible by 100, then `divisibleBy 100` will evaluate to `True` and the entire `if` expression will evaluate to whatever `divisibleBy 400` evaluates to. +- If the year is _not_ evenly divisible by 100, then `divisibleBy 100` is `False` and so the `if` expression evaluates to `divisibleBy 4`. + +## When to use `if`? + +`if` expressions might be a good fit when you + +- need an expression that +- chooses between exactly two options +- depending on a single `Bool`. + +When you have something other than a `Bool`, use `case` instead. diff --git a/exercises/practice/leap/.approaches/if-expression/snippet.txt b/exercises/practice/leap/.approaches/if-expression/snippet.txt new file mode 100644 index 00000000..d069f776 --- /dev/null +++ b/exercises/practice/leap/.approaches/if-expression/snippet.txt @@ -0,0 +1,17 @@ +isLeapYear : Int -> Bool +isLeapYear year = + let + divisbleBy number = + modBy number year == 0 + in + if divisbleBy(400) then + return True + + else if divisbleBy(100) then + return False + + else if divisbleBy(4) then + return True + + else + return False diff --git a/exercises/practice/leap/.approaches/introduction.md b/exercises/practice/leap/.approaches/introduction.md new file mode 100644 index 00000000..81277eea --- /dev/null +++ b/exercises/practice/leap/.approaches/introduction.md @@ -0,0 +1,106 @@ +# Introduction + +There are various idiomatic approaches to solve Leap. +All approaches listed below check for divisibility by 4, 100, and 400. +However, they differ in the ways in which they combine these checks. + +## Approach: a logical expression + +```elm +isLeapYear : Int -> Bool +isLeapYear year = + let + divisbleBy number = + modBy number year == 0 + in + divisibleBy 4 && (not (divisibleBy 100) || divisibleBy 400) +``` + +A logicial expression is the most concise approach. +[Read more about this approach][logical-expression]. + +## Approach: an if expression + +```elm +isLeapYear : Int -> Bool +isLeapYear year = + let + divisbleBy number = + modBy number year == 0 + in + if divisbleBy(400) then + return True + + else if divisbleBy(100) then + return False + + else if divisbleBy(4) then + return True + + else + return False +``` + +An if statement is not as concise, but is [easier to describe][describable-code]. +[Read more about this approach][if-expression]. + +## Approach: a case expression + +```elm +isLeapYear : Int -> Bool +isLeapYear year = + let + isDivisibleByFour = (modBy 4 year) == 0 + isDivisibleBy100 = (modBy 100 year) == 0 + isDivisibleBy400 = (modBy 400 year) == 0 + in + case (isDivisibleByFour, isDivisibleBy100, isDivisibleBy400) of + (True, _, True) -> True + (True, False, _) -> True + _ -> False +``` + +This takes a [truth-table][truth-table] like approach, which can be easier to read for complicated logic. +[Read more about this approach][case-expression]. + +## Other approaches + +There are also more esoteric approaches, [such as this one using recursion, an array and a case statement][esoteric-approach], that are not idiomatic, but that can be interesting to look at, and probably come about by trying to solve the problem using some artificial constraints, as you would often do in a code kata. + +## General guidance + +The key to determining whether a given year is a leap year is to know whether the year is evenly divisible by `4`, `100`, and `400`. +For determining that, you can use the [`modBy` function][modby-function], which yields the remainder after division. + +You don't need to use a ['let' statement][let-statement] to define an `isDivisibleBy` function, although all the examples here do to aid readability. + +## Which approach to use? + +Code exists primarily for humans to read and reason about. +Therefore, in general, go with the approach that _makes the most sense_. + +All approaches listed here are valid choices unless marked otherwise. +Be sure to check out all of their individual pages though: they each have interesting things to say! + +[logical-expression]: + https://exercism.org/tracks/elm/exercises/leap/approaches/conditional-expression + "Approach: a conditional expression" +[if-expression]: + https://exercism.org/tracks/elm/exercises/leap/approaches/if-statement + "Approach: an if statement" +[case-expression]: + https://exercism.org/tracks/elm/exercises/leap/approaches/case-statement + "Approach: a case statement" + +[describable-code]: + https://www.freecodecamp.org/news/writing-describable-code/ + "Writing easily describable code" +[truth-table]: + https://brilliant.org/wiki/truth-tables/ + "Writing easily describable code" +[esoteric-approach] + https://exercism.org/tracks/elm/exercises/leap/solutions/edgerunner + "An esoteric solution to leap, using recursion, an array and a case statement" +[modby-function] + https://package.elm-lang.org/packages/elm/core/latest/Basics#modBy + "modBy function in Elm" diff --git a/exercises/practice/leap/.approaches/logical-expression/content.md b/exercises/practice/leap/.approaches/logical-expression/content.md new file mode 100644 index 00000000..880084de --- /dev/null +++ b/exercises/practice/leap/.approaches/logical-expression/content.md @@ -0,0 +1,32 @@ +# Logical expression + +```elm +isLeapYear : Int -> Bool +isLeapYear year = + let + divisbleBy number = + modBy number year == 0 + in + divisibleBy 4 && (not (divisibleBy 100) || divisibleBy 400) +``` + +We can combine smaller logical statements into larger ones using the logical operators `&&` (and), `||` (or), and `not` (negation). + +## Precedence + +In school they teach you that `2 + 3 * 4` is to be read as meaning `2 + (3 * 4)`. +This is a convention, chosen for its convenience. +We say that the `*` operator has _higher [precedence][precedence]_ than `+`. + +In logic similar ambiguities exist, and these are similarly resolved. + +- _and_ has higher precedence than _or_, and +- _not_ has higher precedence than both _and_ and _or_. + +For example, `p || q && r` means the same as `p || (q && r)`. + +If you don't wish to remember the precendence of all the things, or force readers of your code to do so, you can use parentheses to make it explicit. + +[precedence]: + https://en.wikipedia.org/wiki/Order_of_operations + "Wikipedia: Order of operations" diff --git a/exercises/practice/leap/.approaches/logical-expression/snippet.txt b/exercises/practice/leap/.approaches/logical-expression/snippet.txt new file mode 100644 index 00000000..b4c98ae0 --- /dev/null +++ b/exercises/practice/leap/.approaches/logical-expression/snippet.txt @@ -0,0 +1,7 @@ +isLeapYear : Int -> Bool +isLeapYear year = + let + divisbleBy number = + modBy number year == 0 + in + divisibleBy 4 && (not (divisibleBy 100) || divisibleBy 400) From 8411f882a9f435adfac3f71985a138a0bacfb7b1 Mon Sep 17 00:00:00 2001 From: Cedd Burge Date: Mon, 8 Jan 2024 08:05:05 +0000 Subject: [PATCH 02/14] Update config.json for leap approaches --- .../practice/leap/.approaches/config.json | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/exercises/practice/leap/.approaches/config.json b/exercises/practice/leap/.approaches/config.json index 1ebf99cb..3b61036b 100644 --- a/exercises/practice/leap/.approaches/config.json +++ b/exercises/practice/leap/.approaches/config.json @@ -1,7 +1,7 @@ { "introduction": { "authors": [ - "MatthijsBlom" + "ceddlyburge" ] }, "approaches": [ @@ -11,25 +11,25 @@ "title": "Logical expression", "blurb": "Use logical operators to combine several tests into one.", "authors": [ - "MatthijsBlom" + "ceddlyburge" ] }, { "uuid": "a6fbc4d9-911b-42cc-aa88-e015dd1f03b0", - "slug": "guards", - "title": "Guards", - "blurb": "Use a sequence of guards.", + "slug": "case-expression", + "title": "Case expression", + "blurb": "Use a case expression.", "authors": [ - "MatthijsBlom" + "ceddlyburge" ] }, { "uuid": "708be8e8-0a2e-437d-8b39-6df37326890f", - "slug": "conditional-expression", - "title": "Conditional expression", - "blurb": "Use a single conditional expression.", + "slug": "if-expression", + "title": "If expression", + "blurb": "Use an if expression.", "authors": [ - "MatthijsBlom" + "ceddlyburge" ] } ] From 607bfa38c48f81df35441c213fd0494663917138 Mon Sep 17 00:00:00 2001 From: Cedd Burge Date: Mon, 8 Jan 2024 08:21:18 +0000 Subject: [PATCH 03/14] Add links and backticks --- .../leap/.approaches/case-expression/content.md | 6 ++++-- .../leap/.approaches/if-expression/content.md | 16 ++++++++++++++-- .../practice/leap/.approaches/introduction.md | 7 +++++-- .../.approaches/logical-expression/content.md | 2 ++ 4 files changed, 25 insertions(+), 6 deletions(-) diff --git a/exercises/practice/leap/.approaches/case-expression/content.md b/exercises/practice/leap/.approaches/case-expression/content.md index 6a9b802f..2daca544 100644 --- a/exercises/practice/leap/.approaches/case-expression/content.md +++ b/exercises/practice/leap/.approaches/case-expression/content.md @@ -16,7 +16,7 @@ isLeapYear year = ## In this approach -In this approach we use a [case expression][case-expression], and match on a [Tuple][tuple] +In this approach we use a [`case` expression][case-expression], and match on a [`Tuple`][tuple] It turns out that, if we are careful to ask questions in the right order, we can always potentially attain certainty about the answer by asking one more question. This is a [truth-table][truth-table] like approach, which can be easier to read for complicated logic. @@ -29,7 +29,9 @@ Strings and arrays can hold more values and can also be used with case statement [case-expression]: https://exercism.org/tracks/haskell/exercises/leap/approaches/conditional-expression "Approach: a conditional expression" - [tuple] https://elmprogramming.com/tuple.html "Tuples in Elm" +[truth-table]: + https://brilliant.org/wiki/truth-tables/ + "Truth tables" diff --git a/exercises/practice/leap/.approaches/if-expression/content.md b/exercises/practice/leap/.approaches/if-expression/content.md index 52465e1e..ea1f0bce 100644 --- a/exercises/practice/leap/.approaches/if-expression/content.md +++ b/exercises/practice/leap/.approaches/if-expression/content.md @@ -21,7 +21,7 @@ isLeapYear year = ``` -An _if expression_ (`if … then … else …`) is a compound expression that uses a test to determine which of two alternatives to evaluate to. +An [`if` expression][if-expressions] (`if … then … else …`) is a compound expression that uses a test to determine which of two alternatives to evaluate to. Many other languages feature a similar construct, often termed 'ternary operator'. ## In this approach @@ -34,12 +34,24 @@ Once we know if the year is a multiple of 100, we know which further test to per - If the year is evenly divisible by 100, then `divisibleBy 100` will evaluate to `True` and the entire `if` expression will evaluate to whatever `divisibleBy 400` evaluates to. - If the year is _not_ evenly divisible by 100, then `divisibleBy 100` is `False` and so the `if` expression evaluates to `divisibleBy 4`. +This approach is not as concise as the [logical-expression][logical-expression], but it is [easier to describe][describable-code], which makes it easier to comunicate the problem domain. + ## When to use `if`? -`if` expressions might be a good fit when you +[`if` expressions][if-expression] might be a good fit when you - need an expression that - chooses between exactly two options - depending on a single `Bool`. When you have something other than a `Bool`, use `case` instead. + +[if-expression]: + https://elm-lang.org/docs/syntax#conditionals + "if expressions in Elm" +[logical-expression]: + https://exercism.org/tracks/elm/exercises/leap/approaches/conditional-expression + "Approach: a conditional expression" +[describable-code]: + https://www.freecodecamp.org/news/writing-describable-code/ + "Writing easily describable code" diff --git a/exercises/practice/leap/.approaches/introduction.md b/exercises/practice/leap/.approaches/introduction.md index 81277eea..ee1c41b6 100644 --- a/exercises/practice/leap/.approaches/introduction.md +++ b/exercises/practice/leap/.approaches/introduction.md @@ -72,7 +72,7 @@ There are also more esoteric approaches, [such as this one using recursion, an a The key to determining whether a given year is a leap year is to know whether the year is evenly divisible by `4`, `100`, and `400`. For determining that, you can use the [`modBy` function][modby-function], which yields the remainder after division. -You don't need to use a ['let' statement][let-statement] to define an `isDivisibleBy` function, although all the examples here do to aid readability. +You don't need to use a ['let' expression][let-expression] to define an `isDivisibleBy` function, although all the examples here do to aid readability. ## Which approach to use? @@ -97,10 +97,13 @@ Be sure to check out all of their individual pages though: they each have intere "Writing easily describable code" [truth-table]: https://brilliant.org/wiki/truth-tables/ - "Writing easily describable code" + "Truth tables" [esoteric-approach] https://exercism.org/tracks/elm/exercises/leap/solutions/edgerunner "An esoteric solution to leap, using recursion, an array and a case statement" [modby-function] https://package.elm-lang.org/packages/elm/core/latest/Basics#modBy "modBy function in Elm" +[let-expression] + https://elm-lang.org/docs/syntax#let-expressions + "let expressions in Elm" diff --git a/exercises/practice/leap/.approaches/logical-expression/content.md b/exercises/practice/leap/.approaches/logical-expression/content.md index 880084de..c760326b 100644 --- a/exercises/practice/leap/.approaches/logical-expression/content.md +++ b/exercises/practice/leap/.approaches/logical-expression/content.md @@ -12,6 +12,8 @@ isLeapYear year = We can combine smaller logical statements into larger ones using the logical operators `&&` (and), `||` (or), and `not` (negation). +A logicial expression is the most concise approach. + ## Precedence In school they teach you that `2 + 3 * 4` is to be read as meaning `2 + (3 * 4)`. From 02dc0eb70833dfefbe5c42b63808b093aa1096e3 Mon Sep 17 00:00:00 2001 From: Cedd Burge Date: Mon, 8 Jan 2024 08:23:29 +0000 Subject: [PATCH 04/14] Format and update uuids --- .../practice/leap/.approaches/config.json | 66 +++++++++---------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/exercises/practice/leap/.approaches/config.json b/exercises/practice/leap/.approaches/config.json index 3b61036b..0d6a2130 100644 --- a/exercises/practice/leap/.approaches/config.json +++ b/exercises/practice/leap/.approaches/config.json @@ -1,36 +1,36 @@ { - "introduction": { - "authors": [ - "ceddlyburge" - ] - }, - "approaches": [ - { - "uuid": "a89d3a43-affc-4dc7-97b7-d5ce9353a8d5", - "slug": "logical-expression", - "title": "Logical expression", - "blurb": "Use logical operators to combine several tests into one.", - "authors": [ - "ceddlyburge" - ] - }, - { - "uuid": "a6fbc4d9-911b-42cc-aa88-e015dd1f03b0", - "slug": "case-expression", - "title": "Case expression", - "blurb": "Use a case expression.", - "authors": [ - "ceddlyburge" - ] - }, - { - "uuid": "708be8e8-0a2e-437d-8b39-6df37326890f", - "slug": "if-expression", - "title": "If expression", - "blurb": "Use an if expression.", - "authors": [ - "ceddlyburge" - ] - } + "introduction": { + "authors": [ + "ceddlyburge" ] + }, + "approaches": [ + { + "uuid": "243cf336-7c0b-430b-a064-c976adea8d70", + "slug": "logical-expression", + "title": "Logical expression", + "blurb": "Use logical operators to combine several tests into one.", + "authors": [ + "ceddlyburge" + ] + }, + { + "uuid": "31ad676e-299b-4b7a-912c-3e4f68b5d873", + "slug": "case-expression", + "title": "Case expression", + "blurb": "Use a case expression.", + "authors": [ + "ceddlyburge" + ] + }, + { + "uuid": "9546e09d-9cde-4da1-b78a-0ef33d7d6db3", + "slug": "if-expression", + "title": "If expression", + "blurb": "Use an if expression.", + "authors": [ + "ceddlyburge" + ] + } + ] } From 6803c16f4fc3d3f118e14fa2aacfa002679d8d93 Mon Sep 17 00:00:00 2001 From: Cedd Burge Date: Mon, 8 Jan 2024 08:25:40 +0000 Subject: [PATCH 05/14] Reduce snippet lengths as per linting rules --- .../.approaches/case-expression/snippet.txt | 15 +++-------- .../.approaches/if-expression/snippet.txt | 25 ++++++------------- 2 files changed, 12 insertions(+), 28 deletions(-) diff --git a/exercises/practice/leap/.approaches/case-expression/snippet.txt b/exercises/practice/leap/.approaches/case-expression/snippet.txt index 1932a51c..68a534cc 100644 --- a/exercises/practice/leap/.approaches/case-expression/snippet.txt +++ b/exercises/practice/leap/.approaches/case-expression/snippet.txt @@ -1,11 +1,4 @@ -isLeapYear : Int -> Bool -isLeapYear year = - let - isDivisibleByFour = (modBy 4 year) == 0 - isDivisibleBy100 = (modBy 100 year) == 0 - isDivisibleBy400 = (modBy 400 year) == 0 - in - case (isDivisibleByFour, isDivisibleBy100, isDivisibleBy400) of - (True, _, True) -> True - (True, False, _) -> True - _ -> False +case (isDivisibleByFour, isDivisibleBy100, isDivisibleBy400) of + (True, _, True) -> True + (True, False, _) -> True + _ -> False diff --git a/exercises/practice/leap/.approaches/if-expression/snippet.txt b/exercises/practice/leap/.approaches/if-expression/snippet.txt index d069f776..3228df06 100644 --- a/exercises/practice/leap/.approaches/if-expression/snippet.txt +++ b/exercises/practice/leap/.approaches/if-expression/snippet.txt @@ -1,17 +1,8 @@ -isLeapYear : Int -> Bool -isLeapYear year = - let - divisbleBy number = - modBy number year == 0 - in - if divisbleBy(400) then - return True - - else if divisbleBy(100) then - return False - - else if divisbleBy(4) then - return True - - else - return False +if divisbleBy(400) then + return True +else if divisbleBy(100) then + return False +else if divisbleBy(4) then + return True +else + return False From 438b540c2f9ce25daced781b336b6713a7da3fe5 Mon Sep 17 00:00:00 2001 From: Cedd Burge Date: Mon, 8 Jan 2024 08:44:12 +0000 Subject: [PATCH 06/14] Fix links and copy --- .../leap/.approaches/case-expression/content.md | 7 ++++--- .../leap/.approaches/if-expression/content.md | 2 +- exercises/practice/leap/.approaches/introduction.md | 12 +++++------- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/exercises/practice/leap/.approaches/case-expression/content.md b/exercises/practice/leap/.approaches/case-expression/content.md index 2daca544..28ca9e10 100644 --- a/exercises/practice/leap/.approaches/case-expression/content.md +++ b/exercises/practice/leap/.approaches/case-expression/content.md @@ -24,11 +24,12 @@ This is a [truth-table][truth-table] like approach, which can be easier to read Using a case expression with a `Tuple` is idiomatic in Elm, but Tuple's have a maximum of 3 values, so can't be used for anything larger than this. -Strings and arrays can hold more values and can also be used with case statements, which are useful in many circumstances. Using an array with a case statement and recursion is especially common. +Strings and arrays can hold more values and can also be used with case statements, which are useful in many circumstances. +Using an array with a case statement and recursion is especially common. [case-expression]: - https://exercism.org/tracks/haskell/exercises/leap/approaches/conditional-expression - "Approach: a conditional expression" + https://elmprogramming.com/case-expression.html + "case expressions in Elm" [tuple] https://elmprogramming.com/tuple.html "Tuples in Elm" diff --git a/exercises/practice/leap/.approaches/if-expression/content.md b/exercises/practice/leap/.approaches/if-expression/content.md index ea1f0bce..64dbac9d 100644 --- a/exercises/practice/leap/.approaches/if-expression/content.md +++ b/exercises/practice/leap/.approaches/if-expression/content.md @@ -21,7 +21,7 @@ isLeapYear year = ``` -An [`if` expression][if-expressions] (`if … then … else …`) is a compound expression that uses a test to determine which of two alternatives to evaluate to. +An [`if` expression][if-expression] (`if … then … else …`) is a compound expression that uses a test to determine which of two alternatives to evaluate to. Many other languages feature a similar construct, often termed 'ternary operator'. ## In this approach diff --git a/exercises/practice/leap/.approaches/introduction.md b/exercises/practice/leap/.approaches/introduction.md index ee1c41b6..9f127e50 100644 --- a/exercises/practice/leap/.approaches/introduction.md +++ b/exercises/practice/leap/.approaches/introduction.md @@ -80,18 +80,16 @@ Code exists primarily for humans to read and reason about. Therefore, in general, go with the approach that _makes the most sense_. All approaches listed here are valid choices unless marked otherwise. -Be sure to check out all of their individual pages though: they each have interesting things to say! [logical-expression]: - https://exercism.org/tracks/elm/exercises/leap/approaches/conditional-expression + https://exercism.org/tracks/elm/exercises/leap/approaches/logical-expression "Approach: a conditional expression" [if-expression]: - https://exercism.org/tracks/elm/exercises/leap/approaches/if-statement - "Approach: an if statement" + https://exercism.org/tracks/elm/exercises/leap/approaches/if-expression + "Approach: an if expression" [case-expression]: - https://exercism.org/tracks/elm/exercises/leap/approaches/case-statement - "Approach: a case statement" - + https://exercism.org/tracks/elm/exercises/leap/approaches/case-expression + "Approach: a case expression" [describable-code]: https://www.freecodecamp.org/news/writing-describable-code/ "Writing easily describable code" From 9c2ce5ca489873ce494944455b15333f696579f6 Mon Sep 17 00:00:00 2001 From: Cedd Burge Date: Mon, 8 Jan 2024 08:48:00 +0000 Subject: [PATCH 07/14] Use "expression" instead of "statement" --- .../practice/leap/.approaches/case-expression/content.md | 4 ++-- exercises/practice/leap/.approaches/introduction.md | 6 +++--- .../practice/leap/.approaches/logical-expression/content.md | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/exercises/practice/leap/.approaches/case-expression/content.md b/exercises/practice/leap/.approaches/case-expression/content.md index 28ca9e10..5064cbae 100644 --- a/exercises/practice/leap/.approaches/case-expression/content.md +++ b/exercises/practice/leap/.approaches/case-expression/content.md @@ -24,8 +24,8 @@ This is a [truth-table][truth-table] like approach, which can be easier to read Using a case expression with a `Tuple` is idiomatic in Elm, but Tuple's have a maximum of 3 values, so can't be used for anything larger than this. -Strings and arrays can hold more values and can also be used with case statements, which are useful in many circumstances. -Using an array with a case statement and recursion is especially common. +Strings and arrays can hold more values and can also be used with case expressions, which are useful in many circumstances. +Using an array with a case expression and recursion is especially common. [case-expression]: https://elmprogramming.com/case-expression.html diff --git a/exercises/practice/leap/.approaches/introduction.md b/exercises/practice/leap/.approaches/introduction.md index 9f127e50..22ad3414 100644 --- a/exercises/practice/leap/.approaches/introduction.md +++ b/exercises/practice/leap/.approaches/introduction.md @@ -41,7 +41,7 @@ isLeapYear year = return False ``` -An if statement is not as concise, but is [easier to describe][describable-code]. +An if expression is not as concise, but is [easier to describe][describable-code]. [Read more about this approach][if-expression]. ## Approach: a case expression @@ -65,7 +65,7 @@ This takes a [truth-table][truth-table] like approach, which can be easier to re ## Other approaches -There are also more esoteric approaches, [such as this one using recursion, an array and a case statement][esoteric-approach], that are not idiomatic, but that can be interesting to look at, and probably come about by trying to solve the problem using some artificial constraints, as you would often do in a code kata. +There are also more esoteric approaches, [such as this one using recursion, an array and a case expression][esoteric-approach], that are not idiomatic, but that can be interesting to look at, and probably come about by trying to solve the problem using some artificial constraints, as you would often do in a code kata. ## General guidance @@ -98,7 +98,7 @@ All approaches listed here are valid choices unless marked otherwise. "Truth tables" [esoteric-approach] https://exercism.org/tracks/elm/exercises/leap/solutions/edgerunner - "An esoteric solution to leap, using recursion, an array and a case statement" + "An esoteric solution to leap, using recursion, an array and a case expression" [modby-function] https://package.elm-lang.org/packages/elm/core/latest/Basics#modBy "modBy function in Elm" diff --git a/exercises/practice/leap/.approaches/logical-expression/content.md b/exercises/practice/leap/.approaches/logical-expression/content.md index c760326b..4226d005 100644 --- a/exercises/practice/leap/.approaches/logical-expression/content.md +++ b/exercises/practice/leap/.approaches/logical-expression/content.md @@ -10,7 +10,7 @@ isLeapYear year = divisibleBy 4 && (not (divisibleBy 100) || divisibleBy 400) ``` -We can combine smaller logical statements into larger ones using the logical operators `&&` (and), `||` (or), and `not` (negation). +We can combine smaller logical expressions into larger ones using the logical operators `&&` (and), `||` (or), and `not` (negation). A logicial expression is the most concise approach. From 0ef0849c104459b7abb8935619a1ca96a535f1f1 Mon Sep 17 00:00:00 2001 From: Cedd Burge Date: Mon, 8 Jan 2024 10:39:45 +0000 Subject: [PATCH 08/14] Update exercises/practice/leap/.approaches/case-expression/content.md Co-authored-by: Jie --- exercises/practice/leap/.approaches/case-expression/content.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/practice/leap/.approaches/case-expression/content.md b/exercises/practice/leap/.approaches/case-expression/content.md index 5064cbae..29cb57ba 100644 --- a/exercises/practice/leap/.approaches/case-expression/content.md +++ b/exercises/practice/leap/.approaches/case-expression/content.md @@ -22,7 +22,7 @@ This is a [truth-table][truth-table] like approach, which can be easier to read ## When to use a case expression? -Using a case expression with a `Tuple` is idiomatic in Elm, but Tuple's have a maximum of 3 values, so can't be used for anything larger than this. +Using a case expression with a `Tuple` is idiomatic in Elm, but tuples have a maximum of 3 values, so can't be used for anything larger than this. Strings and arrays can hold more values and can also be used with case expressions, which are useful in many circumstances. Using an array with a case expression and recursion is especially common. From 58c5c7941508f3814d39d27c763bc56bed8806f7 Mon Sep 17 00:00:00 2001 From: Cedd Burge Date: Mon, 8 Jan 2024 10:39:57 +0000 Subject: [PATCH 09/14] Update exercises/practice/leap/.approaches/if-expression/content.md Co-authored-by: Jie --- exercises/practice/leap/.approaches/if-expression/content.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/practice/leap/.approaches/if-expression/content.md b/exercises/practice/leap/.approaches/if-expression/content.md index 64dbac9d..5015d279 100644 --- a/exercises/practice/leap/.approaches/if-expression/content.md +++ b/exercises/practice/leap/.approaches/if-expression/content.md @@ -1,4 +1,4 @@ -# If expresion +# If expression ```elm isLeapYear : Int -> Bool From 5cba4b0f322e2a95ca86f46447136b957a2285a9 Mon Sep 17 00:00:00 2001 From: Cedd Burge Date: Mon, 8 Jan 2024 10:40:05 +0000 Subject: [PATCH 10/14] Update exercises/practice/leap/.approaches/if-expression/content.md Co-authored-by: Jie --- exercises/practice/leap/.approaches/if-expression/content.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/practice/leap/.approaches/if-expression/content.md b/exercises/practice/leap/.approaches/if-expression/content.md index 5015d279..a54079a4 100644 --- a/exercises/practice/leap/.approaches/if-expression/content.md +++ b/exercises/practice/leap/.approaches/if-expression/content.md @@ -4,7 +4,7 @@ isLeapYear : Int -> Bool isLeapYear year = let - divisbleBy number = + divisibleBy number = modBy number year == 0 in if divisbleBy(400) then From 8e37323242aa237fa67eceb1934317be7449eed8 Mon Sep 17 00:00:00 2001 From: Cedd Burge Date: Mon, 8 Jan 2024 10:51:50 +0000 Subject: [PATCH 11/14] Address code review comments --- .../.approaches/case-expression/content.md | 4 +-- .../leap/.approaches/if-expression/content.md | 16 +++++------ .../.approaches/if-expression/snippet.txt | 16 +++++------ .../practice/leap/.approaches/introduction.md | 27 +++++++++---------- .../.approaches/logical-expression/content.md | 2 +- .../logical-expression/snippet.txt | 2 +- 6 files changed, 30 insertions(+), 37 deletions(-) diff --git a/exercises/practice/leap/.approaches/case-expression/content.md b/exercises/practice/leap/.approaches/case-expression/content.md index 29cb57ba..b7db3242 100644 --- a/exercises/practice/leap/.approaches/case-expression/content.md +++ b/exercises/practice/leap/.approaches/case-expression/content.md @@ -24,8 +24,8 @@ This is a [truth-table][truth-table] like approach, which can be easier to read Using a case expression with a `Tuple` is idiomatic in Elm, but tuples have a maximum of 3 values, so can't be used for anything larger than this. -Strings and arrays can hold more values and can also be used with case expressions, which are useful in many circumstances. -Using an array with a case expression and recursion is especially common. +Strings and lists can hold more values and can also be used with case expressions, which are useful in many circumstances. +Using a list with a case expression and recursion is especially common. [case-expression]: https://elmprogramming.com/case-expression.html diff --git a/exercises/practice/leap/.approaches/if-expression/content.md b/exercises/practice/leap/.approaches/if-expression/content.md index a54079a4..72c7c05a 100644 --- a/exercises/practice/leap/.approaches/if-expression/content.md +++ b/exercises/practice/leap/.approaches/if-expression/content.md @@ -7,18 +7,14 @@ isLeapYear year = divisibleBy number = modBy number year == 0 in - if divisbleBy(400) then - return True + if divisibleBy 400 then + True - else if divisbleBy(100) then - return False + else if divisibleBy 100 then + False - else if divisbleBy(4) then - return True - - else - return False - + else + divisibleBy 4 ``` An [`if` expression][if-expression] (`if … then … else …`) is a compound expression that uses a test to determine which of two alternatives to evaluate to. diff --git a/exercises/practice/leap/.approaches/if-expression/snippet.txt b/exercises/practice/leap/.approaches/if-expression/snippet.txt index 3228df06..36c3ae83 100644 --- a/exercises/practice/leap/.approaches/if-expression/snippet.txt +++ b/exercises/practice/leap/.approaches/if-expression/snippet.txt @@ -1,8 +1,8 @@ -if divisbleBy(400) then - return True -else if divisbleBy(100) then - return False -else if divisbleBy(4) then - return True -else - return False +if divisibleBy(400) then + True + +else if divisibleBy(100) then + False + +else + divisibleBy 4 diff --git a/exercises/practice/leap/.approaches/introduction.md b/exercises/practice/leap/.approaches/introduction.md index 22ad3414..4fe80283 100644 --- a/exercises/practice/leap/.approaches/introduction.md +++ b/exercises/practice/leap/.approaches/introduction.md @@ -10,7 +10,7 @@ However, they differ in the ways in which they combine these checks. isLeapYear : Int -> Bool isLeapYear year = let - divisbleBy number = + divisibleBy number = modBy number year == 0 in divisibleBy 4 && (not (divisibleBy 100) || divisibleBy 400) @@ -25,20 +25,17 @@ A logicial expression is the most concise approach. isLeapYear : Int -> Bool isLeapYear year = let - divisbleBy number = + divisibleBy number = modBy number year == 0 in - if divisbleBy(400) then - return True - - else if divisbleBy(100) then - return False - - else if divisbleBy(4) then - return True - - else - return False + if divisibleBy(400) then + True + + else if divisibleBy(100) then + False + + else + divisibleBy 4 ``` An if expression is not as concise, but is [easier to describe][describable-code]. @@ -65,7 +62,7 @@ This takes a [truth-table][truth-table] like approach, which can be easier to re ## Other approaches -There are also more esoteric approaches, [such as this one using recursion, an array and a case expression][esoteric-approach], that are not idiomatic, but that can be interesting to look at, and probably come about by trying to solve the problem using some artificial constraints, as you would often do in a code kata. +There are also more esoteric approaches, [such as this one using recursion, a list and a case expression][esoteric-approach], that are not idiomatic, but that can be interesting to look at, and probably come about by trying to solve the problem using some artificial constraints, as you would often do in a code kata. ## General guidance @@ -98,7 +95,7 @@ All approaches listed here are valid choices unless marked otherwise. "Truth tables" [esoteric-approach] https://exercism.org/tracks/elm/exercises/leap/solutions/edgerunner - "An esoteric solution to leap, using recursion, an array and a case expression" + "An esoteric solution to leap, using recursion, a list and a case expression" [modby-function] https://package.elm-lang.org/packages/elm/core/latest/Basics#modBy "modBy function in Elm" diff --git a/exercises/practice/leap/.approaches/logical-expression/content.md b/exercises/practice/leap/.approaches/logical-expression/content.md index 4226d005..11d5f59e 100644 --- a/exercises/practice/leap/.approaches/logical-expression/content.md +++ b/exercises/practice/leap/.approaches/logical-expression/content.md @@ -4,7 +4,7 @@ isLeapYear : Int -> Bool isLeapYear year = let - divisbleBy number = + divisibleBy number = modBy number year == 0 in divisibleBy 4 && (not (divisibleBy 100) || divisibleBy 400) diff --git a/exercises/practice/leap/.approaches/logical-expression/snippet.txt b/exercises/practice/leap/.approaches/logical-expression/snippet.txt index b4c98ae0..09a3286d 100644 --- a/exercises/practice/leap/.approaches/logical-expression/snippet.txt +++ b/exercises/practice/leap/.approaches/logical-expression/snippet.txt @@ -1,7 +1,7 @@ isLeapYear : Int -> Bool isLeapYear year = let - divisbleBy number = + divisibleBy number = modBy number year == 0 in divisibleBy 4 && (not (divisibleBy 100) || divisibleBy 400) From 73b4ed4d01223e7c73af56d9bccdfe24f5c5b2b4 Mon Sep 17 00:00:00 2001 From: Cedd Burge Date: Mon, 8 Jan 2024 11:08:25 +0000 Subject: [PATCH 12/14] Address code review comments --- exercises/practice/leap/.approaches/if-expression/snippet.txt | 4 ++-- exercises/practice/leap/.approaches/introduction.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/exercises/practice/leap/.approaches/if-expression/snippet.txt b/exercises/practice/leap/.approaches/if-expression/snippet.txt index 36c3ae83..a6c1b3c4 100644 --- a/exercises/practice/leap/.approaches/if-expression/snippet.txt +++ b/exercises/practice/leap/.approaches/if-expression/snippet.txt @@ -1,7 +1,7 @@ -if divisibleBy(400) then +if divisibleBy 400 then True -else if divisibleBy(100) then +else if divisibleBy 100 then False else diff --git a/exercises/practice/leap/.approaches/introduction.md b/exercises/practice/leap/.approaches/introduction.md index 4fe80283..d6976d3e 100644 --- a/exercises/practice/leap/.approaches/introduction.md +++ b/exercises/practice/leap/.approaches/introduction.md @@ -28,10 +28,10 @@ isLeapYear year = divisibleBy number = modBy number year == 0 in - if divisibleBy(400) then + if divisibleBy 400 then True - else if divisibleBy(100) then + else if divisibleBy 100 then False else From a022ccdd779b39379ad6c601e8b4d6c4135280ec Mon Sep 17 00:00:00 2001 From: Cedd Burge Date: Fri, 12 Jan 2024 12:37:43 +0000 Subject: [PATCH 13/14] Update exercises/practice/leap/.approaches/case-expression/content.md Co-authored-by: Jie --- exercises/practice/leap/.approaches/case-expression/content.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/practice/leap/.approaches/case-expression/content.md b/exercises/practice/leap/.approaches/case-expression/content.md index b7db3242..3d356d5b 100644 --- a/exercises/practice/leap/.approaches/case-expression/content.md +++ b/exercises/practice/leap/.approaches/case-expression/content.md @@ -16,7 +16,7 @@ isLeapYear year = ## In this approach -In this approach we use a [`case` expression][case-expression], and match on a [`Tuple`][tuple] +In this approach we use a [`case` expression][case-expression], and match on a [`Tuple`][tuple]. It turns out that, if we are careful to ask questions in the right order, we can always potentially attain certainty about the answer by asking one more question. This is a [truth-table][truth-table] like approach, which can be easier to read for complicated logic. From 3c97b91df032f6e08d8277ce4a0f9f0fff2f5a36 Mon Sep 17 00:00:00 2001 From: Cedd Burge Date: Fri, 12 Jan 2024 12:41:02 +0000 Subject: [PATCH 14/14] Update code for if-expression approach --- .../leap/.approaches/if-expression/content.md | 11 ++++------- .../leap/.approaches/if-expression/snippet.txt | 9 +++------ exercises/practice/leap/.approaches/introduction.md | 9 +++------ 3 files changed, 10 insertions(+), 19 deletions(-) diff --git a/exercises/practice/leap/.approaches/if-expression/content.md b/exercises/practice/leap/.approaches/if-expression/content.md index 72c7c05a..9586177c 100644 --- a/exercises/practice/leap/.approaches/if-expression/content.md +++ b/exercises/practice/leap/.approaches/if-expression/content.md @@ -7,13 +7,10 @@ isLeapYear year = divisibleBy number = modBy number year == 0 in - if divisibleBy 400 then - True - - else if divisibleBy 100 then - False - - else + if divisibleBy 100 then + divisibleBy 400 + + else divisibleBy 4 ``` diff --git a/exercises/practice/leap/.approaches/if-expression/snippet.txt b/exercises/practice/leap/.approaches/if-expression/snippet.txt index a6c1b3c4..8590458f 100644 --- a/exercises/practice/leap/.approaches/if-expression/snippet.txt +++ b/exercises/practice/leap/.approaches/if-expression/snippet.txt @@ -1,8 +1,5 @@ -if divisibleBy 400 then - True +if divisibleBy 100 then + divisibleBy 400 -else if divisibleBy 100 then - False - -else +else divisibleBy 4 diff --git a/exercises/practice/leap/.approaches/introduction.md b/exercises/practice/leap/.approaches/introduction.md index d6976d3e..6c52e82c 100644 --- a/exercises/practice/leap/.approaches/introduction.md +++ b/exercises/practice/leap/.approaches/introduction.md @@ -28,13 +28,10 @@ isLeapYear year = divisibleBy number = modBy number year == 0 in - if divisibleBy 400 then - True + if divisibleBy 100 then + divisibleBy 400 - else if divisibleBy 100 then - False - - else + else divisibleBy 4 ```