Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

user-defined type conversion #199

Open
cvillecsteele opened this issue Jun 2, 2016 · 4 comments
Open

user-defined type conversion #199

cvillecsteele opened this issue Jun 2, 2016 · 4 comments

Comments

@cvillecsteele
Copy link

In runtime.go, convertCallParameter() does a decent job of doing what it can. But sometimes I need more. I don't want to write silly wrapper functions, say, to convert a string into an io.Writer. Let me provide the runtime with a user-defined conversion function, which convertCallParameter() can fall back to if it can't figure out what to do. #

@deoxxa
Copy link
Collaborator

deoxxa commented Jun 2, 2016

100% agree. I've been wanting to put something like this together for a while. Any ideas as to how you'd expect the interface to look?

Imagine a type like so:

type Magician struct { Card string }
func NewMagician(card string) { return Magician{Card: card} }
func (m Magician) PickACard() string { return m.card }

I'd love it if this could be accessible as new Magician("ace of spades"), and if PickACard could be accessed as pickACard.

And then there are non-struct types:

type Counter int
func (c *Counter) Add(n int) { *c += n }

For this, we probably want valueOf to return the numeric value. And how do we make "Add" available as "add"?

I realise that this isn't exactly what you were talking about, but there are lots of open (and related!) API questions here.

@cvillecsteele
Copy link
Author

cvillecsteele commented Jun 2, 2016

I really like what you posted above. Thinking out loud here, so caveat emptor. More focused (at least at the moment, given my lack of sleep) on my particular problem, not so much on your more generalized solution...

rt := otto.New();
rt.SetUserCallConverter(func(v Value, t reflect.Type) *reflect.Value {
    // nifty type conversion code here
});

Then at the end of convertCallParameter():

if self.UserCallConverter {
    if result := self.UserCallConverter(v, t); result != nil {
        return *result;
    }
}

But your thinking is mighty interesting. I'd like that too... There's a lot of ceremony right now for accomplishing what you've suggested, and it's really just boilerplate, so I think a good candidate for a "real" Otto API.

@cvillecsteele
Copy link
Author

cvillecsteele commented Jun 2, 2016

Related... one thing that has been a source of irritation using Otto is that golang does not support package-level introspection at runtime. It can be done statically / with generators, and that approach has been used fairly extensively in some of the golang SDKs I've worked with, but the approach is tiresome (to me at least). I have wanted to be able to point at a golang package (say, filepath) and tell Otto (in effect), "export all that to JS-land". No easy way to do that now.

Reluctantly, I observe that the path of least resistance forward in this area seems to point to some sort of IDL. (Blech.)

(See here: https://groups.google.com/forum/#!topic/golang-nuts/M0ORoEU115o)

@gen0cide
Copy link

@cvillecsteele @deoxxa This is something I'd be very interested in as well. I worked around the issue you described in my project (github.com/gen0cide/gscript/compiler) which essentially "links" Go packages into JS land and instruments a custom otto VM with all the glue.

I'd be interested in understanding how we might be able to marry some of these efforts together.

I don't think there's any issue linking pkg.NewMagician("foo") into the runtime as is. My bigger issue was more around instantiation of new object types. I defined a Create() function inside of my runtime with pointers to my NativeType definition which includes a cumbersome, but working Factory to initialize a new object in memory.

REF: https://github.com/gen0cide/gscript/blob/master/engine/native_package.go#L55

Is there a roadmap or sketch around what's next for Otto? Curious how this work might fit in.

Cheers!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants