functional programming concepts › functional-gdscript.pdf · what is functional programming?...
TRANSCRIPT
![Page 1: Functional programming concepts › functional-gdscript.pdf · What is functional programming? “Everything is a function” Declarative instead of imperative Application of mathematical](https://reader034.vdocument.in/reader034/viewer/2022052408/5f1245523ab84353c64c286c/html5/thumbnails/1.jpg)
Functional programming concepts
And applications on GDScript
![Page 2: Functional programming concepts › functional-gdscript.pdf · What is functional programming? “Everything is a function” Declarative instead of imperative Application of mathematical](https://reader034.vdocument.in/reader034/viewer/2022052408/5f1245523ab84353c64c286c/html5/thumbnails/2.jpg)
George Marques
● Godot contributor since 2015● Member of the project’s leadership since 2017● Worked at Javary Games and IMVU (using Godot)
– Hired by Godot since November 2019● Co-author of the book “Godot Engine Game Development in 24
Hours”, published by Pearson● Responsible for the UWP port and typed GDScript
![Page 3: Functional programming concepts › functional-gdscript.pdf · What is functional programming? “Everything is a function” Declarative instead of imperative Application of mathematical](https://reader034.vdocument.in/reader034/viewer/2022052408/5f1245523ab84353c64c286c/html5/thumbnails/3.jpg)
Topics
● Introduction to functional programming● Monad● Functional programming characteristics● Functions● Applications (in general and on GDScript)● Other resources
![Page 4: Functional programming concepts › functional-gdscript.pdf · What is functional programming? “Everything is a function” Declarative instead of imperative Application of mathematical](https://reader034.vdocument.in/reader034/viewer/2022052408/5f1245523ab84353c64c286c/html5/thumbnails/4.jpg)
What is functional programming?
● “Everything is a function”● Declarative instead of imperative● Application of mathematical concepts● Avoids changing external state (pure functions)● Functions are also values (higher-order functions)
![Page 5: Functional programming concepts › functional-gdscript.pdf · What is functional programming? “Everything is a function” Declarative instead of imperative Application of mathematical](https://reader034.vdocument.in/reader034/viewer/2022052408/5f1245523ab84353c64c286c/html5/thumbnails/5.jpg)
Let’s talk about monad?
“A monad is a monoid in an endofunctor category”
- Rúnar Bjarnason
![Page 6: Functional programming concepts › functional-gdscript.pdf · What is functional programming? “Everything is a function” Declarative instead of imperative Application of mathematical](https://reader034.vdocument.in/reader034/viewer/2022052408/5f1245523ab84353c64c286c/html5/thumbnails/6.jpg)
Okay, let’s not talk about monad
Or will we?
![Page 7: Functional programming concepts › functional-gdscript.pdf · What is functional programming? “Everything is a function” Declarative instead of imperative Application of mathematical](https://reader034.vdocument.in/reader034/viewer/2022052408/5f1245523ab84353c64c286c/html5/thumbnails/7.jpg)
Disadvantages
● Declarative code is not always the most readable● It’s hard to combine pure functions and intended side-effects● Immutability and recursion can lead to performance penalties
– The functional paradigm avoids loops in favor of recursion
![Page 8: Functional programming concepts › functional-gdscript.pdf · What is functional programming? “Everything is a function” Declarative instead of imperative Application of mathematical](https://reader034.vdocument.in/reader034/viewer/2022052408/5f1245523ab84353c64c286c/html5/thumbnails/8.jpg)
Vantages
● Implementation of pure functions are easier to understand– Looking at a function signature may be enough to know what it does
● Easier to run things in parallel (no need for locks)● Testing functions in isolation is more straightforward
– Also easier to debug
![Page 9: Functional programming concepts › functional-gdscript.pdf · What is functional programming? “Everything is a function” Declarative instead of imperative Application of mathematical](https://reader034.vdocument.in/reader034/viewer/2022052408/5f1245523ab84353c64c286c/html5/thumbnails/9.jpg)
Side effects
● By definition: changes in objects outside the function scope● Change of global state● Input and output
– Yes, this includes keyboard input and video output● Changes in the object that contains the function (instance members)
![Page 10: Functional programming concepts › functional-gdscript.pdf · What is functional programming? “Everything is a function” Declarative instead of imperative Application of mathematical](https://reader034.vdocument.in/reader034/viewer/2022052408/5f1245523ab84353c64c286c/html5/thumbnails/10.jpg)
Immutability
● Variables are treated as constants– Forbidden to re-assign a value to a variable– Forbidden to change properties of an object
● (Okay to change a local object for the sake of initialization)
● Instead of changes, make copies– func nope(obj_to_change: Object) -> void– func yep(obj_to_update: Object) -> Object
![Page 11: Functional programming concepts › functional-gdscript.pdf · What is functional programming? “Everything is a function” Declarative instead of imperative Application of mathematical](https://reader034.vdocument.in/reader034/viewer/2022052408/5f1245523ab84353c64c286c/html5/thumbnails/11.jpg)
Pure function
● Don’t have side effects● All parameters are immutable● A call with the same arguments return the same value every time● Similar to the mathematical definition
![Page 12: Functional programming concepts › functional-gdscript.pdf · What is functional programming? “Everything is a function” Declarative instead of imperative Application of mathematical](https://reader034.vdocument.in/reader034/viewer/2022052408/5f1245523ab84353c64c286c/html5/thumbnails/12.jpg)
First-class functions
● Function is also a value– It can be assigned to a variable– It can be passed as arguments to other functions– It can be the return value of a function
● Everything that can be done with a value can also be done with a function– Including putting them in arrays and dictionaries
![Page 13: Functional programming concepts › functional-gdscript.pdf · What is functional programming? “Everything is a function” Declarative instead of imperative Application of mathematical](https://reader034.vdocument.in/reader034/viewer/2022052408/5f1245523ab84353c64c286c/html5/thumbnails/13.jpg)
First-class functions in GDScript
● Well, we’re not there yet, but will soon™
![Page 14: Functional programming concepts › functional-gdscript.pdf · What is functional programming? “Everything is a function” Declarative instead of imperative Application of mathematical](https://reader034.vdocument.in/reader034/viewer/2022052408/5f1245523ab84353c64c286c/html5/thumbnails/14.jpg)
FuncRef to the rescue
● Exclusive Godot type that allows a function reference● Then you can treat the reference as a value
– And call it later (with arguments)● Making it in GDScript:
var my_func = funcref(self, "my_method")
● Calling:
my_func.call_func("An argument")
![Page 15: Functional programming concepts › functional-gdscript.pdf · What is functional programming? “Everything is a function” Declarative instead of imperative Application of mathematical](https://reader034.vdocument.in/reader034/viewer/2022052408/5f1245523ab84353c64c286c/html5/thumbnails/15.jpg)
Higher-order functions
● Functions are “first-order” by default● They’re higher-order if they receive a function as an argument● Or return a function as a result● It’s not mandatory that they are pure
– But we like them more if they are
![Page 16: Functional programming concepts › functional-gdscript.pdf · What is functional programming? “Everything is a function” Declarative instead of imperative Application of mathematical](https://reader034.vdocument.in/reader034/viewer/2022052408/5f1245523ab84353c64c286c/html5/thumbnails/16.jpg)
Higher-order functions
● Examples– map– filter– reduce
Still not available in GDScript for now, but not hard to implement in script
![Page 17: Functional programming concepts › functional-gdscript.pdf · What is functional programming? “Everything is a function” Declarative instead of imperative Application of mathematical](https://reader034.vdocument.in/reader034/viewer/2022052408/5f1245523ab84353c64c286c/html5/thumbnails/17.jpg)
Map
● Take an array and a unary function, returns a copy of the array with the function applied to every element
● Signature: func map(input: Array, function: FuncRef) -> Array● Equivalent to:
var my_arr -= [1, 2, 3]
var mapped -= []
for element in my_arr:
mapped.append(some_func(element))
![Page 18: Functional programming concepts › functional-gdscript.pdf · What is functional programming? “Everything is a function” Declarative instead of imperative Application of mathematical](https://reader034.vdocument.in/reader034/viewer/2022052408/5f1245523ab84353c64c286c/html5/thumbnails/18.jpg)
Map
● Example 1func half(num: int) -> int:
return num / 2
func half_array(numbers: Array) -> Array:
return map(numbers, funcref(self, "half"))
func _ready() -> void:
var numbers -= [2, 4, 6]
var halves -= half_array(numbers) # [1, 2, 3]
![Page 19: Functional programming concepts › functional-gdscript.pdf · What is functional programming? “Everything is a function” Declarative instead of imperative Application of mathematical](https://reader034.vdocument.in/reader034/viewer/2022052408/5f1245523ab84353c64c286c/html5/thumbnails/19.jpg)
Map
● Example 2func get_id(user: User) -> int:
return user.id
func list_user_ids() -> Array:
var users: Array = fetch_users()
return map(users, funcref(self, "get_id"))
![Page 20: Functional programming concepts › functional-gdscript.pdf · What is functional programming? “Everything is a function” Declarative instead of imperative Application of mathematical](https://reader034.vdocument.in/reader034/viewer/2022052408/5f1245523ab84353c64c286c/html5/thumbnails/20.jpg)
Map
● Possible implementationfunc map(input: Array, function: FuncRef) -> Array:
var result -= []
result.resize(input.size())
for i in range(input.size()):
result[i] = function.call_func(input[i])
![Page 21: Functional programming concepts › functional-gdscript.pdf · What is functional programming? “Everything is a function” Declarative instead of imperative Application of mathematical](https://reader034.vdocument.in/reader034/viewer/2022052408/5f1245523ab84353c64c286c/html5/thumbnails/21.jpg)
Filter
● Takes an array and a unary function, returns a new array with only the elements to which the function returns true
● Signature: func filter(input: Array, function: FuncRef) -> Array● Equivalent to:
var my_arr -= [1, 2, 3]
var filtered -= []
for element in my_arr:
if some_func(element):
filtered.append(element)
![Page 22: Functional programming concepts › functional-gdscript.pdf · What is functional programming? “Everything is a function” Declarative instead of imperative Application of mathematical](https://reader034.vdocument.in/reader034/viewer/2022052408/5f1245523ab84353c64c286c/html5/thumbnails/22.jpg)
Filter
● Example 1func is_even(num: int) -> bool:
return num % 2 -= 0
func get_evens(numbers: Array) -> Array:
return filter(numbers, funcref(self, "is_even"))
func _ready() -> void:
var numbers -= [1, 2, 3, 4]
var evens -= get_evens(numbers) # [2, 4]
![Page 23: Functional programming concepts › functional-gdscript.pdf · What is functional programming? “Everything is a function” Declarative instead of imperative Application of mathematical](https://reader034.vdocument.in/reader034/viewer/2022052408/5f1245523ab84353c64c286c/html5/thumbnails/23.jpg)
Filter
● Example 2func is_active(user: User) -> bool:
return user.active
func list_active_users() -> Array
var users: Array = fetch_users()
return filter(users, funcref(self, "is_active"))
![Page 24: Functional programming concepts › functional-gdscript.pdf · What is functional programming? “Everything is a function” Declarative instead of imperative Application of mathematical](https://reader034.vdocument.in/reader034/viewer/2022052408/5f1245523ab84353c64c286c/html5/thumbnails/24.jpg)
Filter
● Possible implementationfunc filter(input: Array, function: FuncRef) -> Array:
var result -= []
for element in input:
if function.call_func(element):
result.append(element)
return result
![Page 25: Functional programming concepts › functional-gdscript.pdf · What is functional programming? “Everything is a function” Declarative instead of imperative Application of mathematical](https://reader034.vdocument.in/reader034/viewer/2022052408/5f1245523ab84353c64c286c/html5/thumbnails/25.jpg)
Reduce
● Takes an array, a binary function, and a value, returns a single value with the function applied to each element and the previous result
● Signature: func reduce(input: Array, function: FuncRef, base)● Equivalent to:
var my_arr -= [1, 2, 3]
var reduced = base
for element in my_arr:
reduced = some_func(reduced, element)
![Page 26: Functional programming concepts › functional-gdscript.pdf · What is functional programming? “Everything is a function” Declarative instead of imperative Application of mathematical](https://reader034.vdocument.in/reader034/viewer/2022052408/5f1245523ab84353c64c286c/html5/thumbnails/26.jpg)
Reduce
● Example 1func sum(num1: int, num2: int) -> int:
return num1 + num2
func array_sum(numbers: Array) -> int:
return reduce(numbers, funcref(self, "sum"), 0)
func _ready():
var numbers -= [1, 2, 3, 4]
var sum: int = array_sum(numbers) # 10
![Page 27: Functional programming concepts › functional-gdscript.pdf · What is functional programming? “Everything is a function” Declarative instead of imperative Application of mathematical](https://reader034.vdocument.in/reader034/viewer/2022052408/5f1245523ab84353c64c286c/html5/thumbnails/27.jpg)
Reduce
● Example 2func larger(num1: int, num2: int) -> int:
return num1 if num1 > num2 else num2
func get_user_age(user: User) -> int:
return user.age
func get_highest_user_age() -> int:
var user_ages: Array = map(fetch_users(), \
funcref(self, "get_user_age"))
# Base value is omitted here
return reduce(user_ages, funcref(self, "larger"))
![Page 28: Functional programming concepts › functional-gdscript.pdf · What is functional programming? “Everything is a function” Declarative instead of imperative Application of mathematical](https://reader034.vdocument.in/reader034/viewer/2022052408/5f1245523ab84353c64c286c/html5/thumbnails/28.jpg)
Reduce
● Possible implementationfunc reduce(input: Array, function: FuncRef, base = null):
var accumulator = base
var index -= 0
if not base and input.size() > 0:
accumulator = input[0]
index = 1
while index < input.size():
accumulator = function.call_func(accumulator, input[index])
index += 1
return accumulator
![Page 29: Functional programming concepts › functional-gdscript.pdf · What is functional programming? “Everything is a function” Declarative instead of imperative Application of mathematical](https://reader034.vdocument.in/reader034/viewer/2022052408/5f1245523ab84353c64c286c/html5/thumbnails/29.jpg)
Lambda
● Function definition where a value (expression) is expected● Helps in cases where the function is simple or doesn’t need to be
reused in another context● Example:
var result -= map([2, 4, 6], x -> x / 2)
print(result) # [1, 2, 3]
![Page 30: Functional programming concepts › functional-gdscript.pdf · What is functional programming? “Everything is a function” Declarative instead of imperative Application of mathematical](https://reader034.vdocument.in/reader034/viewer/2022052408/5f1245523ab84353c64c286c/html5/thumbnails/30.jpg)
Lambdas in GDScript
● Well, we’re not there yet, but will soon™
Seriously!
![Page 31: Functional programming concepts › functional-gdscript.pdf · What is functional programming? “Everything is a function” Declarative instead of imperative Application of mathematical](https://reader034.vdocument.in/reader034/viewer/2022052408/5f1245523ab84353c64c286c/html5/thumbnails/31.jpg)
Let’s talk a bit about theory
I promise it’s only a bit
![Page 32: Functional programming concepts › functional-gdscript.pdf · What is functional programming? “Everything is a function” Declarative instead of imperative Application of mathematical](https://reader034.vdocument.in/reader034/viewer/2022052408/5f1245523ab84353c64c286c/html5/thumbnails/32.jpg)
Functor
● (No need to flee, it’s not that hard)● Functor is a type that can be mapped, that is, there’s a map function
applicable to the type● Yes, that’s it● As we say, Array is a functor because it has* a map function
– *Technically the function isn’t in the Array class, but it doesn’t matter conceptually.
![Page 33: Functional programming concepts › functional-gdscript.pdf · What is functional programming? “Everything is a function” Declarative instead of imperative Application of mathematical](https://reader034.vdocument.in/reader034/viewer/2022052408/5f1245523ab84353c64c286c/html5/thumbnails/33.jpg)
Monoid
● Monoid is a type that has a function with three properties:– Binary
● Has two parameters– Associative
● function(a, function(b, c)) -= function(function(a, b), c)
– Has a neutral (identity) element● function(a, identity) -= function(identity, a) -= a
● It doesn’t need to be commutative– (function(a, b) -= function(b, a))
![Page 34: Functional programming concepts › functional-gdscript.pdf · What is functional programming? “Everything is a function” Declarative instead of imperative Application of mathematical](https://reader034.vdocument.in/reader034/viewer/2022052408/5f1245523ab84353c64c286c/html5/thumbnails/34.jpg)
Monoid
● Example: integers with sum as the function– Binary: 3 + 4 (two arguments: “3” and “4”)– Associative: (1 + 2) + 3 = 1 + (2 + 3) = 6– Identity element: 2 + 0 = 0 + 2 = 2
![Page 35: Functional programming concepts › functional-gdscript.pdf · What is functional programming? “Everything is a function” Declarative instead of imperative Application of mathematical](https://reader034.vdocument.in/reader034/viewer/2022052408/5f1245523ab84353c64c286c/html5/thumbnails/35.jpg)
Monoid
● Array is also a monoid!● What’s the function that makes it a monoid? Concatenation:
– Binary: [1, 2] + [3, 4] -= [1,2,3,4]– Associative: ([1,2] + [3,4]) + [5,6] -= [1,2] + ([3,4] + [5,6]) -=
[1,2,3,4,5,6]
– Identity element: [] + [1,2] -= [1, 2] + [] -= [1, 2]
![Page 36: Functional programming concepts › functional-gdscript.pdf · What is functional programming? “Everything is a function” Declarative instead of imperative Application of mathematical](https://reader034.vdocument.in/reader034/viewer/2022052408/5f1245523ab84353c64c286c/html5/thumbnails/36.jpg)
Monad
● Yes, let’s talk about monad!● As said: “A monad is a monoid in an endofunctor category”● In other words: Monad is a monoid that is also an endofunctor● In the context of programming, every functor is an endofunctor● Which means...
![Page 37: Functional programming concepts › functional-gdscript.pdf · What is functional programming? “Everything is a function” Declarative instead of imperative Application of mathematical](https://reader034.vdocument.in/reader034/viewer/2022052408/5f1245523ab84353c64c286c/html5/thumbnails/37.jpg)
Array is monad!
● Yes, that’s it● It’s a functor (can be mapped)● It’s a monoid (regarding the concatenation function)● So it’s also a monad
![Page 38: Functional programming concepts › functional-gdscript.pdf · What is functional programming? “Everything is a function” Declarative instead of imperative Application of mathematical](https://reader034.vdocument.in/reader034/viewer/2022052408/5f1245523ab84353c64c286c/html5/thumbnails/38.jpg)
Promise
● Encapsulates asynchronous operations● Allows to maintain the chain of operations while we wait the
promise to be fulfilled– That is, the asynchronous operation complete– The promise can be treated as the value that it contains
● Suppress side effects
![Page 39: Functional programming concepts › functional-gdscript.pdf · What is functional programming? “Everything is a function” Declarative instead of imperative Application of mathematical](https://reader034.vdocument.in/reader034/viewer/2022052408/5f1245523ab84353c64c286c/html5/thumbnails/39.jpg)
Promise
● Example: HTTP request (promise implementation)class_name Promise
signal success(value) # probably want error and done signals too
var done: bool = false
func _success(value):
done = true
emit_signal("success", value)
![Page 40: Functional programming concepts › functional-gdscript.pdf · What is functional programming? “Everything is a function” Declarative instead of imperative Application of mathematical](https://reader034.vdocument.in/reader034/viewer/2022052408/5f1245523ab84353c64c286c/html5/thumbnails/40.jpg)
Promise
● Example: HTTP request (kitten request class)var promise: Promise = null
func kitten_request(width: int, height: int) -> Promise:
var http -= HTTPRequest.new(); add_child(http)
http.request("http:-/placekitten.com/%d/%d" % [width, height])
http.connect("request_completed", self, "_on_request_completed")
promise = Promise.new()
return promise
func _on_request_completed(result, response_code, headers, body):
var image -= Image.new()
image.load_jpg_from_buffer(body)
var texture -= ImageTexture.new()
texture.create_from_image(image)
promise._success(texture)
![Page 41: Functional programming concepts › functional-gdscript.pdf · What is functional programming? “Everything is a function” Declarative instead of imperative Application of mathematical](https://reader034.vdocument.in/reader034/viewer/2022052408/5f1245523ab84353c64c286c/html5/thumbnails/41.jpg)
Promise
● Example: HTTP request (using promises)func _ready():
var kitten_promise: Promise = kitten_request(800, 600)
kitten_promise.connect("on_success", self, "on_get_kitten")
func on_get_kitten(kitten: Texture):
$KittenSprite.texture = kitten
![Page 42: Functional programming concepts › functional-gdscript.pdf · What is functional programming? “Everything is a function” Declarative instead of imperative Application of mathematical](https://reader034.vdocument.in/reader034/viewer/2022052408/5f1245523ab84353c64c286c/html5/thumbnails/42.jpg)
Promise
![Page 43: Functional programming concepts › functional-gdscript.pdf · What is functional programming? “Everything is a function” Declarative instead of imperative Application of mathematical](https://reader034.vdocument.in/reader034/viewer/2022052408/5f1245523ab84353c64c286c/html5/thumbnails/43.jpg)
Promise in functional programming
● Promise is also a monad!● Monad can also be seen as encapsulation inside a context● In an Array, the context is the multiplicity of values● In Promise, the context is the “promise” of a future resolution● To put in the context is usually called “Lift”
![Page 44: Functional programming concepts › functional-gdscript.pdf · What is functional programming? “Everything is a function” Declarative instead of imperative Application of mathematical](https://reader034.vdocument.in/reader034/viewer/2022052408/5f1245523ab84353c64c286c/html5/thumbnails/44.jpg)
Promise as a functor
● The “mapping” in promise means applying the function to the final resolved value– Like the kitten picture
● It’s possible to define Promise.map() which applies the function only when it resolves (that is, when the async operation completes)
● Remember that map() returns the value inside the context, so Promise.map() also returns a Promise
● In turn, it’s possible to apply other pure operations to a Promise before it is fullfilled
![Page 45: Functional programming concepts › functional-gdscript.pdf · What is functional programming? “Everything is a function” Declarative instead of imperative Application of mathematical](https://reader034.vdocument.in/reader034/viewer/2022052408/5f1245523ab84353c64c286c/html5/thumbnails/45.jpg)
Promise map
● Examplevar users: Promise = request_users() # Promise of array of users
var active_users: Promise = users.map(funcref(self, "filter_active_users"))
active_users.connect("success", self, "print_users")
func filter_active_users(users: Array) -> Array:
return filter(users, funcref(self, "is_active"))
func print_users(users):
print(users)
![Page 46: Functional programming concepts › functional-gdscript.pdf · What is functional programming? “Everything is a function” Declarative instead of imperative Application of mathematical](https://reader034.vdocument.in/reader034/viewer/2022052408/5f1245523ab84353c64c286c/html5/thumbnails/46.jpg)
Monad as side effect isolation
● Like Promise encapsulates an asynchronous operation, Monads can also encapsulate side effect
● It’s possible to operate with the values inside the lifted context (i.e. inside the Promise) without depending on its effects
● Example: operating in a text input before the user types anything– The function needs only to get the text as argument, not wait for the side effect
● Keeping side effects and shared state only in a small and specific part of the code
![Page 47: Functional programming concepts › functional-gdscript.pdf · What is functional programming? “Everything is a function” Declarative instead of imperative Application of mathematical](https://reader034.vdocument.in/reader034/viewer/2022052408/5f1245523ab84353c64c286c/html5/thumbnails/47.jpg)
Learn a functional language
● At first it may be hard to assimilate the concepts● But the patterns can be applied in other languages and be used to
increase code quality● Examples of functional languages:
– Elm, Elixir, Haskell, Clojure, Scala, F#