What advancements did we have in the field in last 10 years?

Learning from others in front-end development

Artūras Šlajus

2022

Lets take a look around

Games are user-facing products, known as front-end software.

There are also other front-end products:

  • Websites
  • Mobile applications
  • Desktop applications

Can we learn anything from them?

Evolution of front-end development

Websites

  • JQuery (released 2006) - imperative
  • Angular 1 (2010) - imperative
  • Angular 2 (2016) / React (2013) / Vue (2014) - imperative + functional

Mobile applications

  • Android
    • XML layouts (2008, imperative) →
      JetPack Compose (2021, functional)
  • iOS
    • UIKit (2013, imperative) → SwiftUI (2019, functional)
  • React Native (2015) / Flutter (2017): functional by default

Evolution of front-end development

The pattern is that all of the front-end development technologies that started with imperative programming have moved to declarative / functional programming.

There is a good reason for that.

Imperative programming is hard to get right.

What is a programming paradigm?

It is a way we express the steps our program takes to achieve the desired result.

There are multiple ways to do that.

  • Imperative programming is about:
    • having some data;
    • having some statements that change that data.
  • Functional programming is about:
    • having some data;
    • having some expressions that transform that data.

What is a programming paradigm?

Lets look at a two examples.

We want to get the total age of all people in the room.

What is a programming paradigm?

Imperative instructions

static int totalAgeOfAllPeople(IEnumerable<Person> people) {
  var totalAge = 0;
  foreach (var person in people) {
    totalAge += person.age;
  }
  return totalAge;
}

Functional instructions

static int totalAgeOfAllPeople(IEnumerable<Person> people) =>
  people.Select(person => person.age).Sum();

What is a programming paradigm?

Lets look at another example.

We want to make a cake by taking butter, flour, eggs, sugar and baking powder, mixing them in a bowl, then putting it to an oven for 15 minutes at 200°C.

What is a programming paradigm?

Imperative instructions

Bowl bowl = new Bowl();
bowl.add(new Butter());
bowl.add(new Flour());
bowl.add(new Eggs());
bowl.add(new Sugar());
bowl.add(new BakingPowder());
bowl.mix();

Oven oven = new Oven();
oven.put(bowl);
oven.setTemperature(200);
oven.bakeFor(TimeSpan.Minutes(15));

Cake cake = (Cake) bowl.takeOut();

What is a programming paradigm?

Functional instructions

MixedBowl bowl = 
  new Bowl(ingredients: NonEmpty.array(
    new Butter(), new Flour(), new Eggs(), 
    new Sugar(), new BakingPowder()
  ))
  .mix();

Cake cake = Oven.bake(
  bowl, bakeFor: TimeSpan.Minutes(15), temperature: 200
);

Let's compare!

Imperative

Functional

  • Primary goal is mutation.
  • Which is achieved with statements.
  • Code is about how to do.
  • Primary goal is transformation.
  • Which is achieved with expressions.
  • Code is about what to do.

Where does functional programming shine?

Composability

Functions are great - they always always compose.

You can always take Func<A, B> and Func<B, C> and compose them into Func<A, C>.

(Bowl => MixedBowl) + (MixedBowl => Cake)

=

(Bowl => Cake)

No more runtime exceptions

Immutable data structures allow us to make invalid states irrepresentable, thus eliminating runtime exceptions.

 

For example: non-empty collections and taking a random element.

Local reasoning

Easy to reason about - the function does not care about the origins of values it is getting.

Thus there is less need to know the rest of the system when refactoring.

Tests are easy

Everything is just a pure function, with no need for mocks or brittle techniques to change the internal state of objects.

No more dirty checking in UI

Immutable data structures make change propagation very efficient.

If the reference matches - it's the same thing!

Nothing is perfect

  • The performance is worse in a small scale compared to imperative code.

    Thus if you need maximum performance, you must use imperative (although you can still apply functional techniques there!).
     
  • Needs learning. But that is why you are here, right? 😉

Let's compare (pt. 2)!

Imperative

Functional

  • Primary goal is mutation.
  • Which is achieved with statements.
  • Code is about how to do.
  • Composition is about data.
  • Usually less pressure on garbage collector.
  • Maximal local performance.
  • Large scale software becomes hard to comprehend.
  • Primary goal is transformation.
  • Which is achieved with expressions.
  • Code is about what to do.
  • Composition is about functions.
  • Can put pressure on garbage collector (if done wrong).
  • Not maximal local performance.
  • Large scale software is still
    easy to comprehend.

Suggested architecture

  • Imperative paradigm in the small scale.
    • Gameplay code.
    • Maximum performance.
    • Fairly isolated, easy to understand.
  • Functional paradigm in the large scale.
    • Application architecture / User Interface code
    • No need for maximum performance.
    • Usually interconnected and complex, large need for clarity.

 

  • Perfect for writing and maintaining large-scale long-term projects.

Next stop

  • To know how to use functional programming in our games we first have to learn the basic building blocks of the functional paradigm.

See you in the next video!

U2. Learning from others in front-end development

By Artūras Šlajus

U2. Learning from others in front-end development

Exploring what other camps of front-end development have been up to and what options does that give to us.

  • 406