diff --git a/app/data/authors.yaml b/app/data/authors.yaml index 743a039..dfbf31d 100644 --- a/app/data/authors.yaml +++ b/app/data/authors.yaml @@ -29,4 +29,13 @@ description: | José is a cool guy. and here's more text. - thanks. \ No newline at end of file + thanks. + +- name: Venkat Subramaniam + email: venkats@agiledeveloper.com + photo_url: https://itkonekt.com/media/2019/12/Venkat.png + github: venkats + twitter: venkat_s + website: https://agiledeveloper.com/ + description: | + Venkat Placeholder. \ No newline at end of file diff --git a/app/pages/learn/01_tutorial/03_getting-to-know-the-language/03_refactoring_to_functional_style/00_refactoring.md b/app/pages/learn/01_tutorial/03_getting-to-know-the-language/03_refactoring_to_functional_style/00_refactoring.md new file mode 100644 index 0000000..6563b3a --- /dev/null +++ b/app/pages/learn/01_tutorial/03_getting-to-know-the-language/03_refactoring_to_functional_style/00_refactoring.md @@ -0,0 +1,23 @@ +--- +id: refactoring +title: "Refactoring from the Imperative to the Functional Style" +slug: learn/refactoring-to-functional-style +type: tutorial +category: language +category_order: 3 +group: refactoring-to-functional-style +layout: learn/tutorial-group-top.html +subheader_select: tutorials +main_css_id: learn +description: "Learning to change code from the Imperative to the Functional Style." +author: ["VenkatSubramaniam"] +--- + +This part of the tutorial helps you to learn the functional style equivalent of the imperative style code we often find. As you move forward in your projects, wherever it makes sense, you can change imperative style code to functional style code using the mappings you learn in this tutorial. + +In this series we cover the following conversions from the imperative to the functional style: + +| Tutorial |Imperative Style | Functional Style Equivalent | +|------------------------------------------------------|-----------------|------------------------------| +| [Converting Simple Loops](id:refactoring.simple.loops) | `for()` | `range()` or `rangeClosed()` | + diff --git a/app/pages/learn/01_tutorial/03_getting-to-know-the-language/03_refactoring_to_functional_style/01_converting_simple_loops.md b/app/pages/learn/01_tutorial/03_getting-to-know-the-language/03_refactoring_to_functional_style/01_converting_simple_loops.md new file mode 100644 index 0000000..604334f --- /dev/null +++ b/app/pages/learn/01_tutorial/03_getting-to-know-the-language/03_refactoring_to_functional_style/01_converting_simple_loops.md @@ -0,0 +1,97 @@ +--- +id: refactoring.simple.loops +title: Converting Simple Loops +slug: learn/refactoring-to-functional-style/simpleloops +type: tutorial-group +group: refactoring-to-functional-style +layout: learn/tutorial-group.html +subheader_select: tutorials +main_css_id: learn +toc: +- Imperative vs. Functional Styles {styles} +- Simple for Loops {simplefor} +- Mappings {mappings} +description: "Converting Simple Imperative Loops to Functional Style." +last_update: 2023-07-06 +author: ["VenkatSubramaniam"] +--- + +  +## Imperative vs. Functional Styles + +The older versions of Java supported the Object-Oriented paradigm mixed with the imperative style of programming. Starting Java 8, you can also mix the functional style of programming in your code. If your code base was started during the Java 7 or earlier times or later by programmers mostly familiar with older versions of Java, it will be filled with the imperative style code. + +Imperative style is where we tell what to do and also how to do it. Functional style is declarative in nature, where we tell what to do and delegate the how or the details to the underlying libraries. Imperative style code may be easier to write since most of us are very familiar with it. However, the code becomes verbose, complex, and hard to read. Functional style may be hard at first, mainly because most programmers are less familiar with it. In general, it's easier to read, understand, and change. With practice, it becomes easier to write as well. + +In this tutorial series we will take a look at a number of common imperative style code and find a mapping or an equivalent functional style code that we can use instead. As you work with your code based, when you're ready to fix a bug or make an enhancement, you may find it useful to refactor some of the imperative style code to the functional style. You can use this tutorial as a guide to find the imperative to functional style mappings for some common situations. + +In this tutorial we'll focus on simple loops. + +  +## Simple for Loops + +Let's start with the traditional for loop where we perform an action for values of an index over a range. + +```java +for(int i = 0; i < 5; i++) { + System.out.println(i); +} +``` + +In the above code, the essence is the range, from `0` to one less than `5`. The ceremony, the noise, from the __how__, is the syntax plus the increment operation on the index variable `i`. We can keep the essence and remove the ceremony by turning the code to the functional style. + +If you like to use the functional style to write this `for` loop, you can do quite easily and the clue is in the sentence before the code: __index over a range__. Since we're iterating over a range, the `range` method of `IntStream` is the direct equivalent for this. + +```java +import java.util.stream.IntStream; + +... +IntStream.range(0, 5) + .forEach(i -> System.out.println(i)); +``` + +You can further make this concise by using a methor reference for the `println` method. + +```java +import java.util.stream.IntStream; + +... +IntStream.range(0, 5) + .forEach(System.out::println); +``` + +The functional style code is more concise, easier to read, and the intention is clearer in this version than in the imperative version. + +What if your `for` loop runs to include the ending value, like in the following code, you may wonder. + +```java +for(int i = 0; i <= 5; i++) { + System.out.println(i); +} +``` + +The `IntStream` interface has you covered, it has a `rangeClosed` method exactly for this purpose. + +```java +import java.util.stream.IntStream; + +... +IntStream.rangeClosed(0, 5) + .forEach(System.out::println); +``` + +The `rangeClosed` method is useful to iterate from the starting value all the way to include the ending value. + +Whether you use the `range` method or the `rangeClosed` method, you get a stream of `int` values over which you can use the internal iterator to perform actions. Later in this series we will look at operations beyond `forEach`. + +In the previous code examples, the internal iterator removed the burden of iterating from your shoulders. The stream takes care of stepping over the range of values, one at a time. You only have to focus on what to do for each element, as they're provided to you, in the `forEach` method. In our examples, we merely printed the provided value. You can do just about any operation you like, like saving the information to a database, sending it off to a remote service, etc. + +Unlike the external iterator provided by the `for` loop, the code that uses the internal iterator is more concise, has less noise, avoids the need to explicitly mutate the index variable, is easier to read, easier to modify, and more pleasant to work with. + +Proceed to look for opportunities in your own code base where you see the traditional `for` loop and modify it to using the `IntStream`'s `range` or `rangeClosed` method. Make sure you verify that the code works as expected after the change, preferably by running automated tests that you may already have. + +  +## Mappings + +Anywhere you see a simple `for` loop, you can use either the `range` or the `rangeClosed` method of `IntStream`. Use the `range` method if you want to iterate until but not including the ending value. Use the `rangeClosed` to include the ending value as well in your iteration. + diff --git a/app/templates/pages/learn/tutorial-group-top.html b/app/templates/pages/learn/tutorial-group-top.html index 60b6136..b8e9faf 100644 --- a/app/templates/pages/learn/tutorial-group-top.html +++ b/app/templates/pages/learn/tutorial-group-top.html @@ -19,6 +19,10 @@

{{ file.fm.title_html | safe }}

+ {% if file.fm.author %} + {% include "app/templates/partials/_author.html" %} + {% endif %} +

{{ contents | safe }}


diff --git a/app/templates/pages/learn/tutorial-group.html b/app/templates/pages/learn/tutorial-group.html index 8572267..1cddb57 100644 --- a/app/templates/pages/learn/tutorial-group.html +++ b/app/templates/pages/learn/tutorial-group.html @@ -35,6 +35,10 @@

{{ file.fm.title_html | safe }}

+ {% if file.fm.author %} + {% include "app/templates/partials/_author.html" %} + {% endif %} +
diff --git a/app/templates/pages/learn/tutorial.html b/app/templates/pages/learn/tutorial.html index 06943e1..38f3dcf 100644 --- a/app/templates/pages/learn/tutorial.html +++ b/app/templates/pages/learn/tutorial.html @@ -19,8 +19,7 @@

{{ file.fm.title_html | safe }}

{% if file.fm.author %} - This page was contributed by {{ file.data.authorsMap[file.fm.author].name }} under the UPL -
+ {% include "app/templates/partials/_author.html" %} {% endif %}
diff --git a/app/templates/partials/_author.html b/app/templates/partials/_author.html new file mode 100644 index 0000000..c47ad98 --- /dev/null +++ b/app/templates/partials/_author.html @@ -0,0 +1,2 @@ +This page was contributed by {{ file.data.authorsMap[file.fm.author].name }} under the UPL +
\ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js index d399ea6..9201bf8 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -284,7 +284,7 @@ function pages() { .pipe(data(function (file) { if (file.fm.toc) { - const section_name_regex = /^[\s|\w|/|,]+[^{|^\s{]+/; + const section_name_regex = /^[\s\w.,|]+[^{|^\s{]+/; const anchor_regex = /{([^{|^}]+)}/; file.fm.toc = file.fm.toc .map(entry => ({