Browse Source

Update 'functional_go.md'

master
Loki Verloren 5 months ago
parent
commit
b1c0ddc09d
1 changed files with 13 additions and 3 deletions
  1. 13
    3
      functional_go.md

+ 13
- 3
functional_go.md View File

@@ -1,6 +1,16 @@
1 1
 # Functional Programming in Go
2 2
 1. Never use pointers. Don't assume passing around slices and maps is slower than micro-managing the memory allocation. This might be a logical consequence of the maxim to defer optimisation, but specifically in Go, the language wants you to deal in values and not share them.
3
-  If it can be done faster with pointers, better to first get the robust structure and individual elements.
3
+  
4
+  If it can be done faster with pointers, better to first get the robust structure and individual elements. Also consider the idea of intentionally bloating the heap with unused (allocated but not mapped) memory, which can improve the Go GC efficiency as it won't consider the memory dirty enough to clean up until the ballast size of memory is consumed.
5
+  
4 6
 2. Learn to love the assignment operator, especially `:=`. There is many caveats to being able to declare a variable in *every* block scope, so here's some simple rules:
5
-    a. Use a different short variable name for each descent into inner scope. Don't let it happen that the same symbol is used in adjacent scopes.
6
-    b. If you only use value methods, you logically will be returning copies of the receiver as modified. This is necessary because we are dealing in generic structures (maps and slices) and has a happy consequence that you can define a single container type using maps and while each function may have a different view, this captures the mutations in mutated maps, which only rearrange the pointers relative to the index.
7
+    1. Use a different short variable name for each descent into inner scope. Don't let it happen that the same symbol is used in adjacent scopes.
8
+    2. If you only use value methods, you logically will be returning copies of the receiver as modified. This is necessary because we are dealing in generic structures (maps and slices) and has a happy consequence that you can define a single container type using maps and while each function may have a different view, this captures the mutations in mutated maps, which only rearrange the pointers relative to the index.
9
+
10
+3. **Structs are only for cache locality properties**. In Go, slices and maps are two types of allocation mapping scheme. Slices are ordered sequences of pointers to variables, and maps are a key->index `struct{ Key: KeyType{}, Value: ValueType{} }` slice for one direction. Map positions are not deterministic because it can happen they are allocated to different relative positions in terms of their absolute memory addresses, which is how they are sorted. Possibly they are further optimised in the implementation by using two tables, one is `key-><address hash>` and the other is `<address hash>-><*ValueType>`.
11
+
12
+  In other words, only use structs when `map[string]interface{}` imposes a memory retrieval burden that becomes a bottleneck in addition to the address resolution in type switch/assertions.
13
+  
14
+4. **What remains for synchronisation?**. By using strictly generic built-in data structures and pass by value, one eliminates the problem of change of write collisions and state changes immediately after the value has been copied to work on it.
15
+  
16
+  The solution would be in creating publish/subscribe broker/client 

Loading…
Cancel
Save