Repository navigation
v4.0.0 #60
minirang
announced in
Announcements
v4.0.0
#60
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Description
Behavior change: the syntax is cleaned up, and a program written for 3.x has to be rewritten by hand. Every form that was removed is a syntax error (
E2-001) whose hint says what to write, so an old program stops with a message and never quietly means something else, apart from the three changes listed separately below. The table at the end of this entry lists every change with the form to write instead.Behavior change:
change,addandremovetake the same kind of target, a place. A place is a name,selfor a.nameof awithblock, followed by any number of[index]and.field.add 5 to grid[1]adds to the inner list,remove "x" from self.itemsremoves from a field, andchange grid[2][3] to 0changes an item, all by one rule. The statementreplace items[2] to "x"is gone (change items[2] to "x"). A program that hasadd X to NAME[i]orremove X from NAME[i]means something different now: in 3.x the target ended at the name and the[i]after it was read as a list of its own; now the target is the elementNAME[i]. Search a program foradd ... to NAME[andremove ... from NAME[.Behavior change:
isonly compares values. It no longer reads a string on its right as a pattern, socode is "[num]4"is an ordinary comparison with that text and is false. Writecode matches p"[num]4". The case-insensitiveISis removed (answer matches p"yes"i). Two objects areisequal only when they are the same object; two patterns when their source and flags are the same.Behavior change: functions are declared with
func, withasyncandpurein front.set returnable func f()isfunc f(), andset async pure func f()isasync pure func f().returnableis removed because every function canreturna value, and a function that ends without one givesempty.E4-016now meansreturnwith a value outside any function.Behavior change:
change x to globalisglobal x, a statement written before the names are used, which may name several variables (global a, b).Behavior change: the text statements are functions, and patterns are values.
find P from T,match T from P,replace P in T to R,split T by Pandcount P in Tarefind(T, p"P"),match(T, p"P"),replace(T, p"P", R),split(T, p"P")andcount(T, p"P"), with the text first. The flaggis gone:find_allandreplace_alldo what it did. A pattern is writtenp"..."and is raw: the text between the quotes goes to the pattern parser as written, so a backslash in a pattern is written once, not four times (p"a\\b"), and the only escape the literal reads is\". The flagsiandmfollow the closing quote.Behavior change: 11 reserved words are added and 13 are removed, 44 in all.
class,each,extends,fail,isa,matches,private,self,skip,superandwithcan no longer be names of variables, functions or parameters. Rename them.IS,by,count,find,replace,split,returnableand the type namesboolean,list,map,match,numberandstrare no longer reserved: a type name is a type only where a type may stand (set list items to [], a parameterlist items) and is an ordinary name everywhere else, soset list list to [1]is valid.Removed:
&&and||. Writeandandor; the hint says so. Also removed:replace NAME[i] to value,setandreturnablebeforefunc,change x to global, the five text statements and their flagg, andIS.Added: classes and objects.
class Player do: ... enddeclares fields (set number x to 0), methods (func) and, if wanted, the constructorinit.Player("Ann")makes an object,player1.sayhello()calls a method,selfis the object inside a method,class Hero extends Playerinherits andsuper.sayhello()calls the parent's method. A member markedprivatecan be used only by the methods of its class. Objects are shared like lists and maps,iscompares identity,copy(obj)makes a shallow copy,obj isa Playertests the class, andPlayerandobjectare types for variables and parameters. Aprintof an object shows<Player>unless its class has ato_strmethod,to_jsonwrites the public fields, and aset constantfield must be written in capitals and can be set only byinit. A class is declared at the top level of a file and may be used above its declaration. The reference is classes and the tutorial classes and objects.Added:
with object do:. Inside the block the object's members can be used by their plain names (sayhello(),change speed to 5) and as.name. A name is looked up as a variable of the block, then as a member, then in the rest of the program.withopens a scope of its own.Added: errors are objects.
or_else as err do:gives the handler anErrorwithmessage,code,line,columnandhint, for every error the handler can catch.fail "message"orfail Error("message")raises an error of the program, reported asE7-001, a new category thator_elsecan catch, and a class thatextends Errorraises its own kind (fail NotFound("x"), tested witherr isa NotFound).fail errinside a handler raises the same error again.Added: patterns as values.
p"..."has the typepattern;set pattern p to p"[num]+"andtext matches pwork, a pattern can be passed to a function, andpattern(text)orpattern(text, "i")builds one while the program runs.matchestells whether a wholestrfits a pattern.Added:
loop each,skipand default parameters.loop each item in items do:visits the items of a list, the keys of a map or the characters of a text, andskipgoes on with the next pass. A parameter may have a default (func greet(str name, str word to "Hello")), which is worked out at each call.Added: methods on built-in values. A library function whose first argument is the value it works on can be called as a method:
text.upper()isstr_upper(text),scores.sort()islist_sort(scores),text.find(p"[num]+")isfind(text, p"[num]+"). The library must be loaded withuseas before, and the function form still works.copy(x), also writtenx.copy(), makes a copy of a list, a map or an object, one level deep.Added: error codes
E4-031toE4-041andE7-001. They cover an unknown class, a class that inherits from itself, a member that does not exist, aprivatemember used outside its class,.nameorwithon something that is not an object, a class inside a block, a member declared twice, a class named like a function or another class, a class name without a capital, a method used as a value, and apurefunction that changes a field.E4-004also covers a constant field whose name is not in capitals.E4-026covers three new limits: 64 ancestors of a class, 1,024 members of a class and 4,096 classes in a program. Every code has an example in the error catalogue that the documentation check runs.Changed:
cuffsh, the tools and the examples follow the new syntax. The shell knows thatclass,withandloop eachopen a block, and keeps the classes of a session (declaring a class again replaces it for objects made afterwards). The syntax tree printed bycuffc --astshows the new nodes, and the function pages of the documentation list the method form of each function. The examples are rewritten as a course:01to12take one subject each, in order, fromprintthrough text and patterns, errors,async, classes, inheritance andwith;13to15load a module, use the libraries and work with a file;16to19are small programs of the kind people write (a word count, an inventory, a bank account, a log summary).Changed: the documentation is written for 4.0.0. The grammar, the language reference, the pattern reference, the error catalogue, the limits, every library page, the guides, the cookbook and the FAQ describe the new language, with the new reference classes and the new guide classes and objects. The design notes record the decisions of this release from item 46 on. The documentation check runs 217 examples, up from 148.
Added: tests, grouped by the part of the language they check.
tests/cases/andtests/errors/are divided intosyntax,values,operators,collections,control,functions,errors,classes,modules,text,libraries,limitsandphenomena, andtests/README.mdsays which productions of the grammar each area answers for. There are 146 error cases (84 in 3.5.1), 66 cases (32 in 3.5.1), 19 examples and 13 example errors, and nine unit tests with 2,550 checks:syntax_test.cppfor what the parser accepts and refuses,classes_test.cppfor the object model and thewithlookup order,phenomena_test.cppfor what has been printed when an error ends a run, more limits (module depth and size, the regex step and time budgets) inlimits_test.cppandregex_test.cpp, and a threads test that declares classes and makes objects on every thread. The newpython3 tests/coverage.pyasks the engine what it contains and fails when an error code that can be raised, a library function, a built-in method or a production of the grammar is touched by no test; it runs in CI.Added: How it works and Phenomena. The first says what the engine does while a program runs: the four steps of a run, scopes, calls, how values are shared, loops, errors and the
asyncqueue. The second lists fourteen behaviours that follow from those rules, such as functions being known before the first line runs, a loop working from the items it started with, and0.1 + 0.2printing as0.3while not beingis 0.3. Each has a program that is also a test, andtests/coverage.pyfails if a program in the guide stops being the test.Fixed: the build failed with clang on macOS.
Interpreterhas a private base class with a virtual function and no virtual destructor, and clang's-Wdelete-non-abstract-non-virtual-dtoris an error under-Werror.Interpreteris nowfinal, which is what it always was.Fixed: a line break inside a string literal was a carriage return and a line feed when the file used CRLF.
length()of a two-line literal was one more on Windows than on Linux and macOS, so the same program printed different text. A line break in a literal is now one\non every platform.*.cufffiles are checked out with LF line endings, andphenomena_test.cppruns the same literal with both endings.Fixed:
cuffsh's test of a failingasyncjob looked for a file that had moved, so it passed without checking anything. It now finds the file, and stops if it is missing.Changed: the engine is faster. A value is now a tag and a payload written out by hand instead of a
std::variant, so copying, moving and dropping a number, a boolean oremptycosts a few instructions and no call, and the pattern matcher no longer allocates for every step. Measured on one machine against 3.5.1, best of five: a loop of 400,000 iterations 48.9 ms to 34.9 ms, recursivefib(24)30.6 ms to 23.8 ms, pattern matching and text functions over 100 KB 54.7 ms to 26.7 ms, random numbers 30.0 ms to 23.9 ms. One million method calls take 133 ms, down from 237 ms.change self.name to valueandchange variable.name to valueskip the general walk of a place. Behaviour is unchanged: the whole suite passes under AddressSanitizer and UndefinedBehaviorSanitizer with assertions on, and a mutation fuzz of 3,000 programs found nothing.Migrating from 3.x
set returnable func f(a) do: ... endfunc f(a) do: ... endset async pure returnable func f()async pure func f()change total to globalglobal totalreplace items[2] to "x"change items[2] to "x"add 5 to grid[1](added togrid)add 5 to grid[1](adds to the inner list)if code is "[up]2-[num]4" do:if code matches p"[up]2-[num]4" do:if answer IS "yes" do:if answer matches p"yes"i do:(oris)set str p to "[num]+"andx is pset pattern p to p"[num]+"andx matches pfind "[num]+" from textfind(text, p"[num]+")find "[num]+" from text gfind_all(text, p"[num]+")match text from "(a)(b)"match(text, p"(a)(b)")replace "a" in text to "b" greplace_all(text, p"a", "b")split text by "[sp]+"split(text, p"[sp]+")count "a" in text icount(text, p"a"i)"a\\\\b"(one backslash in a pattern)p"a\\b"a && b,a || ba and b,a or beach,skip,with, ...1 ~ length(items)loop each item in items do:This discussion was created from the release v4.0.0.
All reactions