-
Notifications
You must be signed in to change notification settings - Fork 570
Discussion/Proposal: Addressing the idiomatic mismatch between JavaScript and Go #401
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
Comments
@flimzy I'm in following mode at the moment, but interested in following this work |
Agree. I believe this will eventually arrive naturally ... it is hard to know what's idomatic GopherJS until it is in your fingers. I have fiddled with some Facebook React "bindings" the last week. And I think part of the problem is that we call it "bindings" -- which to many translates to a 1:1 mapping. |
I think you've raise some important issues. I see three distinct proposals:
This may be distinct from your proposal, but I'd also like to see some (more) basic documentation, perhaps in the Wiki, on basic usage. How you can use a Go struct (a struct without a *js.Object member), and how you can use a JS struct (a struct with a *js.Object member), and the pitfalls of trying to mix them or confuse them. (E.g. if you want to have a *js.Object member, it must be first, and all your other struct slots must have a And finally, GopherJS has a Google Group. Might I suggest that discussions such as this be held there? Update: I just noticed that this was from 2/14. Sorry for being late to the party. |
Also, I think it would be fine to have bindings that live close to their JS counterpart, and then build more "Go like" libraries on top of those. It is hard to make a JQuery abstraction that doesn't look like jQuery -- but it is easier to build something better on top of a "jQuery like" Go API. |
I think a great starting point for a style guide is for it to point to some existing bindings/libraries from https://github.com/gopherjs/gopherjs/wiki/bindings and suggest using them as a source to learn from. I doubt maintaining a separate style guide is viable this early in this stage and with this few people actively working on it. |
I have read through this issue, but I'm not quite sure what action is proposed here. Is it just that someone writes a document explaining how to make a Go-idiomatic bindings for a JavaScript API? https://github.com/gopherjs/gopherjs/wiki/bindings already has a long-ish list of binding libraries, and I think by now we've established that binding libraries don't have to be owned by the GopherJS organization, perhaps except for the most commonly used ones. |
I think this issue can be closed. It generated some good discussion, but as mentioned, there's no clear course of action proposed. Also, the situation has changed somwhat in the years since this was written, so any existing comments are mostly of historical value, not toward any actions we might take today. Closing. |
This is an issue that's been rolling around in my head for several months. It's more a discussion topic than a specific bug/issue.
As background, I don't know precisely what objectives @neelance had in mind when writing GopherJS. I gather the primary goal (aside from proving it could be done) was to run Go code in the browser. It seems this goal has been largely acheived, with good support for most of the Go standard library. But my primary reason for using GopherJS is to replace JavaScript as the language for writing client-side code. I think it's the other side of the same coin. Toward that end, I think there's room for some improvement.
Here I'd like to address two specific issues, closely related to each other.
The more general issue is that there's no defined style guidelines for GopherJS. There's no "GopherJS way." There is the "Go way" and there is the "JavaScript way" (or ways). And these are good in their own rights, but they are often incompatible, which leads to messy GopherJS Binding libraries. Most of the existing GopherJS bindings I've seen, lend themselves to writing JavaScript code in Go, complete with callbacks, event handlers, and everything else. This doesn't make for very idiomatic Go code, and it raises the barrier to entry, as one must understand both Go and JavaScript idioms to effectively use these libraries. And in many cases, these JavaScript-as-Go idioms can be avoided, by writing (IMO) better bindings.
In my experience, the most common casees where idioms of the two worlds crash are:
Other examples include data type conversions, error handling, null vs nil vs undefined, etc.
The second issue I wish to address is on a higher level. There are a large number of JavaScript APIs that don't have direct correlations in Go, but to be a full-fledged replacement for JavaScript in the browser, these need to be accessible. At the most primitive level, of course, they are accessible. By using
.Get()
,.Call()
, and related functions in thegopherjs/js
packages, literally anything can be accomplished. But that leads to very verbose, and hard-to-follow code, that isn't at all idiomatic Go.We already have example bindings for some of these APIs. But there are many more which don't yet have bindings (to my knowledge). And at least some of the existing bindings don't make for especially idiomatic Go. The jQuery bindings expose the Deferred interface, which isn't idiomatic Go, and I believe could be more idiomatically exposed as synchronous operations (wrap it in a go routine if you need async). The websocket bindings provide both JS and Go idiomatic versions, which I think is an example of a good way to do things.
I expect some big improvements could be made toward idiomatic Go bindings of JS libraries.
This brings me to some possible responses to these issues:
Perhaps at minimum a GopherJS Bindings style guideline could be written. This might exist on the wiki page and/or in the gopherjs-book (is that still alive?). IMHO, this ought to cover suggestions of how to handle JS functions that accept multiple arguments, when (if ever) to expose Callback APIs, versus creating a synchronous wrapper around the underlying object (or perhaps providing both functionalities in the Go API), how events can or should be handled, how to handle errors returned by JS functions, etc.
With such guidelines in place, I think writing idiomatic Go bindings will become much easier. Which lends to...
Should GopherJS own the bindings for official JavaScript APIs? It already owns webgl and websocket bindings. Is there an interest in owning bindings for the File APIs, Worker APIs, Events, etc? If so, how should these various bindings be broken up by package? How can quality/adherence to the guidelines be ensured? Etc? (I don't expect answers to all of these questions now)
And finally, for non-official APIs (PouchDB, jQuery, etc), perhaps it would be worth mentioning in the bindings page which of them adhere to the style guidelines.
I know this leaves a lot of questions unanswered, such as "who's going to do this work?", not to mention "what will the guidelines actually contain?" I'm willing to contribute where possible. But I want this post to be primarily the beginning of this conversation, it doesn't have to answer all of the questions at once.
I'll wait to get some preliminary feedback, but I'm willing to start writing the rough draft of some bindings guidelines, and add them to the wiki (or whereever).
The text was updated successfully, but these errors were encountered: