How `type Name *Name` works? - go

I was looking at some examples on golang.org homepage and found Peano Integers. This example defines the type Number like this:
type Number *Number
First time looking at this code I thought it should not compile, I think I haven't understood how type works in Go.
Can you explain how Go is defining type Number here? This looks very confusing to me.
Go Playground
// Peano integers are represented by a linked
// list whose nodes contain no data
// (the nodes are the data).
// http://en.wikipedia.org/wiki/Peano_axioms
// This program demonstrates that Go's automatic
// stack management can handle heavily recursive
// computations.
package main
import "fmt"
// Number is a pointer to a Number
type Number *Number
// The arithmetic value of a Number is the
// count of the nodes comprising the list.
// (See the count function below.)
// -------------------------------------
// Peano primitives
func zero() *Number {
return nil
}
func isZero(x *Number) bool {
return x == nil
}
func add1(x *Number) *Number {
e := new(Number)
*e = x
return e
}
func sub1(x *Number) *Number {
return *x
}
func add(x, y *Number) *Number {
if isZero(y) {
return x
}
return add(add1(x), sub1(y))
}
func mul(x, y *Number) *Number {
if isZero(x) || isZero(y) {
return zero()
}
return add(mul(x, sub1(y)), x)
}
func fact(n *Number) *Number {
if isZero(n) {
return add1(zero())
}
return mul(fact(sub1(n)), n)
}
// -------------------------------------
// Helpers to generate/count Peano integers
func gen(n int) *Number {
if n > 0 {
return add1(gen(n - 1))
}
return zero()
}
func count(x *Number) int {
if isZero(x) {
return 0
}
return count(sub1(x)) + 1
}
// -------------------------------------
// Print i! for i in [0,9]
func main() {
for i := 0; i <= 9; i++ {
f := count(fact(gen(i)))
fmt.Println(i, "! =", f)
}
}

Related

how to get length of linked list in golang with recursive of method pointer?

I have a single linked list. how do I get the length of the linked list with a recursive method that had a pointer receiver?
type Node struct {
data int
next *Node
}
I had tried like this, but always return 1
func (n *Node) recursiveLength() (result int) {
if n != nil {
result += 1
n = n.next
}
return
}
Your solution is not recursive. It's have compilation error. But if we want to fix it it could be like this:
package main
import "fmt"
type Node struct {
data int
next *Node
}
func (n *Node) recursiveLength() (result int) {
if n != nil {
result += 1
n = n.next
return result + n.recursiveLength()
}
return 0
}
func main() {
x := Node{data: 0, next: &Node{data: 1, next: &Node{data: 2, next: nil}}}
fmt.Println(x.recursiveLength())
}
But this is not a good idea to write length method, It's better to change it to a function that accepts a Node and returns its length:
package main
import "fmt"
type Node struct {
data int
next *Node
}
func recursiveLength(n *Node) (result int) {
if n != nil {
n = n.next
return 1 + recursiveLength(n)
}
return 0
}
func main() {
x := Node{data: 0, next: &Node{data: 1, next: &Node{data: 2, next: nil}}}
fmt.Println(recursiveLength(&x))
}

Implement generic linked list in golang which disallows different types in the same linkedlist

