My sunday project was to write some primitives of a Lisp-like interpreter using DSS Service Components. The core interpreter was derived from my previous work on AjLisp, a Lisp interpreter (I had never published the code before). I write it using Visual Studio 2008 and the CTP v2.0 of Microsoft Robotics Developer Studio. I published the code on my Skydrive space as DssLisp.zip.
It has two projects: a class library named AjLisp (a revamped version of my original interpreter in VB.NET):
and a C# Dss Service project, with has many implemented service components:
It has no manifest. It is designed to use from VPL diagrams.
Most of these components receive or return SymbolicExpression, the base type of my interpreter. See the messages for Rest service Execute operation:
To use this components, you must adjust the references and directories in the DSS project (it points to my local directories, and to my local Microsoft Robotics Developer Studio install).
There are three VPL programs included in the examples. They use the compiled components of the solution. I had a problem with these VPL programs. I couldn’t run them from the menu option Run. You must use Build -> Compile as a Service, and then, use the option Run -> Run Compiled Services. I guess the origin of the problem is that the diagrams maps special messages, not only primitive types or Strings. In order to successful compile, you must adjust the properties of diagrams in each VPL project:
The first one DssLispVpl1 calculate (first ‘(a b c)):
There are two components LispParser and LispToString, that help to convert from string to SymbolicExpression and from SymbolicExpression to string.
The second one is DssLispVpl2:
It uses LispAppend component to append two predefined lists.
The third one is a mini-interpreter DsspLispInterpreter:
I must improve the error treatment. Now, if an exception occurs inside the service process, no Fault response is generated, and a causality is raised.
I could implement some generic contracts, and reuse it in many components, for example, a GenericBinaryOperation component.
I failed to write an Activity, to implement a Reverse function. The activity called itself recursively, but the generated code returns at the last recursive invocation. The problem is caused by my use of a merge to return a value. It’s weird to explain clearly, after some hours trying to do the job, I abandoned the code. Another stone in the way was the fact that activities only accept predefined types in its messages and results. But in this case, I found a solution: generate the code, and modified the generated solution to accept my SymbolicExpression type as inputs and outputs.
One interesting thing I wrote, is the component Uncons, that has TWO expressions in its result response: it takes a list, and returns the first and the rest of that list. Having two members in the response, you can processes each one in parallel branchs of the diagram.
As in previous posts, I found the VPL orchestration as very powerful and interesting, but lacks the support of a generic object, and has problems to manage custom types. I think you can implements any functional languages primitives and make a VPL diagram for each program you want. VPL would have problems with recursion (or I didn’t found a workable solution to manage it). This exercise could be expanded to other ideas:
- Manage a pipeline processing a generic message (I discovered that we can have a generic object as a DataMember)
- Have load balance as a component
- Serialize/Deserialize objects between nodes
- Implement some workflow or application intergration patterns in VPL
Angel “Java” Lopez