How to represent method calls ReScript 9.1.2 - interop

ReScript 9.1.2 made the original #meth semantics inaccessible they said to use #send external instead to represent method calls
My questions are:
can #send external be inside a type?
and is this a correct way to use it knowing that it generates the same javascript code?
Using #meth:
#meth
"createElement": string => Web_node.t,
let createElement = typ => document["createElement"](typ
Using #send external:
#send external
createElement: (t,string) => Web_node.t="createElement"
let createElement = typ => createElement(document, typ)

I don't know what you mean by "inside a type", but yes, that is how you represent a method call. You can verify this by looking at the generated JavaScript. An easy way to do this is by creating an example in the rescript playground, which will show that it generates this:
function createElement(typ) {
return document.createElement(typ);
}
Another handy resource is the rescript bindings cookbook.

Related

Is it bad to use a variable from outside the observable pipe within an operator?

Is using a variable from outside an observable within an operator considered a (significantly) bad practice?
createObservableExample1(parameter1: string, obs$: Observable<string>): Observable<string> {
return obs$.pipe(
map( x => {
const returnValue = `${parameter1}, ${x}`;
return returnValue;
})
);
}
I understand you can do something like this:
createObservableExample2(parameter1: string, obs$: Observable<string>): Observable<string> {
return combineLatest([
of(parameter1),
obs$
]).pipe(
map( (x, y) => {
const returnValue = `${x}, ${y}`;
return returnValue;
})
);
}
But is it worth it?
Does this just come down to accessing variables from outside the scope of anonymous function? Would this force the context of the enclosing method to exist for longer than it should? I remember a code tool I used to use for C# complaining about something similar to this. I have found somewhat related topics by searching for, "anonymous functions and closures", but as of yet, nothing really discussing the scenario explained above.
I ask because I have been creating some relatively complex observables that have enormous operator chains, and constantly adding the needed variables, using combineLatest and of, from the parent scope can make the code even harder to follow.
When I teach Reactive programming to neophytes, I try to make them grasp : Do not break the reactivity by having uneccessary side effects :
no input that from a state (for example using a class or instance property
no storing outside value.
There is none of these red flags in your example. Your function is pure & idempotent with both implementation, go with what ever you like and if possible be consistant within your code base !

Reason React and Graphql handling ENUM values

Just started to learn reason react and struggle with a graphql setup trying to read an ENUM value.
setup
reason react
apollo graphql
graphql_ppx
github graphql endpoint
i am fetching the latest pull request data over the github api and reading the status property which is an enum and defined in the gql docs as:
OPEN
CLOSED
MERGED
checking the network tab, i see the states are received as strings. within the application when I log the field i get a bunch of integers reflecting the values. can smb explain me, how i can "print" the data as string to my view and why they are translated to integers? is there somewhere a type generated which i could use for a variant switch?
let stateEnum = data->map(node => node##state);
Js.log(stateEnum) // possible values: 880069578, 982149804 or -1059826260
// somehow switch these values here?! :)
// current type of `stateEnum` is option('a)
thanks a lot in advance and have a nice day!
GraphQL Enums are represented as Reason polymorphic variants. Under the hood, in runtime, they are just integers. If you want to display them to the user you have two options:
1. Map them to string by hand using a switch
let status =
switch(node#status) {
| `OPEN => “Open”
// other cases
}
You can use BuckleScript functionality do generate jsConverters:
[#bs.deriving jsConverter]
type status = [ |`OPEN | `CLOSED /* other cases */]
this will generate two functions for you: statusToJs and statusFromJs. They help you convert variant to and from string.
Here is BuckleScript documentation about it: https://bucklescript.github.io/docs/en/generate-converters-accessors#convert-between-js-string-enum-and-bs-polymorphic-variant
As #Herku mentioned in his comment, the key was just to do this:
// asume that your enum is on a gqp property called `state`
// and we use the built in lib `Belt.Option` and the fn `getWithDefault`
// this way we are sure, that `stateEnum` is defined with one of the valid enum values
let stateEnum = data->map(node => node##state)->getWithDefault(`OPEN);
// next we switch the polymorphic variant
let state = switch(stateEnum) {
| `OPEN => "open"
| `CLOSED => "close"
| `MERGED` => "merged"
}
// str = let str = ReasonReact.string;
str(state);

Liftable for function literal

Is there a way to make a Liftable for a functional literal (with 2.11)? If I have
case class Validator[T](predicate: T => Boolean)
val predicate = (s: String) => s.startsWith("Hi")
then I want to be able to quasiquote predicate too:
q"new Validator($predicate)"
I hoped to magically create a Liftable with an underscore. But that was a little too optimistic:
implicit def liftPredicate[T: Liftable](f: T => Boolean) =
Liftable[T => Boolean]{ f => q"$f(_)" }
I couldn't figure out from looking at StandardLiftables how I could solve this one.
Another way of looking at it:
Say I want to create instances from the following class at compile time with a macro:
abstract class ClassWithValidation {
val predicate: String => Boolean
def validate(s: String) = predicate(s)
}
and I retrieve a functional literal from somewhere else as a variable value:
val predicate = (s: String) => s.startsWith("Hi")
Then I want to simply quasiquote that variable into the construction:
q"""new ClassWithValidation {
val predicate = $predicate
// other stuff...
}"""
But it gives me this error:
Error:(46, 28) Can't unquote String => Boolean, consider providing an
implicit instance of Liftable[String => Boolean]
Normally I can just make such implicit Liftable for a custom type. But I haven't found a way doing the same for a functional literal. Is there a way to do this or do I need to look at it another way?
From what I understand, you're trying to go from a function to an abstract syntax tree that represents its source code (so that it can be spliced into a macro expansion). This is a frequent thing that people request (e.g. it comes up often in DSLs), but there's no straightforward way of achieving that in our current macro system.
What you can do about this at the moment is to save the AST explicitly when declaring a function and then load and use it in your macro. The most convenient way of doing this is via another macro: https://gist.github.com/xeno-by/4542402. One could also imagine writing a macro annotation that would work along the same lines.
In Project Palladium, there is a plan to save typechecked trees for every program being compiled. This means that there will most likely be a straightforward API, e.g. treeOf(predicate) that would automatically return abstract syntax tree comprising the source of the predicate. But that's definitely not something set in stone - we'll see how it goes, and I'll report back on the progress during this year's ScalaDays.

How to reflect types that have an interface of generic, and get that type of generic

My 1st objective is to filter the types based on a specific interface with a generic.
My 2nd objective is to obtain the type of the generic parameter itself.
public UserService : IUserService, IDisposable, IExportableAs<IUserService>
{
...
}
I cannot assume the structure of the class, its interfaces (if any at all) or alike. The only thing I know I am targetting ExportableAs<T> from my shared assembly that was used to create this plugin. But yet, I need to register the type dynamically.
So, I am using a generic interface to mark the type to export. In this case, it's IUserService. I am doing this assuming some nifty Linq query can give me what I want. But, I am having a little trouble.
Here's what I have so far:
assembly.GetTypes()
.Where(t => t.GetInterfaces().Any(i =>
i.IsGenericType &&
i.GetGenericTypeDefinition() == typeof(IExportableAs<>))
).ToList()
.ForEach(t => _catalogs.Add(
new ComposablePart()
{
Name = t.FullName,
Type = t // This is incorrect
})
);
This is working, but notice the comment above for "This is incorrect". This type is the derived class of UserService.
What I need in my end result are:
The generic type pass into the IExportableAs<T> (IUserService in this case)
The derived class type (in this case, UserService)
This question got a good up-vote as it got me close (as you can see above): How to determine if a type implements a specific generic interface type But, I need to go one step further in finding that generic type.
Feel free to mangle my linq above.
Thanks in advance!
Got it
assembly.GetTypes().SelectMany(t => t.GetInterfaces(), (t, i) => new { t, i })
.Where(ti => ti.i.IsGenericType &&
ti.i.GetGenericTypeDefinition() == (typeof(IExportableAs<>)))
.Select(ti => new ComposablePart() {
Name = ti.t.FullName,
Type = ti.i.GetGenericArguments()[0]
});
[Edit] In my excitement, I didn't leave my test program running long enough to throw an Exception on the interface that wasn't generic. Thought the .NET Framework had been especially clever there. Corrected code now that I know it isn't.

What's so great about Func<> delegate?

Sorry if this is basic but I was trying to pick up on .Net 3.5.
Question: Is there anything great about Func<> and it's 5 overloads? From the looks of it, I can still create a similar delgate on my own say, MyFunc<> with the exact 5 overloads and even more.
eg: public delegate TResult MyFunc<TResult>() and a combo of various overloads...
The thought came up as I was trying to understand Func<> delegates and hit upon the following scenario:
Func<int,int> myDelegate = (y) => IsComposite(10);
This implies a delegate with one parameter of type int and a return type of type int. There are five variations (if you look at the overloads through intellisense). So I am guessing that we can have a delegate with no return type?
So am I justified in saying that Func<> is nothing great and just an example in the .Net framework that we can use and if needed, create custom "func<>" delegates to suit our own needs?
Thanks,
The greatness lies in establishing shared language for better communication.
Instead of defining your own delegate types for the same thing (delegate explosion), use the ones provided by the framework. Anyone reading your code instantly grasps what you are trying to accomplish.. minimizes the time to 'what is this piece of code actually doing?'
So as soon as I see a
Action = some method that just does something and returns no output
Comparison = some method that compares two objects of the same type and returns an int to indicate order
Converter = transforms Obj A into equivalent Obj B
EventHandler = response/handler to an event raised by some object given some input in the form of an event argument
Func = some method that takes some parameters, computes something and returns a result
Predicate = evaluate input object against some criteria and return pass/fail status as bool
I don't have to dig deeper than that unless it is my immediate area of concern. So if you feel the delegate you need fits one of these needs, use them before rolling your own.
Disclaimer: Personally I like this move by the language designers.
Counter-argument : Sometimes defining your delegate may help communicate intent better. e.g. System.Threading.ThreadStart over System.Action. So it’s a judgment call in the end.
The Func family of delegates (and their return-type-less cousins, Action) are not any greater than anything else you'd find in the .NET framework. They're just there for re-use so you don't have to redefine them. They have type parameters to keep things generic. E.g., a Func<T0,bool> is the same as a System.Predicate<T> delegate. They were originally designed for LINQ.
You should be able to just use the built-in Func delegate for any value-returning method that accepts up to 4 arguments instead of defining your own delegate for such a purpose unless you want the name to reflect your intention, which is cool.
Cases where you would absolutely need to define your delegate types include methods that accept more than 4 arguments, methods with out, ref, or params parameters, or recursive method signatures (e.g., delegate Foo Foo(Foo f)).
In addition to Marxidad's correct answer:
It's worth being aware of Func's related family, the Action delegates. Again, these are types overloaded by the number of type parameters, but declared to return void.
If you want to use Func/Action in a .NET 2.0 project but with a simple route to upgrading later on, you can cut and paste the declarations from my version comparison page. If you declare them in the System namespace then you'll be able to upgrade just by removing the declarations later - but then you won't be able to (easily) build the same code in .NET 3.5 without removing the declarations.
Decoupling dependencies and unholy tie-ups is one singular thing that makes it great. Everything else one can debate and claim to be doable in some home-grown way.
I've been refactoring slightly more complex system with an old and heavy lib and got blocked on not being able to break compile time dependency - because of the named delegate lurking on "the other side". All assembly loading and reflection didn't help - compiler would refuse to just cast a delegate() {...} to object and whatever you do to pacify it would fail on the other side.
Delegate type comparison which is structural at compile time turns nominal after that (loading, invoking). That may seem OK while you are thinking in terms of "my darling lib is going to be used forever and by everyone" but it doesn't scale to even slightly more complex systems. Fun<> templates bring a degree of structural equivalence back into the world of nominal typing . That's the aspect you can't achieve by rolling out your own.
Example - converting:
class Session (
public delegate string CleanBody(); // tying you up and you don't see it :-)
public static void Execute(string name, string q, CleanBody body) ...
to:
public static void Execute(string name, string q, Func<string> body)
Allows completely independent code to do reflection invocation like:
Type type = Type.GetType("Bla.Session, FooSessionDll", true);
MethodInfo methodInfo = type.GetMethod("Execute");
Func<string> d = delegate() { .....} // see Ma - no tie-ups :-)
Object [] params = { "foo", "bar", d};
methodInfo.Invoke("Trial Execution :-)", params);
Existing code doesn't notice the difference, new code doesn't get dependence - peace on Earth :-)
One thing I like about delegates is that they let me declare methods within methods like so, this is handy when you want to reuse a piece of code but you only need it within that method. Since the purpose here is to limit the scope as much as possible Func<> comes in handy.
For example:
string FormatName(string pFirstName, string pLastName) {
Func<string, string> MakeFirstUpper = (pText) => {
return pText.Substring(0,1).ToUpper() + pText.Substring(1);
};
return MakeFirstUpper(pFirstName) + " " + MakeFirstUpper(pLastName);
}
It's even easier and more handy when you can use inference, which you can if you create a helper function like so:
Func<T, TReturn> Lambda<T, TReturn>(Func<T, TReturn> pFunc) {
return pFunc;
}
Now I can rewrite my function without the Func<>:
string FormatName(string pFirstName, string pLastName) {
var MakeFirstUpper = Lambda((string pText) => {
return pText.Substring(0,1).ToUpper() + pText.Substring(1);
});
return MakeFirstUpper(pFirstName) + " " + MakeFirstUpper(pLastName);
}
Here's the code to test the method:
Console.WriteLine(FormatName("luis", "perez"));
Though it is an old thread I had to add that func<> and action<> also help us use covariance and contra variance.
http://msdn.microsoft.com/en-us/library/dd465122.aspx

Resources