-
Notifications
You must be signed in to change notification settings - Fork 0
Symbols Guide
It is mostly about syntactic sugar for Catch/Throw to cope well with Messages/Failures.
Basic rules:
-
MGenerate,MGenerateAll,MThrow,MThrowAllhave the same syntax with respect to Message/Failure related cases.-
-Allmeans that aMessagewill be issued too. That also implies only a valid message input can be used while simpleMThrowcan accept whatever input you give it. -
Generatejust creates e.g. aFailurewhileMThrowthrows is to a nearest enclosingMCatch.
-
MThrow can take Message syntax with optional first element which will be a Failure's tag.
MCatch[ MThrow["500", General::invty, Method] ]
Failure["500", <|"MessageTemplate" :> General::invty, "MessageParameters" -> {Method}|> ]
Replace MThrow with MThrowAll and a message will be issued.
Below is a more detailed symbols guide:
MFailureQ /@ {
$Failed, $Aborted, $Canceled, Failure["any","Message"->"Generic message"]
}
{True,True,True,True}
Basic usage:
MGenerateAll[General::argt,foo,2,3,4]General::argt: foo called with 2 arguments; 3 or 4 arguments are expected.
Failure["argt", <| "MessageTemplate" :> General::argt, "MessageParameters" -> {foo, 2, 3, 4} |> ]
Use custom tags for a more fine grained control flow:
MCatch @ MThrow["custom tag",General::argt,foo,2,3,4]
Failure["custom tag", <|"MessageTemplate" :> General::argt, "MessageParameters" -> {foo, 2, 3, 4}|>]
Association/Failure oriented syntax:
MCatch @ MThrow[foo::argx, <|"arg"->bar|>]
Failure["argx", <|"MessageTemplate" :> foo::argx, "MessageParameters" -> <|"arg" -> bar|>|>]
Adding payload can be invaluable for complex flow:
MCatch @ MThrow[
"custom tag"
, General::argt
, foo,2,3,4
, <|"Payload"->"additional information"|>
]
Failure[ "custom tag" , <|"MessageTemplate" :> General::argt , "MessageParameters" -> {foo, 2, 3, 4} , "Payload" -> "additional information" |> ]
More idiomatic approach to If[Test @ expr, exception @ expr, expr]:
MCatch[
$Aborted // MHandleResult[]; 1
]
Failure["err", <|"Message" -> "$Aborted"|>]
MCatch[
NotAString[] // MHandleResult[
Except[_String] , Function[res, MThrow[foo::string, Head[res], _String]]
]
]
Failure["string", <|"MessageTemplate" :> foo::string, "MessageParameters" -> {NotAString, _String}|> ]
More idiomatic approach to If[ FailureQ[expr], handler @ expr, expr]:
$Failed // MOnFailure[foo]
foo[$Failed]
MCatch[ $Failed // MOnFailure[MThrow] ]
$Failed
There is a shorter version for throwing though:
MCatch[ $Failed // MThrowOnFailure ]
$Failed
I find unevaluated expressions hard to manage with respect to flow control so I would like always to get a Failure:
foo[x_]:=x^2;
foo // MFailByDefault;
foo[1,2]foo::argpatt: There are no rules associated with signature foo[Integer, Integer].
Failure["argpatt", <|"MessageTemplate" :> foo::argpatt, "MessageParameters" -> {"foo[Integer, Integer]"}|>]
The idea behind those utilities originates from https://mathematica.stackexchange.com/q/116571/5478
MValidate[
<|"a" -> <|"b" -> 2, "c"->3, "d" -> 4|>|>
, KeyValuePattern[{"a" -> KeyValuePattern[{"b" -> _Integer, "c" -> _Integer, "d" -> _Integer}]}]
]
True
MInvalidContents[
<|"a" -> <|"b" -> 2, "c" -> 3|>|>
, KeyValuePattern[{
"a" -> KeyValuePattern[{"b" -> _Integer, "c" -> _String, "d" -> _List}]
}]
] { {Key["a"], Key["c"]} -> MValidationResult[False, Integer] , {Key["a"], Key["d"]} -> MValidationResult[False, Missing[]] }
foo // ClearAll
$fooPatt = KeyValuePattern[{"a" -> _Integer, "c" -> _String}];
foo // MValidateByDefault[ $fooPatt ]
foo[ in: $fooPatt]:= in["a"]
foo @ <|"a" -> 1, "c" -> "c"|>
foo @ <|"b" -> 1, "c" -> {1}|>
1
foo::InvalidArg: Argument No. 1 has invalid structure at:
{Key[c]} List
{Key[a]} Missing[]
It needs to match:
<|a -> _Integer, c -> _String|>
Failure[...]
Module[{x = 1, y = 2, z = "string"}, ToKeyValue @ {x,y,z}]
{"x" -> 1, "y" -> 2, "z" -> "string"}