How to Create an Internal DSL in Scala? - scala

I have been looking at a couple of books and resources on domain specific languages.
I think I want to build an internal DSL in Scala.
def instrument = new FXInstrument {
provider = "EuroBase"
instrumentOrders = List(
new FXOrder {
baseCcy = "GBP"
termCcy = "EUR"
legs = List(
new FXLeg {
amountPrice = 100000.0
spotPrice = 1.56
requirements = List(
new FXRequirement {
baseCcy="GBP" termCcy="EUR"
settlement="Banker Rain"
}
)
},
new FXLeg {
amountPrice = 200000.0
spotPrice = 1.50
requirements = List(
new FXRequirement {
baseCcy="GBP" termCcy="EUR"
settlement="Banker Sunny"
}
)
}
)
}
}
Such that following asserts are valid:
instrument.orders(0).baseCcy should equal ("GBP")
instrument.orders(0).termCcy should equal ("EUR")
instrument.orders(0).legs(0).amountPrice should equal 100000.0
instrument.orders(0).legs(0).spotPrice should equal 1.56
instrument.orders(0).legs(1).amountPrice should equal 200000.0
instrument.orders(0).legs(1).spotPrice should equal 1.50
instrument.orders(0).legs(0).requirements(0).settlement should equal "Banker Rain"
instrument.orders(0).legs(1).requirements(0).settlement should equal "Banker Sunny"
I just do not know quite how to implement the domain specific language as an internal representation
1) new FXOrder() { /closure/ }
I like this syntax, is it good or should I prefer companion objects.
For instance I can quickly introduce other FX types easy.
2) I want to use "peers" such FXOrder is a scala.Proxy mixee, thus it uses the trait Proxy (mixin)
For example ``instrument.peer'' gives the internal peer Java Object of the third party proprietary API (a well known financial services trading system, can you guess?)
Ditto for
instrument.orders(0).peer
instrument.orders(0).legs(0).peer
instrument.orders(0).legs(0).requirements(0).peer
and so on.
I realise that domain specific language is not as simple as I thought, however some pointers on this above, would be really be useful. I would appreciate your responses. Ta!
PP

I haven't considered what you want yet, but I saw a problem:
1) new FXOrder() { /closure/ }
No, it doesn't work that way. When you follow an initialization (new Something) with a block, you are doing anonymous subclassing. What you are actually doing is new FXOrder() { /constructor, methods, getters and setters/ }.

Maybe, this can help you: DSL in Scala

Related

How to set the proper data type when writing to an OPC-UA node in Milo?

I am an OPC-UA newbie integrating a non-OPC-UA system to an OPC-UA server using the Milo stack. Part of this includes writing values to Nodes in the OPC-UA server. One of my problems is that values from the other system comes in the form of a Java String and thus needs to be converted to the Node's proper data type. My first brute force proof-of-concept uses the below code in order to create a Variant that I can use to write to the Node (as in the WriteExample.java). The variable value is the Java String containing the data to write, e.g. "123" for an Integer or "32.3" for a Double. The solution now includes hard-coding the "types" from the Identifiers class (org.eclipse.milo.opcua.stack.core, see the switch statement) which is not pretty and I am sure there is a better way to do this?
Also, how do I proceed if I want to convert and write "123" to a node that is, for example,
UInt64?
try {
VariableNode node = client.getAddressSpace().createVariableNode(nodeId);
Object val = new Object();
Object identifier = node.getDataType().get().getIdentifier();
UInteger id = UInteger.valueOf(0);
if(identifier instanceof UInteger) {
id = (UInteger) identifier;
}
System.out.println("getIdentifier: " + node.getDataType().get().getIdentifier());
switch (id.intValue()) {
// Based on the Identifiers class in org.eclipse.milo.opcua.stack.core;
case 11: // Double
val = Double.valueOf(value);
break;
case 6: //Int32
val = Integer.valueOf(value);
break;
}
DataValue data = new DataValue(new Variant(val),StatusCode.GOOD, null);
StatusCode status = client.writeValue(nodeId, data).get();
System.out.println("Wrote DataValue: " + data + " status: " + status);
returnString = status.toString();
} catch (Exception e) {
System.out.println("ERROR: " + e.toString());
}
I've looked at Kevin's response to this thread: How do I reliably write to a OPC UA server? But I'm still a bit lost... Some small code example would really be helpful.
You're not that far off. Every sizable codebase eventually has one or more "TypeUtilities" classes, and you're going to need one here.
There's no getting around that fact that you need to be able to map types in your system to OPC UA types and vice versa.
For unsigned types you'll use the UShort, UInteger, and ULong classes from the org.eclipse.milo.opcua.stack.core.types.builtin.unsigned package. There are convenient static factory methods that make their use a little less verbose:
UShort us = ushort(foo);
UInteger ui = uint(foo);
ULong ul = ulong(foo);
I'll explore that idea of including some kind of type conversion utility for an upcoming release, but even with that, the way OPC UA works you have to know the DataType of a Node to write to it, and in most cases you want to know the ValueRank and ArrayDimensions as well.
You either know these attribute values a priori, obtain them via some other out of band mechanism, or you read them from the server.