I want to make a linked list which can hold the values of any type but the linked list must hold values of any one type only.
In general when I am using interfaces for achieving this - any type which implements the interface for the node can be added to the linked list.
I have written an implementation for this where whenever a new key is added to the linked list, the type of the key is checked against the type of the key at the head. I want to understand if this is the correct way of implementing it or is there a better way of doing it.
package main
import (
"errors"
"fmt"
"reflect"
"strings"
)
type MyNode struct {
value int
}
func (node *MyNode) PrintValue() {
fmt.Printf(" %d ", node.value)
}
type llNode struct {
key llNodeInterface
next *llNode
llNodeType reflect.Type
}
type llNodeInterface interface {
PrintValue()
}
type ComplexNode struct {
realValue int
imageValue int
}
func (node *ComplexNode) PrintValue() {
fmt.Printf(" %d + i%d", node.realValue, node.imageValue)
}
// Student type.
type Student struct {
name string
age int
}
// Student implements the PrintValue function - thus llNodeInterface is implemented.
func (node *Student) PrintValue() {
fmt.Printf("Name: %s | Age : %d ", node.name, node.age)
}
// Function which will check the of the new node before adding to the linked
// list. It checks the type of the new key against the type of the key in the
// head. If both are equal then it proceed else return error.
func (head *llNode) AddBeforeHeadTypeCheck(passedKey llNodeInterface) error {
if head.key == nil {
head.key = passedKey
head.llNodeType = reflect.TypeOf(head.key)
} else {
typeOfPassedKey := reflect.TypeOf(passedKey)
if typeOfPassedKey != head.llNodeType {
fmt.Printf("\nUnsupported type for the type %T", passedKey)
return errors.New("Type mistmatch")
}
temp := llNode{key: head.key, next: head.next}
head.key = passedKey
head.next = &temp
}
return nil
}
// Function which will not check the types and will simply add the new node to
// the linked list. Thus linked list will be able to have nodes of multiple
// types.
func (head *llNode) AddBeforeHead(passedKey llNodeInterface) {
if head.key == nil {
head.key = passedKey
head.llNodeType = reflect.TypeOf(head.key)
} else {
temp := llNode{key: head.key, next: head.next}
head.key = passedKey
head.next = &temp
}
}
func (head *llNode) Init() {
head.key = nil
head.next = nil
head.llNodeType = nil
}
// Print the linked list.
func (head *llNode) DisplayLL() {
temp := head
fmt.Printf("\n%s", strings.Repeat("#", 80))
fmt.Printf("\nPrinting the linked list\n")
for {
if temp.key == nil {
fmt.Println("Linked list is empty")
break
} else {
fmt.Printf("\n %T %v ", temp.key, temp.key)
key := temp.key
key.PrintValue()
if temp.next == nil {
break
} else {
temp = temp.next
}
}
}
fmt.Printf("\n%s", strings.Repeat("#", 80))
fmt.Printf("\n\n")
}
func testWithMixedType() {
head := llNode{}
head.Init()
for i := 1; i < 10; i++ {
temp := &ComplexNode{i, i * 10}
head.AddBeforeHeadTypeCheck(temp)
}
temps := &Student{"rishi", 20}
head.AddBeforeHeadTypeCheck(temps) // Will give error.
head.DisplayLL()
}
func testWithComplexNumber() {
head := llNode{}
head.Init()
for i := 1; i < 10; i++ {
temp := &ComplexNode{i, i * 10}
head.AddBeforeHeadTypeCheck(temp)
}
}
func main() {
testWithComplexNumber()
testWithMixedType()
}
The code is working fine - but I want to understand if there is a better or different way of doing this.
Also - what is the performance impact of the current checking of types using the reflect package. Is there a different way of achieving the same thing.
Unsupported type for the type *main.Student
Unsupported type for the type *main.Student
################################################################################
Printing the linked list
*main.ComplexNode &{9 90} 9 + i90
*main.ComplexNode &{8 80} 8 + i80
*main.ComplexNode &{7 70} 7 + i70
*main.ComplexNode &{6 60} 6 + i60
*main.ComplexNode &{5 50} 5 + i50
*main.ComplexNode &{4 40} 4 + i40
*main.ComplexNode &{3 30} 3 + i30
*main.ComplexNode &{2 20} 2 + i20
*main.ComplexNode &{1 10} 1 + i10
################################################################################
Good news, starting from Go 1.18, Generics are now supported in Go.
Following the example from the question, here is a simplified LinkedList using Generics. You can tinker with it at the playground here.
package main
import "fmt"
type MyNode[T any] struct {
next *MyNode[T]
value T
}
type MyLinkedList[T any] struct {
head *MyNode[T]
tail *MyNode[T]
}
func (list *MyLinkedList[T]) Add(t T) *MyLinkedList[T] {
// create node
node := &MyNode[T]{nil, t}
// if first node in list
if list.head == nil {
list.head = node
list.tail = node
} else {
list.tail.next = node
list.tail = list.tail.next
}
return list
}
func (list *MyLinkedList[T]) AddBeforeHead(t T) *MyLinkedList[T] {
node := &MyNode[T]{nil, t}
if list.head != nil {
node.next = list.head
list.head = node
} else {
// make head
list.head = node
list.tail = node
}
return list
}
// display the list
func DisplayList[T any](list *MyLinkedList[T]) string {
var out string = ""
iter := list.head
for iter != nil {
out += fmt.Sprintf("%v -> ", iter.value)
iter = iter.next
}
return out
}
func (list *MyLinkedList[T]) Display() string {
return DisplayList(list)
}
// for printing node value
// you could also implement Stringer
// but this is besides the point, you can ignore
func (node *MyNode[T]) String() string {
return fmt.Sprintf("<MyNode: %v>", node.value)
}
// helper func: create list from array
func CreateLinkedList[T any](arr []T) *MyLinkedList[T] {
list := &MyLinkedList[T]{}
for _, v := range arr {
list.Add(v)
}
return list
}
func main() {
// create a list from array of integers
intArr := []int{10, 20, 30, 40, 50, 60}
list1 := CreateLinkedList(intArr)
// create a list from array of strings
strArr := []string{"foo", "bar", "baz", "faz"}
list2 := CreateLinkedList(strArr)
// test inserting at the beginning
list2.AddBeforeHead("hello")
fmt.Println(list1.Display())
fmt.Println(list2.Display())
}
Some official references covering basics of Generics can be found here:
https://go.dev/doc/tutorial/generics
https://go.dev/blog/intro-generics
https://go.dev/tour/generics/1
You can do it either by using interfaces and runtime checks (as you've discovered), or by using code generation. These are the current options you have in Go for generic programming. The Go team is working to add generics to the language - it's a work in progress, and everyone is free to participate in the discussion. Once generics exist, they will provide the solution you seek here.
As for interfaces vs. code generation, there are the performance implications you've mentioned. Code generation will generate tighter code that doesn't need to do runtime checks for most operations; on the other hand, it adds a bit of complexity to the build process of your project. These are the usual tradeoffs of having something resolved at run-time vs. precomputing things at compile-time.

Making code more generic

I have a program where many functionalities are similar across different structures, however, I end up writing these functions again and again, esp because the variable that are being dealt inside are of different structures.
I have written a sample code here.
In Go Playgroud
package main
import "fmt"
func (a *Match) Add(v Match) {
a.Runs += v.Runs
a.Points += v.Points
}
type Match struct {
Runs uint64
Points uint64
}
func (a *Activity) Add(v Activity) {
a.Walk += v.Walk
a.Jog += v.Jog
}
type Activity struct {
Walk uint64
Jog uint64
}
func GetDailyMatches() map[string]Match {
var dailyMatches map[string]Match
Match1, Match2 := Match{5, 10}, Match{1, 2}
dailyMatches = make(map[string]Match)
dailyMatches["01"] = Match1
dailyMatches["02"] = Match2
dailyMatches["03"] = Match1
dailyMatches["04"] = Match2
return dailyMatches
}
func GetDailyActivities() map[string]Activity {
var dailyActivities map[string]Activity
Activity1, Activity2 := Activity{5, 10}, Activity{1, 2}
dailyActivities = make(map[string]Activity)
dailyActivities["01"] = Activity1
dailyActivities["02"] = Activity2
dailyActivities["03"] = Activity1
dailyActivities["04"] = Activity2
return dailyActivities
}
func main() {
fmt.Println(CalculateMatchSummary("01", "03"))
fmt.Println(CalculateActivitySummary("02", "04"))
fmt.Println(CalculateMatchSummary("01", "03"))
fmt.Println(CalculateActivitySummary("02", "04"))
}
func CalculateMatchSummary(start, end string) (total Match) {
dailyMatches := GetDailyMatches()
for day, value := range dailyMatches {
if day < start {
continue
} else if day > end {
continue
} else {
total.Add(value)
}
}
return
}
func CalculateActivitySummary(start, end string) (total Activity) {
dailyActivities := GetDailyActivities()
for day, value := range dailyActivities {
if day < start {
continue
} else if day > end {
continue
} else {
total.Add(value)
}
}
return
}
If you notice, both Match and Activity has the same functions and same structures, except that internally they are of different structures.
Is there a easy way to make the code more generic (Go generics, which is not there in Go??) in Golang itself.
Go has a pretty package "reflect". You can not do genericity strictly speaking but you can get unification of code for the same behavior.
I've changed your playground a bit : https://play.golang.org/p/bfqZsFOgVQ
The main part :
func AddTwo(a, b interface{}) interface{} {
va := reflect.ValueOf(a)
vb := reflect.ValueOf(b)
res := reflect.New(reflect.TypeOf(a)).Elem()
if va.Kind() != reflect.Struct && vb.Kind() != reflect.Struct {
return nil
}
na, nb := va.NumField(), vb.NumField()
if na != nb {
return nil
}
for i := 0; i < na; i++ {
// additional verification needed here
fa := va.Field(i).Uint()
fb := vb.Field(i).Uint()
fr := fa + fb
res.Field(i).SetUint(fr)
}
return res.Interface()
}
I use reflect to check the fields of the struct I am given. If both are uint64, I can add them reflectively. If your structs contains many uint64, it can add them all !
Note that you must convert the resulting interface to the type of the struct given after calling this function. That is why this is not strictly generic, because the returning type is a interface, and not a Match or Activity.
EDIT: No need even to return a new struct. You can simply update the field of the "a" struct by calling .SetUint() method.

Golang function and function variable semantics

Why can't I define a recursive function as a variable? I seem to be able to define arbitrary functions except when they recurse.
This is legal:
func f(i int) int {
if i == 0 {
return 1
}
return i * f(i-1)
}
func main() {
fmt.Println(f(2))
}
This is illegal:
var f func(int) int = func(i int) int {
if i == 0 {
return 1
}
return i * f(i-1)
}
func main() {
fmt.Println(f(2))
}
This is legal and I'm guessing it is just because you can figure out f after initialization:
func main() {
var f *func(int) int;
t := func(i int) int {
if i == 0 {
return 1
}
return i * (*f)(i-1)
}
f = &t
fmt.Println((*f)(2))
}
So it looks like it comes down to function and variable declarations of a function type are treated differently though from the reading the documentation I wouldn't expect that to be the case. Did I miss the part of the documentation detailing this?
I would expect the illegal case to work just because it works in other languages. Like in JavaScript:
(function () {
var f = function (i) {
if (i == 0) {
return 1;
}
return i * f(i - 1);
};
console.log(f(2));
})();
The below code would be the preferred way of doing what you describe. Note that you do not have to create an additional variable, nor do you have a pointer to a function:
package main
import "fmt"
func main() {
var f func(int) int
f = func(i int) int {
if i == 0 {
return 1
}
return i * f(i-1)
}
fmt.Println(f(2))
}

undefined attributes in an slice of node structs

er, I am trying to learn go by implementing a random graph. I get an error on n.value undefined (type int has no field or method value), and n.neigbours undefined (type int has no field or method neigbours). I can not understand that compilation error as i create a new slice of nodesnr size of empty nodes in the g.nodes = make([]node, g.nodesnr). What is the problem?
package main
import (
"fmt"
//"math/rand"
)
type node struct {
value int
neigbours []int
}
type edge struct {
source int
sink int
}
type graph struct {
nodesnr, edgesnr int
nodes []node
edges chan edge
}
func main() {
randomGraph()
}
func input(tname string) (number int) {
fmt.Println("input a number of " + tname)
fmt.Scan(&number)
return
}
func randomGraph() (g graph) {
g = graph{nodesnr: input("nodes"), edgesnr: input("edges")}
g.addNodes()
for i := 0; i < g.nodesnr; i++ {
fmt.Println(g.nodes[i].value)
}
//g.addEdges()
return
}
func (g *graph) addNodes() {
g.nodes = make([]node, g.nodesnr)
for n := range g.nodes {
n.value = 2
n.neigbours = nil
return
}
}
func (g *graph) addEdges() {
g.edges = make(chan edge)
for i := 0; i < g.edgesnr; i++ {
//g.newEdge()
return
}
}
/*
func (g* graph) newEdge(){
e := new(edge)
e.source, e.sink = rand.Intn(g.nodesnr), rand.Intn(g.nodesnr)
g.edges <-e*
//g.addEdge()
}
*/
func (g *graph) edgeCheck(ep *edge) string {
if ep.source == ep.sink {
return "self"
}
//if(g.neigbourCheck(g.nodes[ep.source].neigbours, ep.sink) OR g.neigbourCheck(g.nodes[ep.sink].neigbours, ep.source){
// return "present"
return "empty"
}
func (g *graph) neigbourCheck(neigbours []node, node int) bool {
for neigbour := range neigbours {
if node == neigbour {
return true
}
}
return false
}
func (g *graph) addEdge() {
e := <-g.edges
switch etype := g.edgeCheck(&e); etype {
case "present":
fallthrough
case "self":
fmt.Println("self")
//go g.newEdge()
case "empty":
//g.nodes[e.source] = append(g.nodes[e.source], e.sink),
//g.nodes[e.sink] = append(g.nodes[e.sink], e.source)
fmt.Println("empty")
default:
fmt.Println("something went wrong")
}
}
Playground
Your error lies on line 47
for n := range g.nodes
When iterating over a slice, when using only one value, that value (n) will be set to the index, which is of type int. What you need to do is to change the line to:
for _, n := range g.nodes
This means that you discard the index but put the value in n instead.
Edit
n will be a copy of the value which means any changes made to n will not affect the node in the slice. To edit the node in the slice, you should actually get the index instead of the value:
for i := range g.nodes {
g.nodes[i].value = 2
g.nodes[i].neigbours = nil
return
}

Resources