Delay homework questions

Functional Programming + React

Some people seem to be having trouble with programming in a functional style, so I’m going to review some of those key ideas both in general and specicifcally for React.

Functional Programming: Key Idea (at least for us)

Constraints in programming;

function foo() {
  let xs = [1,2,3,4];
  bar();
  // xs is still [1,2,3,4] - it's a local variable, so bar
  // can't mess with it.
  
  // In assemby this wouldn't be true.
  // Also not true in Emacs LISP.

Constraints in functional programming:

// we start with a global variable
var numbers = [1,3,2,4];

// procedural style
function append_sort_and_print(int vv) {
    numbers.push(vv); // side effect: mutate global
    numbers.sort(); // side effect: mutate global
    console.log(numbers); // side effect: I/O
}

// functional style

// pure function does the computation
function append_and_sort(xs, vv) {
    let ys = xs.concat([vv]); // xs is unchanged
    ys.sort(); // side effect: mutate local variable
               // This is not externally visible, so function is still pure.
    return ys;
}

// side effects are isolated so we can keep an eye on them
function append_sort_and_print(int vv) {
    let ys = append_and_sort(numbers, vv);
    
    // We still need to actually do the task,
    // but we've isolated the side effects from the computation.
    numbers = ys;
    console.log(numbers);
}

With a functional language like Elixir, we go a step further: completely eliminating object mutation. This prevents us from writing side effects by mistake by mutating shared references.

Functional Programming and React

React is a display framework - currently getting overhyped, but still a good tool - that’s based on an idea from Academia called “Functional Reactive Programming”.

The research question was: How do we render graphics while constraining side effects? Initally, this was mostly a game engine thing.

The solution:

“But the DOM API is imperative, and we don’t want to change it every frame like a game engine, so this makes no sense.”

More recently some other solutions are similar performance to React, but the initial speed boost was enough to convince people to try an FRP style solution, and FRP turns out to be pretty nice in this application.

What that means:

Homework questions?

Hangman with Server-side State

game.html.eex:

<script>
 window.gameName = "<%= @name %>";
</script>

<div class="row">
  <div class="column">
    <h1>Hangman Game: <%= @name %></h1>
    <div id="root">
      <p>React app not loaded...</p>
    </div>
  </div>
</div>

app.js:

import socket from "./socket";
import game_init from "./hangman";

function start() {
  let root = document.getElementById('root');
  if (root) {
    let channel = socket.channel("games:" + window.gameName, {});
    // We want to join in the react component.
    game_init(root, channel);
  }
}

$(start);

Write attached code:

games_channel.ex:

  alias Hangman.Game

  def join("games:" <> name, payload, socket) do
    if authorized?(payload) do
      game = Game.new()
      socket = socket
      |> assign(:game, game)
      |> assign(:name, name)
      {:ok, %{"join" => name, "game" => Game.client_view(game)}, socket}
    else
      {:error, %{reason: "unauthorized"}}
    end
  end

  def handle_in("guess", %{"letter" => ll}, socket) do
    game = Game.guess(socket.assigns[:game], ll)
    socket = assign(socket, :game, game)
    {:reply, {:ok, %{ "game" => Game.client_view(game)}}, socket}
  end

Then update the JSX code: