C#, Functional Programming & Unity3D

 

Artūras Šlajus

arturas@tinylabproductions.com

What this talk is about

  • Not deeply technical
    • Functional programming is something that you need to wrap your head around

How did we get here

  • Imperative OOP programmer from 2002 to 2012 
  • Discovered FP in 2012
  • Been doing a mix of imperative + functional for games from 2015

Why does it matter

  • More correct, robust software
    • Reliance on compiler to point out errors for us
  • Long update cycles
    • Building 60 games - about 12 hours
    • Publishing 60 games - about an hour
    • Waiting for users to update - about a week
  • Medium sized team
    • Lots of change can mean lots of breakage

Core ideas

Honest Functions

public static int parseInt(string str);

public Player findPlayerIn(int x, int y);

Honest Functions

public void updateState(
  Vector3 movement, 
  bool animating, string animationType
);

Honest Functions

public class Player : MonoBehaviour {
  public void init(FooManager fooManager) {
    ...
  }
}

Honest Functions

public class Player : MonoBehaviour {
  public class Init {
    public Init(FooManager fooManager) {
      ...
    }    
  }
}

Things you are using but really should not

null

// Not honest
public Player findPlayer(int x, int y);

// Honest
public Option<Player> findPlayer(int x, int y);

We haven't seen an NPE in ages.

Exceptions

// Not honest
public static int parseInt(string str);

// Somewhat honest
public static bool tryParseInt(
  string str, out int parsed
);

// Honest
public static Either<string, int> parseInt(
  string str
);

Things that are really useful

Future/Task

Represents a value that may be available in the future.

 

 

TLPLib - Future, no threading support

C# stdlib - Task, with threading, heavy

Reactive Extensions (RX)

Represents a value stream.

Think of LINQ for events

 

 

TLPLib - integrated with library, no threading support

Unirx - standalone, more C#ish, threading support, heavier

Build validations

[SerializeField, NotNull] 
GameObject bulletPrefab;

[SerializeField, NonEmpty] 
List<GameObject> enemyPrefabs;

Available in TLPLib

What do you need

C# 6 or 7

  • Let me google that for you
    • unity c# 6
  • https://bitbucket.org/alexzzzz/unity-c-5.0-and-6.0-integration/src
  • Using C# 6 for 1.5 years, no problems whatsoever
  • Makes development so much more bearable.

TLPLib

  • Optional. You can always use other libraries - roll out your own.
  • https://github.com/tinylabproductions/tlplib
  • Production ready.

FP in C# book

  • Highly recommended
  • Explains the ideas in more detail
  • https://www.manning.com/books/functional-programming-in-c-sharp

Summary

  • Please don't lie in your functions
  • Applying FP results in more robust, correct and easier to understand code.
  • Use the right tool for the job - neither imperative nor FP is the ultimate paradigm.
  • If you take away 1 thing from this talk: let it be the banishment of nulls and usage of Option type.
  • FP is a journey. You'll need to take a step back to go forwards.

Thank you

https://slides.com/arturasslajus/c-sharp-fp-unity3d

Artūras Šlajus

arturas@tinylabproductions.com

Made with Slides.com