How does fillStyle work in bs-webapi Canvas2d - html5-canvas

I'm wondering how to create a and set a fill style using bs-webapi and Canvas2d interface in ReasonML.
I think the definition I might need is this:
let fillStyle = (ctx: t) =>
ctx |> fillStyle |> reifyStyle;
But I'm having trouble understanding it.
I have previously used this project as a source of examples, but I think the bs-webapi has changed since that project was authored. At least the following line modeled after the example:
Canvas2d.fillStyle(ctx, "rgba(0,255,255,255)");
gives me this error:
Error: This function has type
Webapi.Canvas.Canvas2d.t => (Webapi.Canvas.Canvas2d.style('a), 'a)
It is applied to too many arguments; maybe you forgot a `;'.

The function you want is setFillStyle:
Canvas2d.setFillStyle(ctx, String, "rgba(0,255,255,255)");
This was renamed from fillStyle long ago, because there was no getter back then and the convention is to name the getter fillStyle and the setter setFillStyle. At the same time it was made to support gradients and pattern.
The way setFillStyle now works is that the second argument determines the type of the third. If you pass String as the second argument, the third is required to be a string. If you pass Gradient it needs to be a gradient, which you can get from createLinearGradient or createRadialGradient. And lastly you can pass Pattern, which requires the third argument be a pattern obtained from createPattern.
In general, you should refer to the Canvas2d test file for usage examples.

Related

How to write a macro like dot(.) operator in hylang?

We have some async properties (using #property) and some usual ones. We have to use hy to check if one is async or not using asyncio.iscoroutine function. The problem is we have to use getattr and not . operator, since dot will call the property inner function. We want to change our hy code without breaking the DSL used in other projects, that is, we do not want to use string notation (double quotes) for attribute name and therefore we need to write some macro working just like . but internally calls getattr.
=> (defmacro attr [obj attr] `(getattr ~obj '~attr))
=> (attr 5 real)
Traceback (most recent call last):
File "stdin-5bbedde10a6366314d9be4bd343639582b4d0748", line 1, in <module>
(attr 5 real)
AttributeError: 'int' object has no attribute 'real'
=> (. 5 real)
5
It sounds like you're confused about the semantics of Python properties, which is understandable, since they're rather hairy. In Python (and thus also in Hy for the equivalent constructions), foo.x and getattr(foo, "x") are always equivalent, even if x is a property. To get a property method as an object instead of calling it, you need to retrieve the attribute for the class (type(x)) instead of an instance, and getattr with a string literal and . remain interchangeable. In this example, getattr(type(foo), 'bar').fset could also be written as type(foo).bar.fset.
I tried
(defmacro attr [obj attr]
`(getattr ~obj ~(str attr)))
(print (attr 5 real))
in the web interpreter and it prints 5.
I was unable to reproduce your issue in the web interpreter though. It must still be running an older version, because I had to install your exact version to do it. I suspect that the following breaking change announced for 1.0a2 accounts for the difference:
Hy model objects are no longer equal to ordinary Python values. For
example, (!= 1 '1). You can promote values to models with hy.as-model
before making such a check.
My version of attr does work on Hy 1.0a3. I checked. Try it.
Attributes in Python are stored in the object's .__dict__ using string keys. Since Hy's symbols are no longer equal to strings, the lookup of a string key using a symbol will always fail. Converting the symbol to a string first fixes it. My initial comment was correct. (And this step is unnecessary in Hissp because it lacks Hy's separate model types.)
Although the latter answer works, but I found out that the problem is getting the method behind the property and as #kodiologist wrote, getattr and dot are equivalent. SO I used fget and :
(iscoroutinefunction (.fget (. (type obj) ~attr)))

ReasonML, side effecting call on x if option is Some(x)

I have let intervalId = option(Js.Global.intervalId)
I would like a succinct way to do the side effecting call to Js.Global.clearInterval if the option has a value (ie. is Some(id) and not None)
Maybe the Belt.Option.map function is the answer, but I'm having problems putting it to use.
I'm very new to OCaml and ReasonML, but several languages I know have suitable functions. I'm paraphrasing some of them here to give the idea what I'm looking for:
In Scala I would say: intervalId.foreach(Js.Global.clearInterval)
In Swift I would say: intervalId.map(Js.Global.clearInterval)
Belt.Option.map(intervalId, Js.Global.clearInterval) should work fine, except it returns a value that you need to discard in some way to avoid a type error or warning.
The safest way to discard values you don't need is to assign it to the wildcard pattern and include a type annotation to ensure the value you discard is what you expect it to be:
let _: option(unit) = Belt.Option.map(intervalId, Js.Global.clearInterval)
You can also use the ignore function, which works particularly well at the end of a sequence of pipes, but beware that you might then accidentally partially apply a function and discard it without actually executing the function and invoking the side-effect.
intervalId
|> Belt.Option.map(_, Js.Global.clearInterval)
|> ignore
For curiosity, I'll leave the obvious thing I had here before the chosen answer:
switch (intervalId) {
|Some(id) => Js_global.clearInterval(id)
|None => ()
}

How to specify the type signature to find a specific method with InteractiveUtils.edit in Julia?

In order to quickly find the implementation of some methods I would like to use InteractiveUtils.edit.
E.g. if I wanted to see the implementation of methodswith I should be able to write something like edit(methodswith). However, as the methodswith function has multiple methods I get:
ERROR: function has multiple methods; please specify a type signature
How do I specify the type signature? I know that I can find out which methods there are with methods(methodswith), giving signatures like this:
[1] methodswith(t::Type; supertypes) in InteractiveUtils at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.0/InteractiveUtils/src/InteractiveUtils.jl:169
How can I plug this into a call of edit?
I know that there is #edit which I could use with some exemplary function call. However, sometimes it would be more straightforward to just specify the types, because constructing the objects for an exemplary call of the method also involves some investigation for valid constructors.
TL;DR:
How to find a specific method of a function with InteractiveUtils.edit in Julia?
Just pass argument types as a tuple in the second positional argument to edit.
For example edit(sin, (Int,)) will open you the definition of sin that is used with one argument of type Int.
Note that this might fail if you want to edit a function from stdlib (for functions from Base or non-standard libraries edit will work properly).
In such a case you have to use methods function and locate the file manually. For example:
julia> using Statistics
julia> edit(mean, (Vector{Int},)) # this might not work as expected
julia> methods(mean, (Vector{Int},))
# 1 method for generic function "mean":
[1] mean(A::AbstractArray; dims) in Statistics at C:\cygwin\home\Administrator\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.1\Statistics\src\Statistics.jl:132
Now you have a file name and a line number where the method is located, but the path may be wrong, so you have to find the file yourself in the Julia installation folder.
Here is how you can retrieve this information programatically (assuming you have specified the args correctly and only one method matches). First define a function:
function edit_stdlib(fun, args)
m = methods(fun, args)
#assert length(m.ms) == 1 # assume we have an exact match
p = joinpath(Sys.STDLIB, splitpath(string(m.ms[1].file))[end-2:end]...)
l = m.ms[1].line
edit(p, l)
end
and now you can write e.g. edit_stdlib(mean, (Vector{Int},)) to get what you want.

Refactoring Business Rule, Function Naming, Width, Height, Position X & Y

I am refactoring some business rule functions to provide a more generic version of the function.
The functions I am refactoring are:
DetermineWindowWidth
DetermineWindowHeight
DetermineWindowPositionX
DetermineWindowPositionY
All of them do string parsing, as it is a string parsing business rules engine.
My question is what would be a good name for the newly refactored function?
Obviously I want to shy away from a function name like:
DetermineWindowWidthHeightPositionXPositionY
I mean that would work, but it seems unnecessarily long when it could be something like:
DetermineWindowMoniker or something to that effect.
Function objective: Parse an input string like 1280x1024 or 200,100 and return either the first or second number. The use case is for data-driving test automation of a web browser window, but this should be irrelevant to the answer.
Question objective: I have the code to do this, so my question is not about code, but just the function name. Any ideas?
There are too little details, you should have specified at least the parameters and returns of the functions.
Have I understood correctly that you use strings of the format NxN for sizes and N,N for positions?
And that this generic function will have to parse both (and nothing else), and will return either the first or second part depending on a parameter of the function?
And that you'll then keep the various DetermineWindow* functions but make them all call this generic function?
If so:
Without knowing what parameters the generic function has it's even harder to help, but it's most likely impossible to give it a simple name.
Not all batches of code can be described by a simple name.
You'll most likely need to use a different construction if you want to have clear names. Here's an idea, in pseudo code:
ParseSize(string, outWidth, outHeight) {
ParsePair(string, "x", outWidht, outHeight)
}
ParsePosition(string, outX, outY) {
ParsePair(string, ",", outX, outY)
}
ParsePair(string, separator, outFirstItem, outSecondItem) {
...
}
And the various DetermineWindow would call ParseSize or ParsePosition.
You could also use just ParsePair, directly, but I thinks it's cleaner to have the two other functions in the middle.
Objects
Note that you'd probably get cleaner code by using objects rather than strings (a Size and a Position one, and probably a Pair one too).
The ParsePair code (adapted appropriately) would be included in a constructor or factory method that gives you a Pair out of a string.
---
Of course you can give other names to the various functions, objects and parameters, here I used the first that came to my mind.
It seems this question-answer provides a good starting point to answer this question:
Appropriate name for container of position, size, angle
A search on www.thesaurus.com for "Property" gives some interesting possible answers that provide enough meaningful context to the usage:
Aspect
Character
Characteristic
Trait
Virtue
Property
Quality
Attribute
Differentia
Frame
Constituent
I think ConstituentProperty is probably the most apt.

No member named dim in Halide::GeneratorInput<Halide::Func>

I'm trying to translate the resize app from the halide repository from the inline declarations to a generator. Everything seems to work fine, except for this:
Func clamped = BoundaryConditions::repeat_edge(input);`
In the original code, input is declared like so ImageParam input(Float(32), 3). In my generator, I've translated this to: Input<Func> input { "input", Float(32), 3 }. I'm then declaring the clamped in the exact same way as the original code. When compiling, I'm getting this error:
Halide.h:15202:50: error: no member named 'dim' in 'Halide::GeneratorInput<Halide::Func>'
object_bounds.push_back({ Expr(func_like.dim(i).min()), Expr(func_like.dim(i).extent()) });
~~~~~~~~~ ^
Is there a way to create a BoundaryConditions::repeat_edge on an Input<Func>?
There is, associate a Buffer<> with it. (Maybe a Buffer in your case, try it out).
struct MyGen : Generator<MyGen> {
Input<Buffer<>> dim_only_input_buffer{ "dim_only_input_buffer", 3 };
...
};
I ran into something similar, you can see more about this in this github issue
The idea of Input<Func> is that it may be instantiated with another Func when composing generators together. (E.g. the output of one generator may be the input to another and the graph of all connected generators is compiled as a single Halide program.) The problem is Funcs do not have fixed bounds like Buffers do. Hence one cannot ask for (e.g.) the width of a Func.
For a generator which is designed to always be used with concrete memory, one can use Input. To impose a boundary condition on an Input, the bounds need to be passed as explicit parameters to the generator. E.g. as other Inputs.

Resources