How to combine the elements of an arbitrary number of dependent Fluxes?

In the non reactive world the following code snippet is nothing special:
interface Enhancer {
Result enhance(Result result);
}
Result result = Result.empty();
result = fooEnhancer.enhance(result);
result = barEnhancer.enhance(result);
result = bazEnhancer.enhance(result);
There are three different Enhancer implementations taking a Result instance, enhancing it and returning the enhanced result. Let's assume the order of the enhancer calls matters.
Now what if these methods are replaced by reactive variants returning a Flux<Result>? Because the methods depend on the result(s) of the preceding method, we cannot use combineLatest here.
A possible solution could be:
Flux.just(Result.empty())
.switchMap(result -> first(result)
.switchMap(result -> second(result)
.switchMap(result -> third(result))))
.subscribe(result -> doSomethingWith(result));
Note that the switchMap calls are nested. As we are only interested in the final result, we let switchMap switch to the next flux as soon as new events are emitted in preceding fluxes.
Now let's try to do it with a dynamic number of fluxes. Non reactive (without fluxes), this would again be nothing special:
List<Enhancer> enhancers = <ordered list of different Enhancer impls>;
Result result = Result.empty();
for (Enhancer enhancer : enhancers) {
result = enhancer.enhance(result);
}
But how can I generalize the above reactive example with three fluxes to deal with an arbitrary number of fluxes?
I found a solution using recursion:
#FunctionalInterface
interface FluxProvider {
Flux<Result> get(Result result);
}
// recursive method creating the final Flux
private Flux<Result> cascadingSwitchMap(Result input, List<FluxProvider> fluxProviders, int idx) {
if (idx < fluxProviders.size()) {
return fluxProviders.get(idx).get(input).switchMap(result -> cascadingSwitchMap(result, fluxProviders, idx + 1));
}
return Flux.just(input);
}
// code using the recursive method
List<FluxProvider> fluxProviders = new ArrayList<>();
fluxProviders.add(fooEnhancer::enhance);
fluxProviders.add(barEnhancer::enhance);
fluxProviders.add(bazEnhancer::enhance);
cascadingSwitchMap(Result.empty(), fluxProviders, 0)
.subscribe(result -> doSomethingWith(result));
But maybe there is a more elegant solution using an operator/feature of project-reactor. Does anybody know such a feature? In fact, the requirement doesn't seem to be such an unusual one, is it?
switchMap feels inappropriate here. If you have a List<Enhancer> by the time the Flux pipeline is declared, why not apply a logic close to what you had in imperative style:
List<Enhancer> enhancers = <ordered list of different Enhancer impls>;
Mono<Result> resultMono = Mono.just(Result.empty)
for (Enhancer enhancer : enhancers) {
resultMono = resultMono.map(enhancer::enhance); //previousValue -> enhancer.enhance(previousValue)
}
return resultMono;
That can even be performed later at subscription time for even more dynamic resolution of the enhancers by wrapping the whole code above in a Mono.defer(() -> {...}) block.

Angular 2 creating models vs working with json objects on the fly?

when interacting with a rest api using Angular 2. Is it worth creating typescript classes for each object (eg. employee, company, project, user ...). the other option is getting json object and working with it on the fly ?
i suggest using models because :
your code will be more readable for yourself after a while coming back to change it, every one else also can easily understand what you've done
making changes in project will be more easily for example obj[0] does not have any special meaning but obj['username'] is more obvious
you will get intellinsense in you IDE
you can put logic in model for example so your controller will be more thin
name: string
age: number
sayInfo(): string {
return `name is ${this.name} and age is ${this.age}`
}
generally managing you app will be without headache (or at least less headache) :D
just remember that fat models thin controllers
don't forget that passing more than five arguments to a function is not a good practice use an object instead for example :
constructor(file) {
this.id = file['id']
this.fileName = file['fileName']
this.extention = file['extention']
this.fileSize = file['fileSize']
this.permission = file['permission']
this.description = file['description']
this.password = file['password']
this.isFolder = file['isFolder']
this.parent = file['parent']
this.banStat = file['banStat']
this.tinyLink = file['tinyLink']
}
getName(): string {
return `${this.fileName}${(this.isFolder) ? '' : '.'}${this.extention}`
}
getIcon(): string {
return this.isFolder ? 'fa-folder' : 'fa-music'
}

