Ok, this is an advanced, more complex topic. Let me see if I can find a way to explain it properly. Bare with me, you'll need some patience;) Let me assure you: it's worth it. You will see the light;) Hopefully. Maybe also wrong to explain all that here on the issue tracker for connectanum-dart. It'll be long, multiple comments. Anyways, here we go.
Intro and the Why?
WAMP was designed along a dynamic typing discipline from the beginning (eg even in WAMPv1). This was a deliberate and conscious decision, and it has served us (the WAMP community) well .. I'd say.
What that means is: WAMP application payload in RPC call arguments/results and PubSub events can transport any args
(positional payload) and kwargs
(keyword payload).
Full run-time dynamic typing has advantages (very flexible, no-frills get started right away, etc), but - as with anything - there is a price to pay.
The price to pay comes in different shapes.
Robustness
Robust app code will need quite a lot of run-time checks. eg say you have a registered WAMP procedure proc add2(a, b)
that returns the (numeric?) sum of a and b (two positional args). what if the caller calls your proc with a=="foo"
and b==666
?
JS, being a duck, will happily return foo666
. most of the time this won't be matching what neither the caller nor the callee had in mind.
so you would continue adding "run-time checks" to the implementation of add2
. as in: "if type(a) != int then raise .."
This can get boring quite quick, and of course is error prone. did you really check everything? what if the caller send three positional args? etc etc
Code scalability
With one developer doing both sides of a WAMP API, eg the app code for the caller and callee, or the publisher and the subscriber, everything is in the head of 1 person, and fixing stuff and making sure it matches up is straight forward and natural. You can do it.
Now, what if you have 10 developers? In one organization this can get tricky to manage already. If you have developers of different parties involved, it quickly turns into a big problem and time sucker. Was it a,b being ints or also floats? Ah, you changed it, so now it's a,b,c?
How do you even communicate what one side (eg callee) did intend anyways? Is it communicated in a way that even gives the other side (eg caller) a chance to do the right thing?
Documentation
Ok, so now your problem becomes: add2 (the callee side) must have proper docs. Sure, dream on! ;) The problem is manyfold: can you even precisely write natural language docs? even if so on day 1, now add2 changes. Surely, updating the docs is forgotten. Now the situation is even worse: there is docs, but they are wrong. So a caller that wants to do its best can't even. And so on. Wrong docs is worse than no docs.
How to ensure that a proc that claims in the docs it takes exactly 2 positional args of type int does indeed at the technical level?
Statically typed host languages
Dealing with dynamic types and data in statically typed host languages always incurs some form of impedance mismatch. Kinda expected.
Also, when working in such a language, you naturally want native language static types for your app level objects.
Eg say you have
public class Person {
public String firstname;
public String lastname;
public String department;
public Person() {
this.firstname = "unknown";
this.lastname = "unknown";
this.department = "unknown";
}
public Person(String firstname, String lastname, String department) {
this.firstname = firstname;
this.lastname = lastname;
this.department = department;
}
}
in your app.
Now, wouldn't it be great if you could do (pseudocode):
Person someone = await session.call("com.example.get_last_customer");
print(someone.lastname)
Performance
WAMP supports multiple, pluggable serialization formats (JSON, MsgPack, CBOR, ...) and routers transparently convert between those (roundtripping). Very useful, all cool. We have that today. However ..
- In Crossbar.io, CPU cycles spent in dealing with this are top 1 and dominate (besides WebSocket low-level processing)
- WAMP clients also have to serialize/deserialize the whole payload even if they only need access to a tiny part of the payload (eg thing of a single attribute in a deeply nested dict)
- further, this is not only about CPU cycles, but also (and even more important) about memory and memory pressure. Dynamic typing is .. dynamic also allocation wise. By nature.
There are more problems .. I stop here;)