Notice how a client operations are all !
, then ?
, then client
.
type mathClient = +{
max: !integer.!integer.?integer. mathClient,
isZero: !integer.?boolean. mathClient,
quit: end
}
new client server : mathClient
client select isZero. client!5. client?b.
printStringLn!"Got "++b++"!".
client select max. client!-5. client!3. client?n.
printStringLn!"This time got "++n+"!".
client select isZero. client!-3. client?b.
printStringLn!"And now "++b++"!".
client select quit
Server operations are the dual:
type mathServer = &{
max: ?integer.?integer.!integer. mathServer,
isZero: ?integer.!boolean. mathServer,
quit: end
}
It's more natural to me to express that in a more object-like way:
object mathServer = {
max: (integer, integer) -> integer,
isZero: integer -> boolean,
quit: end,
}
main = do
new server : mathServer
b <- server.isZero 5
printStringLn ("Got " ++ b ++ "!")
n <- server.max -5 3
printStringLn ("This time got " ++ n ++ "!")
b <- server.isZero -3
printStringLn ("And now " ++ b ++ "!")
server.quit