how to build a REST hierarchy using spyne

I am trying to build a REST web service using spyne. So far I have been able to use ComplexModel to represent my resources. Something very basic, like this (borrowed from the examples):
class Meta(ComplexModel):
version = Unicode
description = Unicode
class ExampleService(ServiceBase):
#srpc(_returns=Meta)
def get_meta():
m = Meta()
m.version="2.0"
m.description="Meta complex class example"
return m
application = Application([ExampleService],
tns='sur.factory.webservices',
in_protocol=HttpRpc(validator='soft'),
out_protocol=JsonDocument()
)
if __name__ == '__main__':
wsgi_app = WsgiApplication(application)
server = make_server('0.0.0.0', 8000, wsgi_app)
server.serve_forever()
To run I use curl -v "http://example.com:8000/get_meta" and I get what I expect.
But what if I would like to access some hierarchy of resources like http://example.com:8000/resourceA/get_meta ??
Thanks for your time!
Two options: Static and dynamic. Here's the static one:
from spyne.util.wsgi_wrapper import WsgiMounter
app1 = Application([SomeService, ...
app2 = Application([SomeOtherService, ...
wsgi_app = WsgiMounter({
'resourceA': app1,
'resourceB': app2,
})
This works today. Note that you can stack WsgiMounter's.
As for the dynamic one, you should use HttpPattern(). I consider this still experimental as I don't like the implementation, but this works with 2.10.x, werkzeug, pyparsing<2 and WsgiApplication:
class ExampleService(ServiceBase):
#rpc(Unicode, _returns=Meta, _patterns=[HttpPattern("/<resource>/get_meta")])
def get_meta(ctx, resource):
m = Meta()
m.version = "2.0"
m.description="Meta complex class example with resource %s" % resource
return m
Don't forget to turn on validation and put some restrictions on the resource type to prevent DoS attacks and throwing TypeErrors and whatnot. I'd do:
ResourceType = Unicode(24, min_len=3, nullable=False,
pattern="[a-zA-Z0-9]+", type_name="ResourceType")
Note that you can also match http verbs with HttpPattern. e.g.
HttpPattern("/<resource>/get_meta", verb='GET')
or
HttpPattern("/<resource>/get_meta", verb='(PUT|PATCH)')
Don't use host matching, as of 2.10, it's broken.
Also, as this bit of Spyne is marked as experimental, its api can change any time.
I hope this helps

Test if property exists on a class at runtime

Something like this:
##class(MyApp.MyClass).%HasProperty("SomeProperty").
I looked into doing something like this:
set classDefinition = ##class(%Dictionary.CompiledClass).%OpenId(%class.Name)
and then looping through the Properties, however, I need to be able to use any class, not just %class
For a simple OO approach, you can use the following API:
Set tPropExists = ##class(%Dictionary.CompiledProperty).IDKEYExists("SomeClass","SomeProperty")
This should have much less runtime cost than loading the class definition data and looping over its properties (and thus loading the data for those properties as well).
If you still want to create a %HasProperty() helper method for your application classes, you can use the following base method (assuming you are on Cache 2010.2 or higher - I believe the $this special variable and the $classname() function were added in 2010.2, but that may have been in 2010.1.):
ClassMethod %HasProperty(pPropName As %String = "") As %Boolean
{
Set tHasProp = 0
If (pPropName '= "") {
Set tHasProp = ##class(%Dictionary.CompiledProperty).IDKEYExists($classname($this),pPropName)
}
Quit tHasProp
}
You also might want to use a generator method (one of the really nice features in Cache objects) if run-time speed is important to you.
For example:
Method PropertyExists(Name) As %Boolean [ CodeMode = generator, ProcedureBlock = 1, ServerOnly = 1 ]
{
Set %code=0
S ClassDef=##class(%Dictionary.CompiledClass).%OpenId(%class)
i '$IsObject(ClassDef) $$$GENERATE(" Q 0") Q $$$OK
I '$IsObject(ClassDef.Properties) $$$GENERATE(" Q 0") Q $$$OK
S Key="" F S Key=ClassDef.Properties.Next(Key) Q:Key="" D
. S CompiledProperty=ClassDef.Properties.GetAt(Key)
. $$$GENERATE(" I Name="""_CompiledProperty.Name_""" Q 1" )
$$$GENERATE(" Q 0")
q $$$OK
}