-
Notifications
You must be signed in to change notification settings - Fork 17
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
Consider an API with fewer mutable classes #27
Comments
In the current design, The number of strokes and points in a drawing could be very large (thousands, or tens of thousands of points). Subsequent predictions may only involve a small change to the drawing. For example:
AFAIK, built-in JS arrays can't do this efficiently. |
As I said, that makes sense as to why you might need a HandwritingDrawing class, since maybe it's easier to cache getPrediction() results on a HandwritingDrawing class than on a JS array. (But see below.) But it doesn't explain why you need a HandwritingStroke class...
I think you could use either the built-in JS array, or a HandwritingDrawing instance, as the cache key for your internal store. If you used a built-in JS array, you'd have to either compute some sort of running hash of the array contents, or use the array object itself as the cache key and account for mutations of its contents during lookup. This is indeed more complicated, but maybe worth it in terms of simplifying the API for web developers. |
Thanks for the suggestion. I agree arrays are simpler, but may not be a good choice for some use cases. Please let me show a more concrete example. Say, the user writes cursive text "hello" in a single stroke. The web application requests a prediction midway (e.g. after "hel" are written). The code will look like this: const drawing = new HandwritingDrawing()
const stroke = new HandwritingStroke()
// The stroke starts.
drawing.addStroke(stroke)
// Points for "hel"
stroke.addPoint({x, y, t})
drawing.getPrediction() // => prediction is "hel"
// Points for "lo"
drawing.addPoint({x,y,t})
drawing.getPrediction() // => prediction is "hello" The implementation can easily determine stroke has been changed after being added to the drawing, by updating drawing's state in If we replace stroke with an array: const drawing = new HandwritingDrawing()
const stroke = []
// The stroke starts.
drawing.addStroke(stroke)
// Points for "hel"
stroke.push({x, y, t})
drawing.getPrediction()
// Points for "lo"
stroke.push({x, y, t})
drawing.getPrediction()
// Or mutate the value of a point.
stroke[1].x = newX It's very hard (or impossible?) to determine the changed strokes without inspecting all strokes:
|
When I benchmark iterating through a ten-thousand item |
Discussed offline with @domenic: The key is balance between API flexibility and easy-of-use. Let's propose / plan a future addition to With this addition, developers can avoid boilerplate-ish
|
Hey there,
From the perspective of idiomatic JavaScript, I was wondering why the API has so many classes and custom add/remove/clear methods, instead of using objects and arrays.
That is, instead of the example at https://github.com/WICG/handwriting-recognition/blob/main/explainer.md#perform-recognition, I would have expected something like this:
I'm not sure why the current API has so many mutable classes and extra copies. All the actual work seems to happen in the async
drawing.getPrediction()
(or, in my version,handwriting.getPrediction(drawing)
). So transforming that data intoHandwritingStroke
andHandwritingDrawing
classes seems like extra work.Are there implementation reasons why these mutable classes are necessary? If so, it'd be good to be clear about them in the explainer, and especially to explain why they are necessary in all implementations and not just a Chromium implementation limitation. I found https://github.com/WICG/handwriting-recognition/blob/main/explainer.md#alternative-api-design which maaaybe explains why a
HandwritingDrawing
class is necessary (although I had to read a lot between the lines; I'm guessing the idea is that you have some sort of side table mapping earlier versions of the drawing to recognition results, and then reuse those partial results in future calls togetPrediction()
? And that's impossible to do based on normal JS objects---for some reason?). But I'm not sure it explains why theHandwritingStroke
class is necessary.The text was updated successfully, but these errors were encountered: