Adept 2.7
Adept 2.7 has been released!
Sponsors:
- Special thanks to Fernando Dantas for sponsoring Adept ❤️
List of changes in Adept 2.7
Language:
-
Added ability to mark types as no discard using the
exhaustive
keyword:func getName() exhaustive String = "Not using this return value is a compile-time error"
-
Added ability to mark functions as disallowed using
= delete
-
func youCannotCallThisFunction(a, b int) int = delete
-
func youCannotCallThisFunction(a, b int) int = delete { return a + b }
-
Trying to call a disallowed function is a compile-time error.
-
Trying to assign a type regularly that has
__assign__
disallowed is a compile-time error.func __assign__(this *UnassignableType, _other POD UnassignableType) = delete
-
-
Unreachable code paths are no longer required to return a value
-
Added better and consistent constructors, with the new
constructor
keywordstruct Rectangle (w, h float) { constructor(w, h float) { this.w = w this.h = h } constructor(size float) { this.__constructor__(size, size) } } func main { rectangle1 Rectangle(100, 50) rectangle2 Rectangle = Rectangle(75, 50) rectangle3 Rectangle rectangle3.__constructor__(500) rectangle4 *Rectangle = new Rectangle(640, 480) defer delete rectangle4 }
- Constructors automatically generate a constructor function (that has the same name as the type it's for)
- Constructors come with a companion
__constructor__
method, which can be used to call a constructor on any value - Constructors can use the new immediate construction syntax:
my_value MyType()
andnew MyType()
- Zero-initialization is still the default, constructors don't apply to naked definitions, e.g.
my_value MyType
is zero-initialized and not constructed.
-
Trying to declare
__as__
as a method is now a compile-time error (__as__
should be declared as a function) -
Changed
#halt
directive to exit the compiler with status code 1 instead of 0 -
Added
#done
directive to exit the compiler with status code of 0 -
Added
#runtime_resource
directive, which will create a project-local copy of a file (if one with the same name doesn't already exist)- Used to automatically supply runtime resources such as
.dll
files to new projects that need them
- Used to automatically supply runtime resources such as
-
Added classes, which are equivalent to structs except that they allow for virtual dispatch and come with a
__vtable__
field.import basics class Shape () { constructor {} } func main { shape *Shape = new Shape() defer delete shape print(shape.__vtable__) // Will be non-zero since `value` is constructed and ready for dynamic dispatch }
- All classes require a constructor and must be constructed in order to use dynamic dispatch / virtual methods
-
Added virtual methods and virtual dispatch
import basics class Shape () { constructor {} virtual func getArea() float { return 0.0f } } class Rectangle extends Shape (w, h float) { constructor(w, h float) { this.w = w this.h = h } override func getArea() float { return this.w * this.h } } func main { shape *Shape = new Rectangle(100.0f, 50.0f) defer delete shape print(shape.getArea()) }
- Virtual methods can be used alongside existing features such as regular polymorphism, default values, and more
-
Added optional
foreign
prefix for enums, which disables the requirement to use theEnumName::
prefix to refer to enum variants. This is useful when writing bindings for C libraries, as enum variants are already named to be unambiguous.// ... foreign enum CURLUPart ( CURLUPART_URL, CURLUPART_SCHEME, CURLUPART_USER, CURLUPART_PASSWORD, CURLUPART_OPTIONS, CURLUPART_HOST, CURLUPART_PORT, CURLUPART_PATH, CURLUPART_QUERY, CURLUPART_FRAGMENT, CURLUPART_ZONEID /* added in 7.65.0 */ ) func main { // Without `foreign` prefix, we would have to do: part1 CURLUPart = CURLUPart::CURLUPART_URL // With `foreign` prefix, we're allowed to do: part1 CURLUPart = CURLUPART_URL }
-
Resolved issues with loose polymorphism
$T
and$~T
are no longer equivalent$T
and$~T
are now only equivalent if at the top level of a type. For example,func add(a, b $T) $T
is equivalent tofunc add(a $T, b $~T) $T
, butfunc add(a, b <$T> Container) <$T> Container
is not equivalent tofunc add(a <$T> Container, b <$~T> Container) <$T> Container
.
-
Added new polymorphic prerequisite
$T extends MyClass
, e.g.func useShape(shape <$T extends Shape> Optional) { ... }
-
Changed
__unix__
to now properly betrue
when compiling for macOS -
Lots of bugs fixes
Standard Library:
- Removed outdated lowercase constructors for types in
2.7/
standard libraryarray(items, length)
removed in favor ofArray(items, length)
list(items, length, ownership)
removed in favor ofList(items, length, ownership)
string(null_terminated_string)
removed in favor ofString(null_terminated_string)
captColor(r, g, b, a)
removed in favor ofCaptColor(r, g, b, a)
- etc.
- Outdated programs that use these old constructor names will need to have an earlier version of the standard library specified in order to compile (e.g. with
--std=2.6
orpragma default_stdlib '2.6'
or havepragma compiler_version '2.6'
)
- Some types such as
Pair
are now records instead of plain structs - Trying to use a donor
String
,List
, orGrid
value after it has been donated now is now a runtime error (enabled by default) StringOwnership::DONATED
has been renamed toStringOwnership::DONOR
- Added
give()
method forString
,List
, andGrid
, which is equivalent tocommit()
with ownership required. Not having ownership to give is a runtime error by default. - Added
__assign__
for Optional, so that their internal values are not improperly assigned whenhas
is false
Behind the Scenes Changes:
- Completely rewrote lexer
- Cleaner compiler code
Adept 2.7 is also backwards compatible with most programs written in versions 2.0 through 2.6