Rascal Using the webserver module - rascal

I'm currently working on the stable version of Rascal and I want to spawn the Rascal webserver to serve my html templates with javascript functions.
Looking at the Webserver module I can't see how to use the serve function to use the webserver. It asks for a location (I'm assuming that the location would be something like |http://localhost:8080|) and a callback that has the type of Response (Request) but what is that type? I don't know how to create this kind of type and what it exactly is.

The type Response (Request) callback is a function, E.g.:
Response (Request r) {
return response(...);
}
This function is an anonymous function (it has no name) that you can pass into the serve function as an argument, you can also define it as a normal function with a name, and just put the name of that function as the argument.
So this would probably work:
serve(|http://localhost:8080|,
Response (Request r){
return response("Hello world");
}):
Since there is a factory method Response response(str content) in Webserver.rsc, that will create a response for you from a string argument.

In the absence of documentation about this module, all you can do is read the source. In the Eclipse browser, the libraries are accessible (indicated by little jar icons) and you'll find util::Webserver there with the definition of the Response and Request types.
Basically Request is a callback function with all the HTTP headers and stuff as parameters and Response is a wrapper with alternative response types (files, strings, etc.).
Note that the current version is quite a bit different from the stable version you use, so reading code on github will not help much.

Related

Can I omit the class name when calling a static method?

In F#, can I omit the class name when calling a static method?
Example:
In C#, I can do something like:
using static Bizmonger.Patterns.MessageBus;
...
Publish("SOME_MESSAGE");
instead of:
MessageBus.Publish("SOME_MESSAGE");
Can I do something like this in F#?
In F#, you can use open on namespaces (just like using in C#) or on modules (which is useful when the API you are calling has been written in F#), but not on static classes (which is what you'd need when calling C# libraries).
One thing that you can do though to make the code a bit shorter is to define a type alias:
type M = Bizmonger.Patterns.MessageBus;
// Now you can write just
M.Publish("SOME_MESSAGE")
// Rather than writing the full
MessageBus.Publish("SOME_MESSAGE");
There is a feature request on the F# UserVoice to allow using open on static classes (just like in C#) and so if you'd like this to happen, please upvote and comment there.
I also learned that I could implement a function to serve as a wrapper for clients to call instead.
Create a wrapper function
module Messages
open Bizmonger.Patterns
let Publish (message:string, payload:_) =
MessageBus.Publish(message, payload)
Client
Then a client can now invoke a function without specifying a class name.
open Messages
...
Publish("SOME_MESSAGE", null);

Using type from F# host via Ajax in FunScript JS code

How do I use types declared in my host project and served over Ajax in the generated FunScript code?
For example I lets say I declare a type T and then create a REST endpoint serving data in that format. Now if I want to load the data and use it from FunScript its no longer type T.
Edited with solution based on Alfanso's answer:
Assuming type "MyType" is defined in the base F# project and data matching this type served on localhost:6543/myData
let start () =
async{
let url = "http://localhost:6543/myData"
let req = System.Net.WebRequest.Create(url)
let! data = req.AsyncGetJSON<MyType list>()
Globals.window.alert( (sprintf "%A" data) )
}
|> Async.StartImmediate
What I was missing was
req.AsyncGetJSON
Use Async.StartImmediate
Could you please post some code to see better what you're exactly trying to do? For reference, you can see an example of how to exchange type-safe JSON values using FunScript.HTML extensions in this little project. In this case:
Types are shared between server, client and database using F# records with CLIMutable and System.Data.Linq.Mapping.Table attributes: Source
For the server, I'm using ASP.NET Web API which send types as JSON transparently: Source
In the client, I'm using the WebRequest.AsyncGetJSON<'T> extension from FunScript.HTML, which in the background just issue a XMLHttpRequest, parses the result with the browser JSON.parse method and uses unbox<'T> to "cast" the object to the desired type: here, here and here.
unbox<'T> is the little trick you'll often have to use if you want to use dynamic types in a statically-typed manner in F#.
I hope this helps!

dart, reflection and source maps?

I have a proxy object which uses noSuchMethod to relay invocations to other objects, but the proxy object exists in a minified/obfuscated environment, and the objects it relays the invocations to are in a non-minified/obfuscated state, so when the name of the method being called reaches the non-minified environment the names don't match up, I have the myFile.dart.js.map file, is there a simple algorithm to parse this and get the original invocation name back from the minified name using the source maps? or even better is there a library that already does this in dart?
You can use MirrorSystem.getName to get the real name of a symbol. In the case of noSuchMethod :
noSuchMethod(Invocation invocation) {
String member = MirrorSystem.getName(invocation.memberName);
}

How to get concrete object of a static method via mirror API?

I have something like this:
class MyClass
{
static void DoSomething(arg1, arg2){...}
}
Via reflection, I am able to get the ClassMirror of this class. From this point, how would I get to the concrete static function so I can call it.
Note that I tried to use:
ObjectMirror.invoke('DoSomething', [arg1, arg2]);
which would initially appear to work, but it doesn't support passing of complex types as arguments, This static function requires a complex type as one of it's arguments.
Ideally, I'd like to get the 'Function' object that represents the static method so I can invoke it directly.
a. The current state of affairs is temporary. The plan is that the mirror API will wrap the arguments with mirrors for you.
b. The API may eventually support a getProperty method that will give you a Future on the function object. However, you will not get a Function object directly, so this won't really make any difference in this case.
c. The core idea is that the API fundamentally works on mirrors. To make it more usable, it should accept non-mirrors as input and wrap them in mirrors for you. It will always return mirrors, and in some cases return futures on these. This is so the API works the same for remote and local cases.
d. Resources for understanding mirrors:
http://www.bracha.org/mirrors.pdf (academic paper, tough going)
http://www.hpi.uni-potsdam.de/hirschfeld/events/past/media/100105_Bracha_2010_LinguisticReflectionViaMirrors_HPI.mp4 (a video, pre-Dart, discusses earlier Mirror systems)
http://gbracha.blogspot.com/2010/03/through-looking-glass-darkly.html (an old, pre-dart, blog post of mine on mirrors)
http://www.wirfs-brock.com/allen/posts/228 (Allen Wirfs-Brock's blog. Allen was a mirror pioneer back in Smalltalk in the 90s)
http://www.wirfs-brock.com/allen/posts/245
You can also search my blog, or Allen Wirf-Brock's for posts on the topic.

ASMX web service, external WSDLs *without* wsdl.exe

I'm working on some legacy code, and I need an asmx to implement a particular wsdl, which is being provided to me.
I would like to receive the root element of the message as either an XmlDocument or XmlNode, rather than the wsdl.exe generated object graph. Is this even possible?
First of all, you should use svcutil.exe, not wsdl.exe, unless you have no other choices.
Second, you don't need either program to implement an external WSDL. Just go write your service so that the XML Serializer will properly serialize and deserialize the incoming message. In particular, if you like processing XML, try this:
[WebMethod]
public XmlElement SomeOperation(XmlElement parameter)
{
}
I believe that the same works with the newer XElement class.
In WCF (which is what you should be using, since Microsoft now considers ASMX web services to be "legacy technology"), I believe you should use the Message type:
[OperationContract]
Message SomeOperation(Message parameter);

Resources