Showing posts with label golang_type. Show all posts
Showing posts with label golang_type. Show all posts

Mar 19, 2021

[Go] untype type

Reference:
https://groups.google.com/g/golang-nuts/c/9EVmGFVoawg/m/nYXYaUcpCgAJ


Untyped bool, int, etc are the types of untyped constants:
https://golang.org/ref/spec#Constants

package main

const i = 42      // i is untyped int
const j = int(42) // j is int

var f float64 = i // ok because i is untyped int
var g float64 = j // compile error, type mismatch

func main() {
}

Mar 16, 2021

[Go] type define can assign to un-defined type

Reference:
1. https://www.youtube.com/watch?v=HxaD_trXwRE
2. https://golang.org/test/peano.go
3. C++ "Variadic Templates , Parameter Packs" 


Unlike C++, the type alias in Go can be assigned to a pointer to none-defined type.
i.e
 type Number *Number
This could form a lambda calculus computation, which is demo in:
https://golang.org/test/peano.go

package main

import "runtime"

type Number *Number

// -------------------------------------
// Peano primitives

func zero() *Number {
	return nil
}

func is_zero(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 is_zero(y) {
		return x
	}

	return add(add1(x), sub1(y))
}

func mul(x, y *Number) *Number {
	if is_zero(x) || is_zero(y) {
		return zero()
	}

	return add(mul(x, sub1(y)), x)
}

func fact(n *Number) *Number {
	if is_zero(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 is_zero(x) {
		return 0
	}

	return count(sub1(x)) + 1
}

func check(x *Number, expected int) {
	var c = count(x)
	if c != expected {
		print("error: found ", c, "; expected ", expected, "\n")
		panic("fail")
	}
}

// -------------------------------------
// Test basic functionality

func init() {
	check(zero(), 0)
	check(add1(zero()), 1)
	check(gen(10), 10)

	check(add(gen(3), zero()), 3)
	check(add(zero(), gen(4)), 4)
	check(add(gen(3), gen(4)), 7)

	check(mul(zero(), zero()), 0)
	check(mul(gen(3), zero()), 0)
	check(mul(zero(), gen(4)), 0)
	check(mul(gen(3), add1(zero())), 3)
	check(mul(add1(zero()), gen(4)), 4)
	check(mul(gen(3), gen(4)), 12)

	check(fact(zero()), 1)
	check(fact(add1(zero())), 1)
	check(fact(gen(5)), 120)
}

// -------------------------------------
// Factorial

var results = [...]int{
	1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800,
	39916800, 479001600,
}

func main() {
	max := 9
	if runtime.GOARCH == "wasm" {
		max = 7 // stack size is limited
	}
	for i := 0; i <= max; i++ {
		if f := count(fact(gen(i))); f != results[i] {
			println("FAIL:", i, "!:", f, "!=", results[i])
			panic(0)
		}
	}
}
and for this:
type F func() F 
on the other hand, are useful for state machines.
The idea is that the current state of some operation is expressed in the form of a function, and every call to the state function returns a function that implements the next state. There is an example of this at: https://golang.org/src/text/template/parse/lex.go#L105

Mar 23, 2019

[Go] interesting read of Eli Bendersky's "Does a concrete type implement an interface in Go?"

Eli Bendersky has post an interesting article titled
"Does a concrete type implement an interface in Go?"


I really do love seeing C++ experts playing with other languages from their deep understanding of C/C++/Assembly :-)


Go's interface stores embedded data's type information, RTTI in C++, a pointer to v-table minus offset is type information, plus offset are pointers to member functions(index honors declared sequence).

Go's interface stores embedded data act as this pointer in C++, while calling the member functions, copying the embedded data as first parameter into member functions.

Thus, if embedded data is pointer type, then copy the pointer into the member functions.

Alas, if embedded data is instance of the data type, then copy the instance into the member functions.

Go's interface implement:
https://github.com/golang/go/blob/56131cbd1d61ec446e10dfe72a96f329ed3d952a/src/go/types/type.go#L244

Thus, Go's interface type provides an extra layer of abstraction for interface exchanges.

package main

import "fmt"

type fun struct {
}

func (f *fun) run() {
 fmt.Println("stateless member function call.")
}

type I interface {
 run()
}

func main() {
 I((*fun)(nil)).run()
}

C++: https://godbolt.org/z/YWAXze
#include <iostream>

struct fun {
    void run()
    {
        using std::cout;
        using std::endl;
        cout << "stateless member function call." << endl;
    }
};

int main()
{
    static_cast<fun*>(nullptr)->run();
}


Reference:
A book about the internals of the Go programming language
https://github.com/teh-cmc/go-internals

Go 1.1 Function Calls - Russ Cox, February 2013
https://docs.google.com/document/d/1bMwCey-gmqZVTpRax-ESeVuZGmjwbocYs1iHplK-cjo/pub

Go Data Structures: Interfaces, Russ Cox, December 1, 2009.
https://research.swtch.com/interfaces

Go Interfaces, Ian Lance Taylor
https://www.airs.com/blog/archives/277

[golang] reflection quick note
http://vsdmars.blogspot.com/2019/01/golang-reflection-quick-note.html

Mar 8, 2019

[Go] conversion rule

Conversion rules:

Since Golang 1.7
A non-constant value x can be converted to type T in any of these cases:
  • same sequence of fields (order matters due to memory layout, in C/C++/assembly/Golang, which includes padding.
    In C++, padding matters also due to object slicing (hey, we have inheritance in C++).
    Please refer to note:
    http://vsdmars.blogspot.com/2018/09/golangc-padding.html)
  • corresponding fields with same type.
  • x is assignable to T.
  • x's type and T have identical underlying types.
  • x's type and T are unnamed pointer types and their pointer base types have identical underlying types.
  • ignoring struct tags, x's type and T have identical underlying types.
  • ignoring struct tags, x's type and T are unnamed pointer types and their pointer base types have identical underlying types.

type Person struct {
    Name     string
    AgeYears int
    SSN      int
}

var aux struct {
    Name     string `json:"full_name"`
    AgeYears int    `json:"age"`
    SSN      int    `json:"social_security"`
}

var yeah Person = Person(aux)