rslc compiler.
E-LOOKUP-TOTAL
State a lookup’s default in the table.E-LOOKUP-TOTAL guards against a lookup that carries a default value of its own. RSL source spells a lookup one way, lookup!(Table, key, …), which takes keys alone, so rslc check leaves this code unprinted.
A table states the row for all other keys with otherwise [cite: …]: { … }. A lookup that can reach a key with a missing row gets E-LOOKUP-GAP.
E-ENTITY-REL
Give each record one enclosing record. A record that contains another is its parent, and the contained record is its child. The check asks that each link runs both ways: the child of a record names that record as its parent. The compiler derives both directions from the field types, so a rater written in current forms keeps them in step. The message appears when a second problem leaves a record with two candidate parents, and it arrives together with the message for that problem. Fix that one and both clear. The words[children] and [parent] in the message are the annotations of an earlier version of RSL. Read them as “contains” and “is contained by”.
Example
Policy and Branch each contain a Location, so Location has two enclosing records.
E-RECORD-POSITION advises. The two types share the same fields.
[parent] and gives it a type other than the enclosing record, such as policy: Option(Policy) [parent]. That rater gets E-RELATION-REMOVED as well: delete the field and read the enclosing record by its name.
Complete files
Complete files
bad/rater.rsl
good/rater.rsl
E-AXIS-SUBSET
Give each map key one declaration. A map holds one value for each member of its enum, such as a rate for each coverage. The check asks that exactly one declaration states the value of each key. Earlier versions of RSL built a map from several declarations, each over part of the keys. Two of them could claim the same key, and this message names that key. RSL 0.4 gives a map one declaration, so the message always arrives withE-AXES-REMOVED for the second declaration.
One declaration that chooses with match c shows every key’s value in one place, and the compiler checks that each key has an arm.
Example
The map rate is declared for every Coverage and again for FirstParty, so two declarations claim property.
match c arm. Delete the refined enum once it has become unused.
rate[c: Coverage] and rate[p: Peril]. That rater gets E-MERGE-FIDELITY as well. Give the second map its own name.
Complete files
Complete files
bad/rater.rsl
good/rater.rsl
E-HOLE
Replace a placeholder with a calculation. A placeholder,nl "…", holds a calculation that is still written in plain words. E-HOLE is the code for a value that depends on a placeholder. rslc check reports the placeholder itself, on a line that starts obligation: 25, and leaves E-HOLE unprinted.
A placeholder lets you sketch a rater and fill it in step by step. rslc check --allow-incomplete accepts a rater whose only open findings are placeholders. The strict check fails until each one is RSL, and rslc export refuses a rater whose outcomes depend on one.
Example
The calculation premium is a placeholder that describes the rule in words.
Complete files
Complete files
bad/rater.rsl
good/rater.rsl
E-ROUND-INC
Round to a scale and a mode.E-ROUND-INC is reserved for a rounding increment that is malformed, as in the removed form round(x, 0.01). rslc check reports every rounding problem as E-ROUND, and that message gives the current form: round(x, 2, half_up).
E-TABLE-MODE
Declare a table with dims and bands. Earlier versions of RSL declared a table as( … ) -> { … } with a match: line. A range table matched a number against a pair of minimum and maximum columns. RSL 0.4 has one table form: table dims (key: Type, …) -> { outputs }.
In that form each key cell is exact, and a range is a band type declared in Types. IntBands(0, 250000, 1000000..) lists the lower cut of each band, and the CSV holds one row for each cut.
With the cuts in the type, the compiler proves that every payroll the rater accepts falls in one band.
Example
The table PayrollRate uses the removed signature, NumRange and match: range over a minimum and a maximum column.
Types and key the table with them. Delete the match: and columns: lines, and keep one CSV column that holds each band’s lower cut.
- A
table dimstable still has amatch:line. Delete the line. - A table has the
( … ) -> { … }signature withmatch: specific, or with thematch:line left out. Writetable dimsbefore the keys. - An input or a table key has the type
NumRange. Declare anIntBandsorDecimalBandstype and use it. - A
columns:entry maps a key to a pair of headers. Map one header that holds the lower cut.
Complete files
Complete files
bad/rater.rsl
bad/tables/PayrollRate.csv
good/rater.rsl
good/tables/PayrollRate.csv
E-REQUIRES
Keep exact constraint forms in constraints. An input constraint decides which requests the rater accepts, so the compiler evaluates each one in exact arithmetic. Two forms exist for constraints alone, and this message reports one of them out of place or malformed.N% of xis an exact ratio. It belongs in a refinement, such aswhere self.subcontracted <= 50% of self.payroll.values: Csvon a numeric type keeps the type’s permitted values inenums/<Type>.csv, under the headervalue.
round.
Example
The calculation premium uses the exact ratio 50% of self.payroll.
values: Csv, such as Limit = Num {precision: int, values: Csv}.
- The rater’s folder lacks an
enums/folder, or the folder lacksLimit.csv. Add the file. - The file is empty, or its header is something other than
value. Start the file with the linevalue. - The file has a header and zero values. List at least one value.
- A cell holds text where a number belongs, or repeats an earlier value. Keep one row for each number.
- A value has more decimal places than the type’s
precision. Match the values to the precision. - A value lies outside the range in the type’s
where self in […]. Widen the range or remove the value. - The type leaves out
precision. State one, such asprecision: int. values:names something other thanCsv. Writevalues: Csv.- The braces state
values:twice. Keep one. - An input wraps the type, as
Option(Limit)orList(Limit). Use the type directly on a single input.
Complete files
Complete files
bad/rater.rsl
good/rater.rsl
E-REJECT
A reject needs a code and message.reject("CODE", "message") is a form from earlier versions of RSL, where a calculation refused a request. The check reads its two arguments as text literals. The code starts with a capital letter and continues with capital letters, digits, _ and -. The message holds at least one character.
RSL 0.4 removes reject itself, so this message always arrives with a second one for the removed form. In a table’s otherwise: reject(…) that is E-OTHERWISE-REJECT-REMOVED, and inside checked(…) it is E-CHECKED-REMOVED. Fix both at once by stating the rule as a refinement.
Example
The calculation premium calls reject with a code in lower case.
- The call has one argument, or three:
rejecttakes a code and a message. - An argument is a number or a name where the call needs a text literal.
- The code or the message is the empty text
"". - A table’s
otherwise: reject(…)has a malformed code or an empty message. - The third argument of
checked(x, T, …)is something other than arejectcall.
Complete files
Complete files
bad/rater.rsl
good/rater.rsl
E-MERGE-FIDELITY
Declare each map once, over one enum. Earlier versions of RSL built a map from several declarations and merged them. This check confirms that the merged map gives each key the value its own declaration wrote. It reports a key whose owner is ambiguous after the merge. RSL 0.4 gives a map one declaration, so the merge has a single input and the check holds. The message appears when a name is declared as a map twice, over two different enums. It arrives withE-AXES-REMOVED for the second declaration and E-AXIS-SUBSET for the two enums.
The numbers in the message are positions in the file and the compiler’s own labels. Read the map’s name and the key, then find the two declarations.
Example
The step declares rate over Coverage and again over Peril.
rate, over one enum. A second map, over another enum, takes its own name.
Complete files
Complete files
bad/rater.rsl
good/rater.rsl
E-BAND-COVERAGE
Cover every lookup key with a band.E-BAND-COVERAGE is retired. It was the code for a number that falls outside every band of the band type that keys a table. rslc check reports that problem at the lookup as E-KEY-RANGE, with the range the key can take and the range the bands cover.
E-EXTERN-REMOVED
Declare an external table as an ordinary table. Earlier versions of RSL let a table point at rows held outside the rater, with[extern: "…"] and related annotations. RSL 0.4 keeps every table’s rows in the rater’s own tables/ folder, where the check reads them.
With the rows in the folder, the compiler proves that each lookup finds a row. A large table needs the same declaration as a small one, and the compiler chooses how to store it.
A lookup by an identifier, such as a class code, keys the table with a Code type. An otherwise row gives the filed rate for every code the table leaves out.
Example
The table ClassRate carries the removed extern annotation and has its rows outside the rater.
tables/ClassRate.csv, with one header for each key and each column.
tables/ClassRate.csv
implementation, path, sqlite_table and reject on a table also belonged to external tables and get the same message. Delete each one.
Complete files
Complete files
bad/rater.rsl
good/rater.rsl
good/tables/ClassRate.csv
E-TEXT-REMOVED
Replace Text with a code or an enum. Earlier versions of RSL had aText type for free text. In RSL 0.4 the type of every value states what the value accepts, so the compiler can check each rule that reads it.
An identifier, such as a class code or a ZIP code, is a Code type with a pattern: ClassCode = Code(pattern: "[0-9]{4}"). A closed set of labels is an enum. A value that rating leaves unread, such as the insured’s name, belongs to the system that calls the rater.
A Text input that lacks the [extern] annotation gets E-TYPE as well. One fix clears both messages.
Example
The input insured_name has the removed type Text, and the premium ignores it.
payroll.
Where a rule reads the value, declare its type in Types as a Code with a pattern, or as an enum of its labels.
Complete files
Complete files
bad/rater.rsl
good/rater.rsl
E-AXIS-INDEX
Read a map at a key it defines.E-AXIS-INDEX is the code for a read of an indexed value at an element it leaves undefined. An indexed value in RSL 0.4 is a map over an enum, and rslc check reports the same problem as E-MAP-DOMAIN.
E-REQUIRES-REMOVED
Write a record rule as a refinement. A rule that compares two inputs of one record belongs to the record. Earlier versions of RSL wrote such rules in arequires block inside the record. RSL 0.4 writes each rule as a refinement after the record’s closing brace: } where condition.
A refinement states which requests the rater accepts. The compiler uses it when it proves each calculation, and a request that breaks the rule is refused before rating starts.
The message quotes the first clause of the block as the refinement to write.
Example
The record Policy states its rule in a requires block.
where for each clause, written one after another.
Complete files
Complete files
bad/rater.rsl
good/rater.rsl
E-RANGE-REMOVED
Write a value range as a refinement. Earlier versions of RSL stated the values a number accepts inside the type’s braces:{precision: int, range: [0, 100]}. RSL 0.4 keeps precision in the braces and writes the range as a refinement after the type: where self in [0, 100].
A refinement is the one place a rater states which values it accepts. The compiler reads it to prove each calculation, and a request outside the range is refused before rating starts.
The message gives the refinement to write, with the bounds copied from the old range.
Example
The input payroll states its range as range: metadata.
range: from the braces and write the bounds as where self in […] after the type. Annotations in brackets, such as a label, stay before the where.
- A type alias in
Typesstatesrange:metadata. Write the same refinement after the alias’s type. - A table column states
range:metadata. Delete it: the rows of the table give the column’s values.
Complete files
Complete files
bad/rater.rsl
good/rater.rsl
E-AXES-REMOVED
Replace an axis with an enum and maps. Earlier versions of RSL declared coverages, perils and similar dimensions in anAxes block and indexed values by axis. RSL 0.4 uses the forms it has for every other set of labels:
- The dimension is an enum in
Types, such asCoverage. - A value for each member is a map with one declaration:
rate[c: Coverage]. - A value that differs by member chooses with
match c. - A read names one key:
self.rate[c]orself.rate[@Coverage.liability]. - A total names the enum and a binder:
sum(Coverage as c, self.rate[c]).
Types and used in the same places.
With one declaration for each map, the compiler proves that every key has a value.
Example
The total premium folds over an axis with the removed form sum(x over axis).
- The file has an
Axesblock. Declare each axis as an enum inTypes, asCoverageis in the example. - A step declares one member of a map, as
rate[liability], or a listed subset. Write one declaration over the enum and choose withmatch c. - A step declares the same map twice. Write one declaration over all the keys.
- A read lists several keys, as
self.rate[c: {liability, property}]. Read one key. - A table column lists members, as
rate: Rate[{liability, property}]. Key the column by the enum:rate: Rate[Coverage]. - An input carries an axis annotation, as
limit: Num [coverage]. Declare one input for each member and build the map in a step.
Complete files
Complete files
bad/rater.rsl
good/rater.rsl
E-RELATION-REMOVED
Declare records and contain them by type. Earlier versions of RSL declaredEntities and linked them with annotated fields: [children] on the parent and a [parent] field on the child. RSL 0.4 declares Records, and a record contains another by naming its type.
- A field typed
Locationholds one record. - A field typed
Option(Location)holds at most one. - A field typed
List(Location)holds several.
Policy.experience_mod. The compiler knows each record’s place from the types, so the back-reference field has gone.
Example
The file declares Entities, a [children] list of EntityId(Location) and a [parent] field on Location.
Records and type the list List(Location). Delete the [parent] field and read the policy’s value as Policy.experience_mod.
Complete files
Complete files
bad/rater.rsl
good/rater.rsl
E-REJECT-REMOVED
State a refusal as an input refinement. Earlier versions of RSL let a calculation refuse a request withreject("CODE", "message"). In RSL 0.4 every calculation returns a value for every request the rater accepts. A rule that refuses a request is a refinement on the inputs it reads.
The refinement keeps the business code and the message. A request that breaks the rule gets that code before rating starts, and the calculation holds only arithmetic.
The message names the calculation and the kind of rule it found. Its help line writes the refinement, with the code and message copied from the reject.
Example
The calculation premium refuses a payroll below 1,000 with reject.
Complete files
Complete files
bad/rater.rsl
good/rater.rsl
E-OTHERWISE-REJECT-REMOVED
Refuse an unrated key at the input. Earlier versions of RSL let a table refuse a key that lacks a row, withotherwise: reject("CODE", "message"). In RSL 0.4 a lookup returns a row for every request the rater accepts. A rule that refuses a request is a refinement on the input it reads.
The refinement keeps the business code. A request with an unrated key gets that code before rating starts, and the compiler proves that each lookup finds a row.
otherwise remains for the filed all-other row, written with values and a citation: otherwise [cite: manual:p4]: { rate: 3.1 }.
Example
The table TerritoryRate files rates for urban and rural, and refuses offshore with otherwise: reject.
otherwise [cite: …]: { … }.
Complete files
Complete files
bad/rater.rsl
bad/tables/TerritoryRate.csv
good/rater.rsl
good/tables/TerritoryRate.csv
E-CHECKED-REMOVED
Prove a range from the inputs. Earlier versions of RSL tested a value against a type while rating:checked(x, T, reject("CODE", "message")) refused a request whose x fell outside T. In RSL 0.4 every calculation returns a value for every request the rater accepts. The compiler proves that x lies in T from the ranges of the inputs.
A rule that refuses a request is a refinement on the input it reads. The refinement keeps the business code, and a request outside the range gets that code before rating starts.
Example
The calculation rated_payroll tests the payroll against the type RatedPayroll with checked.
max(min(self.payroll, 100000000), 1000).
Complete files
Complete files
bad/rater.rsl
good/rater.rsl
E-SLOT-REMOVED
Let the formula state the rule. Earlier versions of RSL let the brackets of a calculation repeat what its formula does, in keys such asat_least:, total: and chain:. The compiler reads the same facts from the formula, so RSL 0.4 writes each rule once.
One statement of a rule stays true when the formula changes. A key beside the formula could say one thing while the arithmetic did another.
The message names the key, and its help line says which part of the formula carries the meaning.
Example
The calculation premium applies a minimum with max(…) and repeats it as at_least: minimum_premium.
max(…) in the formula states the minimum.
at_least:is stated bymax(…)in the formula.at_most:is stated bymin(…)in the formula.total:is stated by the sum in the formula.product:andchain:are stated by the product in the formula.by:is stated by the keys of the lookup.selects:is stated by the inputs the calculation reads.series:is stated by a map value that reads its own previous element.bands:becomes a group: writecollectand atitle.when:becomes a condition: writeexception when …orwith … otherwise.within:becomes a choice: writeselect(low..high, position).
Complete files
Complete files
bad/rater.rsl
good/rater.rsl
E-INVARIANT
Meet each structural rule of a rater.E-INVARIANT is reserved for a rater that breaks one of the compiler’s numbered structural rules. rslc check prints such a finding on a line of its own. The line starts with the kind of finding and the rule’s number, in place of an E- code.
A placeholder, nl "…", is one such case: its line starts obligation: 25.