No elegant way to make a struct with mixed element?

Pascal has a way to make struct with variant type with union.
In C++ ,you can do this with struct/ object with a common ancestor.
But so far, i didn’t find a solution without unsafe pointer and casting. Did a miss a trick ?

Can you provide an example what problem you want to solve?
Depending on the example you could use Interfaces, embedding or pointer-casting.

I’m trying to write an interpreter. I need to do linked list with different type of element like string | number | expression list. It’s my exercise when I learn a new language.

I’m using these programs as a reference: https://github.com/pliba/kamin

so far I have found this: https://www.jerf.org/iri/post/2917/

But it’s not very compact in comparison to the C version.

If all elements in a single list have the same type one can use generics like this: list[string] if they have potentially different types in the same list, one could just use the interface type “any”.
Interface types store the data inline if it is small enough, or a pointer if the data is bigger.
You can use a union like data type for very special use cases with pointer casting, but I would only recommend it if all the safer/easier options don’t satisfy your requirements under realistic conditions.

I knew this solution. But I was hoping to find a better solution. At some point, language maintainers are going to have to consider the solution of C, or object-oriented programming, or a less rigid interface model with return values. They have been debating on the subject since at least 2017. It’s heartbreaking.

It looks like I’m going to have to keep exploring programming languages.

Thanks anyway.

Go has made its’ name on being opinionated and slightly different than other languages. If it doesn’t work for your use case, there are a lot of other really great options out there. But they the rigidity of the language/tooling is something most people see as a feature. This is a tad like complaining about Rust because you don’t like the borrow checker, when the borrow checker is one of the selling points of Rust.

That is one of the strengths and weaknesses of Go. Nearly everything in language/compiler design is a series of tradeoffs. The Go team moves slowly in an attempt to make the right tradeoffs and not break their promise of compatibility.

Check out zig if you haven’t already!

1 Like

It could be informative to check “Writing An Interpreter In Go” from Thosten Ball (https://interpreterbook.com/) I am not relate in any form with Thosten, however this book look interesting

It’s seem just a little bit less complicate than Rust
Ordinary, I’m using Ruby. Because i prefer to put my concentration on the idea instead of how building the idea. I’m more an analyst than a programmer. An i have the luxury doing prototype mainly. But with Ruby, it is easy to steal a prototype. And use it to make a finish product.

Pascal was my first language. Golang has a lot of similarity with it. And enough speed for my need.

And i found the solution to the problem

package main

import "fmt"

type Exptype int

const (
	NullType Exptype = iota
	IntType
	StringType
	ListType
)

type MixedNode struct {
	data interface{}
	next *MixedNode
}

// Returns an initialized list
func (n *MixedNode) Init() *MixedNode {
	n.data = -1
	return n
}

// Returns an new list
func New() *MixedNode {
	return new(MixedNode).Init()
}

// Returns the first node in list
func (n *MixedNode) Next() *MixedNode {
	return n.next
}

// Returns the last node in list if exist, otherwise returns current
func (n *MixedNode) Back() *MixedNode {
	current := n.next
	for current != nil && current.next != nil {
		current = current.next
	}
	return current
}

// This function prints contents of linked list starting from the given node
func printList(n *MixedNode) {
	for n != nil {
		fmt.Println(n.data)
		n = n.next
	}
}

func main() {
	//To allocate dynamically a new MixedNode in C language : head = (struct MixedNode*) malloc(sizeof(struct MixedNode));
	head := New()
	second := New()
	third := New()

	//Assign data in first node
	head.data = 1
	//Link first node with second node
	head.next = second

	second.data = "Allo"
	second.next = third

	nums := [4]int{1, 2, 3, 4} // init
	third.data = nums
	third.next = nil

	printList(head)
}

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.