glycerine/zygomys

Q: How to create a hash in Go?

markx opened this issue · 5 comments

markx commented

I'm trying to convert a Go struct to a hash, and pass it into zlisp.

func MakeHash(args []Sexp, typename string, env *Zlisp) (*SexpHash, error) { is the only function I found, but why does it depend on env? I gave it a nil, and it panics.

Is there a better way to create a hash in Go?

And even more specific to my use case, what's the best way to turn a Go struct into a hash and pass it to env? I just need it read-only. No need to create structs from zlisp.

but why does it depend on env? I gave it a nil, and it panics.

MakeHash creates the hash table in the zygo environment env. Since it can contain references to many different values within the environment, you are simply telling zygo which lisp environment you want to own your hash--and how to lookup those symbols that it references. Just make a new env or pass in the one you are working with.

to turn a Go struct into a hash

I think you would have to do that manually. Create the hash, walk the struct, add each field in turn.

If instead, however, you wanted to register your Go struct and have zygo use reflection to allow it to be manipulated and read by zygo (a major use case is going the other direction: zygo hash into Go struct), then that is supported. It uses the json field tags in particular to map the names of struct fields into zygo.

Here is an example of how to do this:
https://github.com/glycerine/zygomys/blob/master/zygo/demo_go_structs.go#L121

docs:
https://github.com/glycerine/zygomys/wiki/Go-API#registering-go-structs-creating-corresponding-records-and-automatically-configuring-a-tree-of-go-structures

update: I don't think that the example does do exactly what you want. So you may have proceede manually. Not hard. But perhaps the above gives you useful ideas, so I will leave it.

markx commented

I think you would have to do that manually. Create the hash, walk the struct, add each field in turn.

Then I'll do it manually.
My biggest problem is to create the hash. Is MakeHash the only/best way to create a hash?

I don't know what to pass for the parameters. I feel it's quite counter-intuitive. What is a typename for a hash? Why should it depend on an env? If this is just to satisfy the signature as one of those builtin functions to be injected into the environment, I guess that make sense. But I find it confusing that these parameters are actually required.

Also, in my understanding, a hash is just data, so it really shouldn't contain a reference to the environment. What if I need to create the hash before I have an env? What if I need to dynamically set the env?

Anyway, I guess it's one of the design decisions made for a trade off. I just haven't looked deep enough to fully understand the reason behind it. :)

https://en.wikipedia.org/wiki/XY_problem

If you describe your high level objective, we might better assist. Your questions don't really make any sense. One always creates a zygo hash inside a zygo env, for the reasons already explained. Making an env is trivial; env := zygo.NewZlisp()

What are you really trying to do, at a high level?

markx commented

Sure. What I'm really trying to do, as I mentioned in the beginning, is to convert a Go struct to a hashmap, and pass it into zlisp.

markx commented

Don't be mad man. Sorry for the confusion. Is this not high level enough? Let me try to rephrase it. My goal is to pass a Go struct to a zlisp, and this struct could be something like

type Person struct {
    Name string
    Age int
}

Hope you could still help.