Highlights
Changed license to Apache 2.0 with LLVM Exception
With the changes below, notably to make the remaining tweaks for function syntax, I think version 0.8 is now stable enough to be ready for a license that allows commercial use. Thank you again to everyone who provided feedback and PRs so far!
Note: This project is still 'without warranty / use at your own risk' and clearly says pre-1.0 right on the tin. You Have Been Reminded!
Regularized function syntax: Require =
for all functions, and defaulted single-expression bodies to -> forward _
Requiring =
even for the super-terse notation has been a widely-requested change, and I think it does make the code clearer to read.
For example, f: () expr;
must now be written as f: () = expr;
For a function whose body is a single expression, the default return type (i.e., if not specified) is now -> forward _
, which is Cpp1 -> decltype(auto)
(which, importantly, can deduce a value).
With this change, single-expression function bodies without { }
are still legal for any function, but as of this commit we have a clearer distinction in their use (which is reflected in the updates to the regression tests and other Cpp2 code in this commit):
-
It further encourages single-expression function bodies without
{ }
for unnamed function expressions (lambdas), by making more of those cases Do the Right Thing that the programmer intended. -
It naturally discourages their overuse for named functions, because it will more often cause a compiler warning or error:
-
a warning that callers are not using a returned results, when the function is called without using its value
-
an error that a deduced return type makes the function order-dependent, when the function is called from earlier in the source file... this is because a deduced return types creates a dependency on the body, and it is inherent (not an artifact of either Cpp1 or Cpp2)
But for those who liked that style, fear not, usually the answer is to just put the two characters
{ }
around the body... see examples in this commit, which I have to admit most are probably more readable even though I'm one of the ones who liked omitting the braces. -
Note: I realize that further evolution may not allow the
{ }
-free style for named functions. That may well be a reasonable further outcome.
I think both of these are positive improvements.
Added regular _ref
option to in
param and forward _
return; remove oddity inout: const
This keeps things nicely orthogonal addresses the two open issues with parameter passing:
- the now-removed oddity of
inout : const
, which becomes justin_ref
- the now-addressed need to directly express both Cpp1
-> decltype(auto)
and-> auto&&
, which now are-> forward _
and-> forward_ref _
Style | Parameter | Return |
---|---|---|
in |
⭐ | |
inout |
✅ | |
out |
✅ | |
copy |
✅ | |
move |
✅ | ✅ |
forward |
✅ | ⭐ |
The two ⭐'s are the cases that automatically pass/return by value or reference:
- all uses of
in
- deduced uses of
-> forward _
(ordinary-> forward specific_type
always returns by reference, adding constness if there's anin this
parameter)
Now both ⭐ cases also provide a _ref
option to not choose by-value.
An example that illustrates both is std::min
:
min: (in_ref a, in_ref b) -> forward_ref _
= { if b < a { return b; } else { return a; } }
main: (args) = {
x := 456;
y := 123;
std::cout << min(x, y) << '\n';
}
The container<T>::operator[]
case could already be written like this, where the first return lowers to Cpp1 T const&
and the second to T&
:
container: <T> type = {
buf: std::array<T, 10> = ();
operator[]: ( this, idx: i32) -> forward T = buf[idx];
operator[]: (inout this, idx: i32) -> forward T = buf[idx];
}
main: (args) = {
v: container<int> = ();
std::cout << v[0] << '\n';
}
Added support for decltype()
and type_of()
as a type-id
Thanks to @JohelEGP for this PR!
Support heterogeneous ..<
and ..=
ranges when there's a common type
Thanks @bluetarpmedia for this PR!
Renamed unsafe_*
to unchecked_*
, and recommend discard instead of as void
For renaming unsafe_*
" Thanks to Redditor @tialaramex for their suggestion, persuasively citing Rust's naming style (and thanks to the Rust designers too for the inspiration).
For replacing as void
: Thanks to @Velocirobtor and @JohelEGP for their suggestions on improving this diagnostic in the #1279 comment thread.
Added @hashable
metafunction
Super basic, adds a hash() -> size_t
function that has memberwise semantics, and uses std::hash
for data members and base::hash
for base classes.
Made forward
parameters of concrete type accept convertible/derived arguments
Made @struct
constructors use forward
parameters
A forward
parameter with a concrete type used to require an exact match, but can now accept arguments of convertible/derived types.
Code like this continues to work:
data: @struct type = { name: std::string; city: std::string; }
x: data = ( "Henry", "Memphis" ); // ok, uses conversions
I also added a @struct<noforward>
option to allow using @struct
with GCC 10, which doesn't support forward
parameters. And I use that in cppfront's own sources, just so cppfront itself continues building under GCC 10. (Someday we'll drop GCC 10 as a supported compiler, but for now it's still doing pretty well except for the won't-backport requires
-clause bug...)
Note that allowing the generated forwarding reference to bind to arguments of derived types was also suggested by @brevzin of @jumptrading in P2481 "Forwarding reference to specific type/template" -- thanks Barry, for the Cpp2 suggestion and for the ISO C++ forward
parameter proposal paper!
More examples:
Base: @polymorphic_base type = { } // a Base type
Derived: type = { this: Base; } // a Base-derived type
b: Base = ();
d: Derived = ();
s: std::string = ();
f:(forward _: Base ) = { } // forward a Base object
g:(forward _: std::string) = { } // forward a std::string object
main: () = {
f( b ); // ok, b is-a Base
f( d ); // ok, d is-a Base
f( s ); // ERROR, s is-not-a Base
g( s ); // ok, s is-a std::string
g( "xyzzy" ); // ok, "xyzzy" is-convertible-to std::string
g( b ); // ERROR, b is-not-a std::string
}
Cleaned up is
/as
implementation for std::variant
, std::optional
, std::any
Thanks to @filipsajdak for these PRs!
Added initial clang-tidy configuration
Thanks for @farmerpiki for this PR!
Additional PRs (thanks!)
- Don't build and run tests for docs-only changes. by @gregmarr in #1275
- Add passing styles to single type return by @gregmarr in #1274
- CI Update default arg tests by @jarzec in #1263
- Fix doc typo: Updated
..<
instead of...
for range operations in doc common.md by @tsoj in #1254 - CI Update the GitHub checkout action by @jarzec in #1299
- Exclude MSVC workaround on clang and gcc by @gregmarr in #1306
- CI Update tests - make all tests pass by @jarzec in #1324
New Contributors
- @farmerpiki made their first contribution in #1253
Full Changelog: v0.7.4...v0.8.0