== Matching == Prefer named arguments:: When matching a uniontype, prefer using named arguments to only match what is used. A match using named arguments only needs to be changed if the matched fields change in a uniontype, while a match using positional arguments will always have to be changed if the uniontype changes. {{{#!mo // Prefer this. case DAE.ARRAY(ty = DAE.T_REAL()) // Not this. case DAE.ARRAY(DAE.T_REAL(), _, _) }}} Use {{{else}}} for catch-all:: Prefer using {{{else}}} when writing a catch-all case: {{{#!mo outValue := match(inExp1, inExp2) case (DAE.ICONST(), DAE.ICONST()) then inExp1.integer + inExp2.integer; else 0; // Avoid this: case (_, _) then 0; // And this (using 'then' is legal, but unnecessary): else then 0; end match; }}} Use {{{as}}} only for partial matches:: {{{as}}} is usually not necessary when matching a whole input argument, such as this: {{{#!mo _ := match(inExp, inStr) local DAE.Exp exp; String str; case (exp as DAE.CALL(path = Absyn.IDENT("sum")), _) then ExpressionDump.printExpStr(exp); case (_, str as "someString") then str; end match; }}} Prefer using the input parameters directly instead: {{{#!mo outStr := match(inExp, inStr) case (DAE.CALL(path = Absyn.IDENT("sum")), _) then ExpressionDump.printExpStr(inExp); case (_, "someString") then inStr; end match; }}} == Error Handling == Use the appropriate method to handle errors:: For errors that are of interest to the user, use one of the Error.addXXXMessage functions to print an error/warning message. Always supply the source info when posssible, i.e. prefer using addSourceMessage or addMultiSourceMessage. For cases where it might be of interest to the developers if a function fails, use failtrace and Debug.traceXXX: {{{#!mo if Flags.isSet(Flags.FAILTRACE) then Debug.traceln("- Foo.bar failed!"); end if; }}} For functions that should never fail, use internal errors: {{{#!mo function foo input Integer inN; algorithm if inN < 0 then Error.addInternalError("Negative number given to foo!", sourceInfo()); end if; end foo; }}} Only print internal errors as a last resort:: Internal errors should only be used when something has gone really wrong, and ideally they should never be shown to users. In many cases it's therefore appropriate to check that some other error hasn't already been printed before printing an internal error: {{{#!mo function foo ... protected Integer err_count = Error.getNumErrorMessages(); algorithm try // Something which can fail, and might or might not print an error message if it does fail. else // Only print an internal error if the above code failed without printing an error message. if err_count == Error.getNumErrorMessages() then Error.addInternalError(...); end if; end try; end foo; }}}