Closed dgrr closed 4 years ago
Thanks for sharing this with us. Great that you are working with Anko.
Currently Anko can call functions that on in structs but struct type definitions are not really there. My idea is to add/improve struct type definitions to Anko. Once that is done, Anko should be able work like Go for making structs and using there functions.
How is that different then what you are working on?
Hello,
The difference is that my implementation performs those calls transparently. I think I didn't explain my example well.
In my fork when you call v = obj["key"]
the vm calls obj.Get
transparently. It's like doing the following in C++:
void* A::operator[](std::string key) {
...
}
In C++ the compiler will call the operator overload function every time there's a call like obj["key"]. (assume obj's type is A). I implemented that in anko, and I would like to know if you are interested in something like that in the main repo. If you aren't I will keep it in my fork and if you like the idea you can add a section on the README pointing out my repo with the features available.
Thanks for the link to the repo. I personally think that overloading is beyond the scope of Anko, mainly because there is no overloading in Go.
Side note, often I see overloading more of a syntax shortcut then really needed. Was curious what is your use case where it is required where another option could not be used?
I am using anko to transform CSV rows. I already have an efficient parser and I wanted to add the transformation feature. I want to be easy to use by non-programmer users. So doing something like
v, ok = obj["key"]
if ok {
v = 20
}
requires obj
to be a map. Anyway, the v value is not modified if the script doesn't contain obj["key"] = v
. To accomplish that I have to:
Get
and Set
).I want to keep a balance between performance and easiness of use, and of course, I don't want to modify the parser. So what I did is implementing in the Row
struct functions like Get
which returns the struct Column
which implements Set
. So, when I do v, ok = obj["key"]
, being obj a Row and the returned object a Column, I can easily use the script above without modifying my code, and also, avoiding the user getting in complex language stuff.
I know Golang doesn't have any overriding, but an interpreted language can. And yes, it is a syntax shortcut.
Not sure if I follow exactly but have you looked at using https://godoc.org/github.com/mattn/anko/env#Env.SetExternalLookup
I think it isn't the same, because my functions doesn't have only the Get. Try this example:
package main
import (
"fmt"
"github.com/dgrr/anko/env"
"github.com/dgrr/anko/vm"
)
type Row struct {
h []string
c []Column
}
func (r *Row) Get(k string) Column {
for i, h := range r.h {
if h == k {
return r.c[i]
}
}
return nil
}
type Column interface {
Set(v interface{})
}
type ColumnInt struct {
v int64
}
func (c *ColumnInt) String() string {
return fmt.Sprintf("%d", c.v)
}
func (c *ColumnInt) Set(v interface{}) {
c.v = v.(int64)
}
type ColumnString struct {
v string
}
func (c *ColumnString) Set(v interface{}) {
c.v = v.(string)
}
func (c *ColumnString) String() string {
return c.v
}
func main() {
r := Row{
h: []string{"a", "b"},
c: []Column{
&ColumnInt{1},
&ColumnString{"first"},
},
}
e := env.NewEnv()
e.Define("row", &r)
e.Define("println", fmt.Println)
vm.Execute(e, nil, script)
fmt.Println("\nAfter exec")
for _, c := range r.c {
switch col := c.(type) {
case *ColumnInt:
fmt.Println("a:", col.v)
case *ColumnString:
fmt.Println("b:", col.v)
}
}
}
var script = `
v, ok = row["a"]
if ok {
println("a:", v)
v = 20
}
v, ok = row["b"]
if ok {
println("b:", v)
v = "hello"
}`
Right, I am saying if you remove the syntax shortcuts (overloading), the external lookup would work fine.
If it is really important that you have the syntax shortcuts instead of the method calls, then yes, overloading would need to be implement.
Personally I think having method calls can make it easier for people.
Yes. Said that, would you accept a PR applying those shortcuts?
Like I mentioned, I personally believe overloading is beyond the scope of Anko. Matt has the final say of accepting PRs.
In that case, I will keep that in my fork. Thanks.
Hello,
I am developing a project in need of function overriding. I already developed some on my fork, but I was wondering if you would be interested in merging my commits to the master branch. Let me show you some examples so you can have a better idea of what I am trying to do:
Having:
I want to call A from the script in a transparent way by using:
That should call:
That's already implemented in my fork, and you can try it out with your custom structures. I'll wait for your comments and suggestions.
Thanks.