Repository navigation
The library reads as methods of its types, and every program that calls it
must change. Sixteen modules export 203 names where they exported 354; the
151 that went are gone rather than deprecated, because §6.11.2 puts every
imported name in one scope and keeping both spellings would keep the collision
the change exists to remove. There is no migration period. What a caller does:
| was | is |
|---|---|
JsonIntegerOr(JsonMember(p, 'line'), -1) |
p.Member('line').IntegerOr(-1) |
TomlPath(doc, 'server.port') |
doc.Path('server.port') |
ErrorText(e) |
e.Text |
IVecPush(v, 10) / SVecGet(v, 1) |
v.Push(10) / v.At(1) |
NetWriteLine(s, t) / TlsWriteLine(c, t) |
s.WriteLine(t) / c.WriteLine(t) |
StreamReadLine(f, l) / NextEntry(d, n) |
f.ReadLine(l) / d.NextEntry(n) |
A name that is still exported is one with no receiver to select from: a
type, a bound, a constructor (JsonNewObject, TomlNewTable, IVecNew), or
an entry point that answers a value rather than acting on one (JsonParse,
RegexCompile, NetConnect). pascalc --dump-uses and the language server
answer where a method is defined; grep for a bare Put no longer does, which
is the one cost no gate sees.
This is the major number because of that table, not because of the language:
every construct that compiled before this release still compiles, with two
exceptions listed under Removed.
Added
-
A module's implementations reach the components that import it
(ADR-0411, AP 6.7.10.5).impl Circle;andimpl Renders for Circle;
written in a module-block are selected in every program-component that can
nameCircle— so a library's types carry their own routines, and
c.Area,Area(c)and adyn Rendersbuilt by the client all reach them.
Nothing about the spelling changed; what changed is which translations may
read it.Until now this did not work and was not refused: the call compiled and the
program failed at the assembler or the linker, naming a symbol no source
spells. AP 6.7.10.1 NOTE 9 had recorded it as not provided (ADR-0341).A method's heading is now part of what a component is translated against,
so changing one without rebuilding the client is refused at the link, the
way a changed module-heading already was (AP 6.13.2). Changing a method's
body still costs no relink.A method may be
external, which had been admitted since methods landed and
is now pinned by a case; it is the one method shape whose linkage name is
C's rather than this compiler's. -
A type may have routines of its own:
impl T;andx.M(a)(ADR-0410,
AP 6.7.10, AP 6.7.10.4).impl Point;declares routines belonging to
Point, with the receiver written as an ordinary first parameter, and
p.Shift(1, 1)calls one. It is not a second mechanism:x.M(a)and
M(x, a)denote the same call, the routine having been selected from its
first argument's type since traits landed, so a method may be written either
way and any variable may be the receiver —p.Len,q^.Len,a[1].Len,
b.inner.Len.What it buys is that a method is not an exported name: a module exports
the type, and its routines travel with it, so two modules may each have a
Putwhere §6.11.2 refuses that to two exported names. 139 of this
library's 486 exported names repeat their own module's noun to work around
exactly that.A type may not have a field and a routine of one name, and is told so where
the implementation is written. A method called on what a method returned
needs that second method to take its receiver by value, §6.6.3.3 wanting a
variable for avarparameter.implreserves nothing.This completes ADR-0315's three increments, all of them now built.
-
A collection may hold values of different types:
dyn T, the trait
object (ADR-0408, ADR-0409, AP 6.7.11).type Shape = dyn Renders;denotes
something that implementsRenders, andowned ^Shapeowns one;take
moves a concrete value in and attaches its implementation, and a call
through the result selects the implementation where the value is used
rather than where the call is translated. This is what a bound
(AP 6.7.3.10.5) cannot do — a bound chooses where the type is written, so
one collection is one type — and it is the first place this compiler emits a
dispatch table.A trait object stands in two positions: the domain of an
ownedpointer and
avarorprotected varparameter. Everything else is refused with a
message saying where one can stand, because every other position would hold
a value whose lifetime nothing states. The implementation travels with the
value and so does the release, so disposing anowned ^Shapereleases
the concrete value and whatever that owns.Not every trait has a trait object: each routine must take its receiver as a
varorprotected varfirst parameter and nameSelfnowhere else, and a
trait that does not is told so where thedyntype is declared, with the
heading named.dynreserves nothing — a program may still declare a type,
a field and a parameter of that name.AP 6.7.11 was published one release early, marked
[not yet implemented]
under AP 5.6 — the first and only clause ever to carry that marker — and the
marker is now gone. Building it corrected two things the clause had said
(AP Annex E.13, E.14).
Changed
-
PasJson's routines are methods of its types (ADR-0412, AP 6.7.10).
The module exports 25 names where it exported 50, and a document is read
bydoc.Member('id').IntegerOr(-1)rather than
JsonIntegerOr(JsonMember(doc, 'id'), -1).JsonKindOfisKind,
JsonCharsAddLineisAddText,JsonTextIntoisTextInto, and so on
for 24 routines; what stays exported is what has no receiver to select
from — the types, the three bounds, the sevenJsonNew*constructors and
JsonParse/JsonParseChars.This renames a library's interface and every caller must change. The
old spellings are gone rather than deprecated:§6.11.2puts every
imported name in one scope, and keeping both would keep the collision the
change exists to remove.JsonCharsandJsonPtrnow each have aFree,
aLenand anAt, which two exported names could not have been. -
PasToml's routines are methods of its types too (AP 6.7.10). The same
change one format over, and the module it was modelled on: 31 names are
exported where 59 were, and a configuration is read by
doc.Path('server.port').IntegerOr(80)rather than
TomlIntegerOr(TomlPath(doc, 'server.port'), 80).TomlKindOfisKind,
TomlCharsAddLineisAddText,TomlPositionOfisTomlChars.PositionOf
-- a buffer asked about itself -- andTomlCharsandTomlPtrnow each
have aFree, aLenand anAt.TomlParse,TomlParseCharsand the
eightTomlNew*constructors keep their names, a parse answering a document
rather than being an operation of a buffer. Every caller must change,
for the reason above; the three TOML cases answer their goldens unchanged,
which is what says the rewrite moved no behaviour. -
Eight more library modules read as methods of their types (AP 6.7.10).
PasVectorexports 4 names where it exported 15,PasMap6 of 16,
PasStrVec6 of 19,PasRegex20 of 31,PasProcess12 of 22,PasNet10
of 14,PasTls16 of 20 andPasHttp27 of 38 — withPasJsonand
PasToml, 157 exported names where there were 284. A vector is
v.Push(x),v.At(i)andv.Len; a socket and a TLS connection both have
Close,WriteText,WriteLineandReadLine; a match is
m.GroupInto(1, s). Every caller must change, and the old spellings are
gone rather than deprecated, for the reason given above.Five spellings could not simply lose a prefix and the compiler said so:
IVecSet/SVecSetarePut(§6.1.2 reservesset) andBeginRequest/
BeginResponseareBeginWrite/BeginRead(it reservesbegin);
RegexFaultOf,RegexGroupsandRegexStepsareFaultOf,GroupCount
andStepCount, each beside a field of that spelling; andRegexFaultText
isRegexFault's ownText, an enumerated type being able to carry an
implementation. Nine receivers gainedprotected var: §6.7.3.1's advice is
deferred for an exported routine and fires on a method.PasFileis deliberately unconverted, and so arePasProcess'sRun,
CaptureandCaptureLinesandPasNet'sNetWait: their first parameter
is a type produced from a schema, or a schema, and neither may carry an
inherent implementation. -
PasErrorandPasLspDiagtoo, which finishes the conversion at
sixteen modules and 203 exported names where there were 354.ErrorText(e)
ise.TextandFailed(e)ise.Failed— an enumerated receiver, so
errNone.Textworks on a constant — andDiagJson(d, line, enc)is
d.Json(line, enc). 234 call sites across 48 files. What could not convert in
either module says what a receiver may be:ValueOrtakes a type-parameter
first, andHoldsNul,DiagParseandUtf16Columntakestringor a
production of it, which no module owns. -
Four more library modules read as methods of their types (AP 6.7.10).
PasListexports 3 names where it exported 13,PasStream6 of 11,PasLsp
7 of 10 andPasDir5 of 7 — with the ten before them, 177 exported names
where there were 325. A list isl.Push(x),l.Len,l.Reverse; a stream
and a socket and a TLS connection now shareWriteText,WriteLine,
ReadLineandClose.PasListkeeps no constructor, a fresh variable of
anowned ^being an empty list already. Every caller must change, for
the reason given above. -
PasNet.NetServiceisSocket.Service(AP 6.7.10), the one judgement
call the previous batch left open. It takes a socket that already exists and
asks it about itself, which is the receiver test exactly; that its answer is
about the socket's identity in the system rather than the stream of bytes
through it is a fact about the answer, not about how the routine is reached.
PasNetexports 9 names where it exported 14. Its receiver tookprotected varfor the reason the others did. -
At most one implementation of a type per program (ADR-0413,
AP 6.7.10). The rule said in a program-component, which every component
satisfies separately — so the language permitted two modules each giving one
type routines of its own, and no program that imports both can be given a
meaning. The library rule that follows: a module must not implement a type it
does not declare.One thing it does change about what the compiler accepts: an
inherent implementation for a type produced from a schema is now refused,
a type produced from schema 'string' is the same type wherever it is written, so it cannot carry an implementation of its own. 6.4.7 interns a
production by its tuple, so routines of its own would be routines of every
string(255)in the program. The trait form is unaffected —impl Sortable for Nameover a string-type of one's own is what that facility is
for, and three cases in the corpus rely on it.
Removed
-
An inherent implementation for a type produced from a schema is refused
(ADR-0413, AP 6.7.10). 6.4.7 interns a production by its tuple, so
string(255)is one type in every module; routines of its own would be
routines of everystring(255)in the program.impl FilePath;compiled
before this release and does not now. The trait form is unaffected —
impl Sortable for Nameover a string-type of one's own is what that
facility is for. -
An inherent implementation for a name that renames another type is
refused (ADR-0414).type Day = integer; impl Day;gave every integer in
the program that method, held by a name that did not say so.impl integer
written out stays legal: what is refused is the claim being invisible, and
the diagnostic names the identifier to write instead.
Fixed
-
A method may name itself through a receiver (ADR-0415, AP 6.7.10.4).
Inside an implementation,l^.next.Len— a parameterless method-designator
naming the routine whose declaration contains it — was refused with no
routine of that name is implemented for it, while the same recursion
written as a statement or as a call with arguments compiled. A routine now
joins its implementation before its body is checked, so all three spellings
reach it. Written order still decides: a method declared later is not in
scope, in any spelling. -
A method-designator selects from its receiver and not from the scope
(ADR-0412, AP 6.7.10.2). Inside an implementation that had a routine of
the name,x.M(a)bound to that routine rather than tox's — so two
types in one translation could not both have aFree, which is the whole
of what an implementation is for. -
A method chain is a procedure-statement.
a.M(x).N(y);consumed
a.M(x)and reportedexpected 'end' at the end of a compound statement. -
A parameterless method statement takes any receiver.
b.Freewas a
statement andv^.text.Freeandarr[1].Freewereexpected ':=' in an assignment. -
A designator's type is found in a variant part. A field declared in a
variant part answered no type when asked quietly, so a method selected on
one was reported unknown and the owned-vs-owned-pointer hint was not
given. -
A
varparameter produced from a schema is threatened by being passed
on (§6.9.4 b)).protected var s: stringcould be handed to another
routine'svar s: stringand written through there, with no diagnostic;
and the advice to addprotectedwas given for parameters that could not
take the word. One missing call, both faces. -
A trait may declare a procedure, and calling one now selects an
implementation. AP 6.7.10.2 has named a function-designator or a
procedure-statement since it was written and only the function half was
built, soEmit(p)over a type implementing the trait reported
unknown procedure 'emit'whileSize(p)beside it resolved (ADR-0407).
The specification's own NOTE 14 had recorded the gap and thereby
contradicted the clause above it; it now says what the procedure half
additionally requires — that the routine selected is a procedure, a trait's
function used as a statement being refused where any other function is.