Closed
Description
Although we can declare every Either
-like union types to represent successful/failed result of methods, there are several downsides:
- As Nirum currently doesn't have generics, we need to declare many lookalike union types.
- Although some programming languages having algebraic data type (e.g. Haskell, Rust, Swift) tend to deal with errors through
Either
-like union type, such approach to represent errors is not that natural to many programming languages having exceptions (e.g. Java, Python, JavaScript). It would be great if errors can be dealt in the most natural way of each programming language.
If service methods can have an error type alongside of a return type errors can be dealt in multiple ways so that each language target choose its own translation to represent errors in the most natural way of the language.
For example:
union image-lookup-error = missing-image | moderated-image (text reason);
service image-service (
hash upload (blob image),
uri lookup (hash image-hash): image-lookup-error,
);
(The : error-type
syntax is just a pseudocode.) The the above code can be compiled to Haskell using Either
monad:
data ImageLookupError = MissingImage | ModeratedImage { reason :: Text } deriving (Eq, Ord, Show)
class ImageService s where
upload :: s -> ByteString -> Hash
lookup :: s -> Hash -> Either ImageLookupError URL
whereas be compiled to Java using checked exceptions:
// Of course, we need to annotate so that Java target compile `image-lookup-error` to a class subclassing `Exception`.
final public class ImageLookupError extends Exception {}
final public class MissingImage extends ImageLookupError {}
final public class ModeratedImage extends ImageLookupError {
final protected String reason;
public ModeratedImage(final String reason) {
super();
this.reason = reason;
}
// omit other overloaded constructors...
public String getReason() {
return reason;
}
}
public interface ImageService {
public Hash upload(final byte[] image);
public URI lookup(final Hash imageHash) throws ImageLookupError;
}