Skip to content

Releases: ponylang/ponyc

0.51.1

29 Jun 23:53
Compare
Choose a tag to compare

Fix String.f32 and String.f64 errors with non null terminated strings

Until now, the String.f32 and String.f64 methods required null-terminated strings in order to work properly. This wasn't documented, and wasn't the intended behaviour. We've now fixed these cases and these functions should work as expected for non-null-terminated strings.

Fix for infinite Ranges

Even though all Range objects that contain NaN parameters or a zero step parameter are considered infinite, some did not iterate at all or produced an error after the first iteration. For example, the code from the Range documentation:

  // this Range will produce 0 at first, then infinitely NaN
  let nan: F64 = F64(0) / F64(0)
  for what_am_i in Range[F64](0, 1000, nan) do
    wild_guess(what_am_i)
  end 

did not run as expected, but rather produced an error on the first iteration. This is now fixed, and .next() calls on the above Range[F64](0, 1000, nan) now first yields 0 and subsequently indefinetely NaN values. Likewise, Range(10, 10, 0) will now indefinitely yield 10.

Update to basing musl images off of Alpine 3.12

We supply nightly and release Docker images for ponyc based on Alpine Linux. We've updated the version of Alpine we use from 3.12 which recently reached it's end of life to Alpine 3.16 which is supported until 2024.

More efficient actor heap garbage collection

We have improved the actor heap garbage collection process
to make it more efficient by deferring some initialization
work and handling as part of the normal garbage collection
mark and sweep passes.

Fix compiler crash related to explicit FFI return types

After we re-added the ability to override the return type for FFI function calls in a previous release, we forgot to reintroduce some checks in the compiler that ensured that the specified return types would be known to the code generation pass. This caused some programs that introduced a new type (for example, a bare lambda) in the context of a FFI return type to crash the compiler. This is now fixed.

Support void* (Pointer[None]) parameters in bare lambdas and functions

Unlike conventional FFI functions, bare lambdas @{(...)} and bare functions fun @bare() => ... did not support Pointer[None] parameters, Pony's equivalent of void*. This is despite the fact that like FFI functions, bare lambdas and functions are strictly intended for use with FFI calls and callbacks.

This commit allows bare lambdas and bare functions with Pointer[None] parameters to accept arguments of any Pointer[A] type for these parameters. Therefore, code like the following now works:

use @printf[I32](fmt: Pointer[None] tag, ...)

actor Main
  new create(env: Env) =>
    let printer = @{(fmt: Pointer[None] tag): I32 => @printf(fmt)}
    let cb = this~print()
    printer("Hello".cstring())
    cb(" world!\n".cstring())

  fun @print(fmt: Pointer[None]): I32 =>
    @printf(fmt)

Systematic testing for the runtime

Pony is a concurrent and parallel language. Different actors can be run
at the same time on multiple CPUs. The Pony runtime coordinates all of
this interleaving of actors and contains a fair amount of complexity.
Runtime functionality such as the message queues and the backpressure
system rely on atomic operations which can be tricky to get right across
multiple platforms.

Systematic testing will allow us to coordinate the interleaving of the
multiple runtime scheduler threads in a deterministic and reproducible
manner. This ability to reproduce a particular runtime behavior will be
invaluable for debugging runtime issues.

The overall idea and some details of the implementation for systematic
testing has been shamelessly stolen from the Verona runtime (see:
https://github.com/microsoft/verona/blob/master/docs/explore.md#systematic-testing
for details). This implementation doesn't include replayable runtime
unit tests like Verona, but it sets a foundation for allowing replayable
runs of programs (and probably tests) for debugging runtime issues such
as backpressure/etc. Additionally, while all development and testing was
done on Linux, in theory this systematic testing functionality should
work on other operating systems (Windows, MacOS, Freebsd, etc) barring
issues related to lack of atomics for tracking the active thread and
whether a thread has stopped executing or not (unlikely to be an issue
on MacOS/Freebsd/other pthread based threading implementations).

Instructions for using systematic testing...

The following instructions were tested on Linux but should in theory
function correctly on other *nix environments that use the Pony
make/cmake based build system.

Start with a clean environment:

make clean config=debug

Configure with systematic testing and pthreads enabled:

make configure config=debug use=scheduler_scaling_pthreads,systematic_testing

Build:

make build config=debug

Compile helloworld:

./build/debug-systematic_testing/ponyc examples/helloworld/

Run helloworld:

./helloworld

Output will look something like:

me@home:~/ponyc$ ./helloworld
Systematic testing using seed: 360200870782547...
(rerun with `<app> --ponysystematictestingseed 360200870782547` to reproduce)
<SNIPPED LOTS OF OUTPUT>
thread 139871784978176: yielding to thread: 139871776585472.. next_index: 3
Hello, world.
thread 139871776585472: yielding to thread: 139871768192768.. next_index: 4
<SNIPPED LOTS OF OUTPUT>
Systematic testing successfully finished!
me@home:~/ponyc$ 

[0.51.1] - 2022-06-29

Fixed

  • Fix String.f32 and String.f64 errors with non null terminated strings (PR #4132)
  • Fix for infinite Ranges (PR #4127)
  • Ensure reachability of types returned by FFI calls (PR #4149)
  • Support void* (Pointer[None]) parameters in bare lambdas and functions (PR #4152)

Added

  • Avoid clearing chunks at start of GC (PR #4143)
  • Systematic testing for the runtime (PR #4140)

Changed

  • Update to basing musl images off of Alpine 3.16 (PR #4139)

0.51.0

29 May 01:43
Compare
Choose a tag to compare

Update glibc Linux Docker base image

Previously our glibc Linux Docker images where based on Ubuntu 20.04. They've been updated to use Ubuntu 22.04.

Update to LLVM 14.0.3

We've updated the LLVM used to build Pony to 14.0.3.

Don't include debug information in release versions of ponyc

At some point in the past, we turned on an option PONY_ALWAYS_ASSERT when building ponyc and the runtime. The result of this option was to not only turn on all debug assertions, but also, turn on almost all debug code in the runtime and the ponyc compiler.

The inclusion of assertions was great for error reports from users for compiler bugs. However, it was also including code that would make the compiler slower and use more memory. It was also including code that made the runtime slower for all compiled Pony programs.

We've turned off PONY_ALWAYS_ASSERT. Programs will be somewhat faster, the compiler will be a little faster, and the compiler will use a little less memory. In return, if you report a compiler bug, we'll definitely need a minimal reproduction to have any idea what is causing your bug.

Add prebuilt ponyc binaries for MacOS on Apple Silicon

We've added prebuilt ponyc binaries specifically made to work MacOS Monterey on Apple Silicon. You can install them with ponyup that is now also available for MacOS on Apple Silicon.

Disable incorrect runtime assert for ASIO thread shutdown.

In a rare race condition, a runtime assertion failure related to destruction of the runtime ASIO thread's message queue could be observed during program termination, causing a program crash instead of graceful termination.

This change removes the invalid runtime assertion for that case, because the invariant it was meant to ensure does not apply or hold for the specific case of terminating the runtime ASIO thread, even though it still holds and is still being tested for the more common case of individual actor terminator.

[0.51.0] - 2022-05-29

Fixed

  • Disable incorrect runtime assert for ASIO thread shutdown. (PR #4122)

Added

  • Add prebuilt ponyc releases on MacOS for Apple Silicon (PR #4119)

Changed

  • Update base image for glibc Linux docker images (PR #4100)
  • Update LLVM to 14.0.3 (PR #4055)
  • Don't use "mostly debug runtime" with release configurations (PR #4112)

0.50.0

30 Apr 11:23
Compare
Choose a tag to compare

Fix compiler crash with exhaustive match in generics

Previously, there was an interesting edge case in our handling of exhaustive match with generics that could result in a compiler crash. It's been fixed.

Fixed parameter names not being checked

In 2018, when we removed case functions from Pony, we also removed the checking to make sure that parameters names were valid.

We've added checking of parameter names to make sure they match the naming rules for parameters in Pony.

Fixed bug that caused the compiler to crash

We've fixed a bug that caused a compiler crash.

Allow overriding the return type of FFI functions

With the approval of RFC 68, we made FFI declarations mandatory, and with that, also removed the ability to separately specify a return type for an FFI function at the call site, like so:

use @printf[I32](fmt: Pointer[U8] tag, ...)

actor Main
  new create(env: Env) =>
    @printf[I32]("Hello, world!\n".cstring())

Since the return type at the call site needed to match the return type of the declaration, we removed this syntax on the grounds of it being redundant.

That change, however, made it impossible to write safe bindings for type-generic C functions, which might return different types depending on how they are used. Let's imagine an example with a generic list:

struct List;

struct List* list_create();
void list_free(struct List* list);

void list_push(struct List* list, void *data);
void* list_pop(struct List* list);

We want to use this API from Pony to store our own Point2D struct types. We can write the declarations as follows:

use @list_create[Pointer[_List]]()
use @list_free[None](list: Pointer[_List])

use @list_push[None](list: Pointer[_List], data: Point)
use @list_pop[NullablePointer[Point]](list: Pointer[_List])

primitive _List

struct Point2D
  var x: U64 = 0
  var y: U64 = 0

The problem with these declarations is that the list_push and list_pop functions can only operate with lists of elements of type Point2D. If we wanted to use these functions with different types, we would modify list_push to take an element of type Pointer[None], which represents the void* type. Until now, however, there was no way of making list_pop truly generic:

use @list_push[None](list: Pointer[_List], data: Pointer[None])
use @list_pop[Pointer[None]](list: Pointer[_List])

// OK
let point_list = @list_create()
@list_push(list, NullablePointer[Point2D].create(Point2D))

// OK
let string_list = @list_create()
@list_push(string_list, "some data".cstring())

// Compiler error: couldn't find 'x' in 'Pointer'
let point_x = @list_pop(point_list)
point.x

// Compiler error: wanted Pointer[U8 val] ref^, got Pointer[None val] ref
let head = String.from_cstring(@list_pop(string_list))

With this release, one can make list_pop generic by specifying its return type when calling it:

use @list_pop[Pointer[None]](list: Pointer[_List])

// OK
let point_x = @list_pop[Point](point_list)
point.x

// OK
let head = String.from_cstring(@list_pop[Pointer[U8]](string_list))

Note that the declaration for list_pop is still needed. The return type of an FFI function call without an explicit return type will default to the return type of its declaration.

When specifying a different return type for an FFI function, make sure that the new type is compatible with the type specified in the declaration. Two types are compatible with each other if they have the same ABI size and they can be safely cast to each other. Currently, the compiler allows the following type casts:

  • Any struct type can be cast to any other struct.
  • Pointers and integers can be cast to each other.

Specifying an incompatible type will result in a compile-time error

Don't allow FFI calls in default methods or behaviors

In Pony, when you use an external library, you import the public types defined by that library. An exception to this rule is FFI declarations: any FFI declarations in a library will not be visible by external users. Given that the compiler only allows a single FFI declaration per package for any given function, if external FFI declarations were imported, deciding which declaration to use would be ambiguous.

When added to the fact that every FFI function must have a matching declaration, a consequence of not importing external declarations is that if a library contains a public interface or trait with default methods (or behaviors), performing an FFI call on those methods will render them unusable to external consumers.

Consider the following code:

// src/lib/lib.pony
use @printf[I32](fmt: Pointer[None] tag, ...)

trait Foo
  fun apply() =>
    @printf("Hello from trait Foo\n".cstring())

// src/main.pony
use "./lib"

actor Main is Foo
  new create(env: Env) =>
    this.apply()

Up until ponyc 0.49.1, the above failed to compile, because main.pony never defined an FFI declaration for printf. One way of making the above code compile is by moving the call to @printf to a separate type:

// src/lib/lib.pony
use @printf[I32](fmt: Pointer[None] tag, ...)

trait Foo
  fun apply() =>
    Printf("Hello from trait Foo\n")

primitive Printf
  fun apply(str: String) =>
    @printf(str.cstring())

// src/main.pony
use "./lib"

actor Main is Foo
  new create(env: Env) =>
    this.apply()

Given that the original error is not immediately obvious, starting from this release, it is now a compile error to call FFI functions in default methods (or behaviors). However, this means that code that used to be legal will now fail with a compiler error. For example:

use @printf[I32](fmt: Pointer[None] tag, ...)

actor Main is _PrivateFoo
  new create(env: Env) =>
    this.apply()

trait _PrivateFoo
  fun apply() =>
    // Error: can't call an FFI function in a default method or behavior.
    @printf("Hello from private trait _PrivateFoo\n".cstring())

As mentioned above, to fix the code above, you will need to move any FFI calls to external function:

use @printf[I32](fmt: Pointer[None] tag, ...)

actor Main is _PrivateFoo
  new create(env: Env) =>
    this.apply()

trait _PrivateFoo
  fun apply() =>
    // OK
    Printf("Hello from private trait _PrivateFoo\n")

primitive Printf
  fun apply(str: String) =>
    @printf(str.cstring())

We believe that the impact of this change should be small, given the usability problems outlined above.

Fix concurrency bugs in runtime on Arm

Due to some incorrect memory ordering usage within various atomic operations in the runtime, it was possible for "bad things to happen" on Arm platforms. "Bad things" being violations of invariants in the runtime that could lead to incorrect runtime behavior that could exhibit in a variety of ways.

We've strengthened a number of memory orderings on Arm which should address the issues we have observed.

Fix a runtime fault for Windows IOCP w/ memtrack messages.

When the runtime is compiled with -DUSE_MEMTRACK_MESSAGES on
Windows, the code path for asynchronous I/O events wasn't
initializing the pony context prior to its first use,
which would likely cause a runtime crash or other undesirable
behavior.

The -DUSE_MEMTRACK_MESSAGES feature is rarely used, and has
perhaps never been used on Windows, so that explains why
we haven't had a crash reported for this code path.

Now that path has been fixed by rearranging the order of the code.

Add prebuilt ponyc binaries for Ubuntu 22.04

We've added prebuilt ponyc binaries specifically made to work on Ubuntu 22.04.

You can opt into using the Ubuntu binaries when using ponyup by running:

ponyup default ubuntu22.04

[0.50.0] - 2022-04-30

Fixed

  • Fix crash with exhaustive match and generics (PR #4057)
  • Fix parameter names not being checked (PR #4061)
  • Fix compiler crash in HeapToStack optimization pass (PR #4067)
  • Strengthen the ordering for some atomic operations (PR #4083)
  • Fix a runtime fault for Windows IOCP w/ memtrack messages. (PR #4094)

Added

  • Allow to override the return type of FFI functions (PR #4060)
  • Add prebuilt ponyc releases for Ubuntu 22.04 (PR #4097)

Changed

  • Don't allow FFI calls in default methods or behaviors (PR #4065)

0.49.1

13 Mar 18:41
Compare
Choose a tag to compare

Fix soundness bug introduced

We previously switched our underlying type system model. In the process, a soundness hole was introduced where users could assign values to variables with an ephemeral capability. This could lead to "very bad things".

The hole was introduced in May of 2021 by PR #3643. We've closed the hole so that code such as the following will again be rejected by the compiler.

let map: Map[String, Array[String]] trn^ = recover trn Map[String, Array[String]] end

[0.49.1] - 2022-03-13

Fixed

0.49.0

26 Feb 12:42
Compare
Choose a tag to compare

Add workaround for compiler assertion failure in Promise.flatten_next

Under certain conditions a specific usage of Promise.flatten_next and Promise.next could trigger a compiler assertion, whose root-cause is still under investigation.

The workaround avoids the code-path that triggers the assertion. We still need a full solution.

Take exhaustive match into account when checking for field initialization

Previously, exhaustive matches were handled after we verified that an object's fields were initialized. This lead to the code such as the following not passing compiler checks:

primitive Foo
  fun apply() : (U32 | None) => 1

type Bar is (U32 | None)

actor Main
  let bar : Bar

  new create(env : Env) =>
      match Foo()
      | let result : U32 =>
          bar = result
      | None =>
          bar = 0
      end

Field initialization is now done in a later pass after exhaustiveness checking has been done.

Fix compiler crash related to using tuples as a generic constraint

Tuple types aren't legal constraints on generics in Pony and we have a check in an early compiler pass to detect and report that error. However, it was previously possible to "sneak" a tuple type as a generic constraint past the earlier check in the compiler by "smuggling" it in a type alias.

The type aliases aren't flattened into their various components until after the code that disallows tuples as generic constraints which would result in the following code causing ponyc to assert:

type Blocksize is (U8, U32)
class Block[T: Blocksize]

We've added an additional check to the compiler in a later pass to report an error on the "smuggled" tuple type as a constraint.

Add greatest common divisor to math package

Code to determine the greatest common divisor for two integers has been added to the standard library:

use "math"

actor Main
  new create(env: Env) =>
    try
      let gcd = GreatestCommonDivisor[I64](10, 20)?
      env.out.print(gcd.string())
    else
      env.out.print("No GCD")
    end

Add least common multiple to math package

Code to determine the least common multiple of two unsigned integers has been added to the standard library:

use "math"

actor Main
  new create(env: Env) =>
    try
      let lcm = LeastCommonMultiple[U64](10, 20)?
      env.out.print(lcm.string())
    else
      env.out.print("No LCM")
    end

Fix incorrect "field not initialized" error with while/else

Previously, due to a bug in the compiler's while/else handling code, the following code would be rejected as not initializing all object fields:

actor Main
  var _s: (String | None)

  new create(env: Env) =>
    var i: USize = 0
    while i < 5 do
       _s = i.string()
       i = i + 1
    else
      _s = ""
    end

Fix incorrect "field not initialized" error with try/else

Previously, due to a bug in the compiler's try/else handling code, the following code would be rejected as not initializing all object fields:

actor Main
  var _s: (String | None)

  new create(env: Env) =>
    try
      _s = "".usize()?.string()
    else
      _s = None
    end

Fix compiler crash related to using tuples in a union as a generic constraint

Tuple types aren't legal constraints on generics in Pony and we have a check in an early compiler pass to detect and report that error. However, it was previously possible to "sneak" a tuple type as a generic constraint past the earlier check in the compiler by "smuggling" it in a type union in a type alias.

The type aliases aren't flattened into their various components until after the code that disallows tuples as generic constraints which would result in the following code causing ponyc to assert:

type Blocksize is (U64 | (U8, U32))
class Block[T: Blocksize]

We've added an additional check to the compiler in a later pass to report an error on the "smuggled" tuple type as a constraint.

Fix incorrect code returned by ANSI.erase

erase was intended to erase all characters to the left of the cursor but was instead returning the code to erase all characters to the right.

Reimplement with

The with keyword has been little used in most Pony programs. with was implemented as "sugar" over the try/else/then construct. Over the course of time, this became problematic as changes were made to make try more friendly. However, these try changes negatively impacted with. Prior to this change, with had become barely usable. We've reimplemented with to address the usability problems that built up over time. with is no longer sugar over try and as such, shouldn't develop any unrelated problems going forward. However, the reimplemented with is a breaking change.

Because with was sugar over try, the full expression was with/else. Any error that occurred within a with block would be handled by provided else. The existence of with/else rather than pure with was not a principled choice. The else only existed because it was needed to satisfy error-handling in the try based implementation. Our new implementation of with does not have the optional else clause. All error handling is in the hands of the programmer like it would be with any other Pony construct.

Previously, you would have had:

with obj = SomeObjectThatNeedsDisposing() do
  // use obj
else
  // only run if an error has occurred
end

Now, you would do:

try
  with obj = SomeObjectThatNeedsDisposing() do
    // use obj
  end
else
  // only run if an error has occurred
end

Or perhaps:

with obj = SomeObjectThatNeedsDisposing() do
  try
    // use obj
  else
    // only run if an error has occurred
  end
end

The new with block guarantees that dispose will be called on all with condition variables before jumping away whether due to an error or a control flow structure such as return.

This first version of the "new with" maintains one weakness that the previous implementation suffered from; you can't use an iso variable as a with condition. The following code will not compile:

use @pony_exitcode[None](code: I32)

class Disposable
  var _exit_code: I32

  new iso create() =>
    _exit_code = 0

  fun ref set_exit(code: I32) =>
    _exit_code = code

  fun dispose() =>
    @pony_exitcode(_exit_code)

actor Main
  new create(env: Env) =>
    with d = Disposable do
      d.set_exit(10)
    end

A future improvement to the with implementation will allow the usage of iso variables as with conditions.

Fix the interfaces for Iter's map and map_stateful methods to be less strict

The map_stateful and map methods on an Iter (from the itertools package) were too strict in what they required, requiring a B^ in order to produce an Iter[B].

This change correctly makes them only require B.

Use symbol table from definition scope when looking up references from default method bodies

Previously, symbols from default method bodies were only looked up in the local scope of the file into which they were included. This resulted in compilation errors if said symbol wasn't available in the local scope.

Issues #3737 and #2150 were both examples of this problem.

We've updated definition lookup to check if the enclosing method is provided by a trait or interface and if it is, to also check to definition scope for any needed symbols.

Remove logger package from the standard library

The logger package is intentionally limited in its functionality and leans heavily into reducing messaging overhead between actors to the point of intentionally sacrificing functionality.

Our stated belief as a core team has been that the standard library isn't "batteries included". We have also stated that libraries were we believe it would be "relatively easy" for multiple competing standards to appear in the community shouldn't be included in the standard library unless other factors make inclusion important.

Some other factor we have discussed in the past include:

  • Not having a standard library version would make interop between different 3rd-party Pony libraries difficult.
  • The functionality is required or called for by an interface in one or more standard library classes.
  • We consider the having the functionality provided to be core to the "getting started with Pony experience".

We don't believe that any of above 3 points apply to the logger package. Therefore, we've removed logger from the standard library and turned it into it's own stand alone library.

If you were using the logger package, visit it's new home and follow the "How to Use" directions.

Fix call receiver type casting in LLVM IR

In some rare cases (such as in the PonyCheck library), ponyc was generating LLVM that did not use the correct pointer types for call site receiver arguments. This did not result in unsafe code at runtime, but it was still a violation of the LLVM type system, and it caused the "Verification" step of compilation to fail when enabled.

To fix this issue, we introduced an LLVM bitcast at such call sites to cast the receiver pointer to the correct LLVM type.

Rename ponybench package to match standard library naming conventions

We recently realized that when we renamed large portions of the standard library to conform with our naming standards, that we missed the ponybench package. To conform with the naming convention, the ponybench package as been renamed to pony_bench.

You'll need to update your test code from:

use "ponybench"

to

use "pony_bench"

Add PonyCheck to the standard library

PonyCheck, a property based testing library, has been added to the standard library. PonyCheck was previously its own project...

Read more

0.48.0

08 Feb 21:15
Compare
Choose a tag to compare

Add a pony primitive that exposes scheduler information

Previously, when users wanted to optimize the parallelizing work based on the maximum number of actors that can be run at a single time, we were pointing them to using the private runtime method @ponyint_sched_cores().

This was problematic for two reasons:

  1. We were pointing users at an internal implementation method that we hadn't promised not to change.
  2. We were requiring users to muck about with FFI for something that has become somewhat common for users wanting to maximize performance want to know.

We've now exposed some information about scheduler threads via a new package runtime_info thereby resolving both of the problems mentioned above.

Pony users should expect to see additional information added to the runtime_info package moving forward.

Anyone who was using the internal ponyint_sched_cores() FFI call will need to update to using runtime_info as the internal function has been removed.

Stop creating prebuilt ponyc releases for Ubuntu 21.04

Ubuntu 21.04 hit its end-of-life at the end of January 2022. We are no longer build prebuilt ponyc releases for it. If you are still using Ubuntu 21.04 and need ponyc for 21.04, you'll have to build from source.

The next Ubuntu LTS release is coming in April of 2022 and we'll be adding prebuilt ponyc for it. If have upgraded to a non-LTS Ubuntu after 21.04 that s still supported and would like us to do ponyc releases for it, please let us know via a GitHub issue or via the Ponylang Zulip.

Fix runtime crash when tracing class iso containing struct val

Prior to this fix, you could crash the runtime if you sent a val struct wrapper in an iso class. For example:

use "collections"

struct val Foo

class Bar
  let f: Foo = Foo

actor Main
  new create(env: Env) =>
    for i in Range(0, 20000) do
      inspect(recover Bar end)
    end

  be inspect(wrap: Bar iso) =>
    None // Do something with wrap.f

Revert "prevent non-opaque structs from being used as behaviour parameters"

The bug that #3781 aka "prevent non-opaque structs from being used as behaviour parameters" was an attempt at preventing, as only partially solved by the change.

We've introduced a full fix in #3993 that removes the need for #3871.

Update to LLVM 13.0.1

We've updated the LLVM used to build Pony to 13.0.1.

Remove out parameter from pony_os_stdin_read

The signature of the pony_os_stdin_read function has been simplified to remove the bool* out_again parameter.

-PONY_API size_t pony_os_stdin_read(char* buffer, size_t space, bool* out_again)
+PONY_API size_t pony_os_stdin_read(char* buffer, size_t space)

It is permitted to call the pony_os_stdin_read function again in a loop if the return value is greater than zero, and the platform is not windows. Given that those two conditions are enough information to make a decision, the out_again parameter is not needed, and can be removed.

Technically this is a breaking change, because the function is prefixed with pony_ and is thus a public API. But it is unlikely that any code out there is directly using the pony_os_stdin_read function, apart from the Stdin actor in the standard library, which has been updated in its internal implementation details to match the new signature.

Expose additional scheduler information in the runtime_info package

Three additional methods have been added to SchedulerInfo.

  • minimum_schedulers

Returns the minimum number of schedulers that will be active.

  • scaling_is_active

Returns if scheduler scaling is on

  • will_yield_cpu

Returns if scheduler threads are yielding the CPU to other processes when they have no work to do.

Add additional methods to itertools

Previously there were methods for Iter within itertools which, while originally planned, where not implemented. These methods have now been implemented.

The added methods are:

  • dedup which removes local duplicates from consecutive identical elements via a provided hash function
  • interleave which alternates values between two iterators until both run out
  • interleave_shortest which alternates values between two iterators until one of them runs out
  • intersperse which yields a given value after every n elements of the iterator
  • step_by which yields every nth element of the iterator
  • unique which removes global duplicates of identical elements via a provided hash function

[0.48.0] - 2022-02-08

Fixed

  • Fix runtime crash when tracing class iso containing struct val (PR #3993)

Added

  • Add a pony primitive that exposes scheduler information (PR #3984)
  • Expose additional scheduler info via the runtime_info package (PR #3988)
  • Add additional methods to itertools (PR #3992)

Changed

  • Stop creating prebuilt ponyc releases for Ubuntu 21.04 (PR #3990)
  • Revert "prevent non-opaque structs from being used as behaviour parameters" (PR #3995)
  • Update LLVM to 13.0.1 (PR #3994)
  • Remove out parameter from pony_os_stdin_read (PR #4000)

0.47.0

02 Feb 01:51
Compare
Choose a tag to compare

Remove simplebuiltin compiler option

The ponyc option simplebuiltin was never useful to users but had been exposed for testing purposes for Pony developers. We've removed the need for the "simplebuiltin" package for testing and have remove both it and the compiler option.

Technically, this is a breaking change, but no end-users should be impacted.

Fix return checking in behaviours and constructors

Our checks to make sure that the usage of return in behaviours and constructors was overly restrictive. It was checking for any usage of return that had a value including when the return wasn't from the method itself.

For example:

actor Main
  new create(env: Env) =>
    let f = {() => if true then return None end}

Would return an error despite the return being in a lambda and therefore not returning a value from the constructor.

Fix issue that could lead to a muted actor being run

A small logical flaw was discovered in the Pony runtime backpressure system that could lead to an actor that has been muted to prevent it from overloading other actors to be run despite a rule that says muted actors shouldn't be run.

The series of events that need to happen are exceedingly unlikely but we do seem them from time to time in our Arm64 runtime stress tests. In the event that a muted actor was run, if an even more unlikely confluence of events was to occur, then "very bad things" could happen in the Pony runtime where "very bad things" means "we the Pony developers are unable to reason about what might happen".

Remove library mode option from ponyc

From the very early days of the Pony runtime, a "library mode" has been around that allows you to compile a Pony program to a C compatible library that you can then start up using various runtime APIs to do things like initialize the runtime, create actors, send messages and more. We've made extensive changes to the runtime over the years and have no faith that library mode and its related functionality work.

Our lack of faith extends back many years and we've stated as the Pony core team that we don't consider library mode to be supported; until now, we haven't done anything about what "not supported" means.

With this release, library mode has been removed as an option.

Don't allow interfaces to have private methods

When Pony allowed interfaces to have private methods, it was possible to use an interface to break encapsulation for objects and access private methods from outside their enclosing package.

The following code used to be legal Pony code but will now fail with a compiler error:

actor Main
  new create(env: Env) =>
    let x: String ref = "sailor".string()
    let y: Foo = x
    y._set(0, 'f')
    env.out.print("Hello, " + x)

interface Foo
  fun ref _set(i: USize, value: U8): U8

If you were previously using interfaces with private methods in your code, you'll need to switch them to being traits and then use nominal typing on all the implementers.

For example:

interface Foo
  fun ref _bar()

would become:

trait Foo
  fun ref _bar()

And any objects that need to provide Foo would be changed from:

class ProvidesFoo

to

class ProvidesFoo is Foo

We believe that the only impact of this change will primarily be a single interface in the standard library AsioEventNotify and updates that need to be done to deal with it changing from an interface to a trait.

If you are unable to make the changes above, it means that you were taking the encapsulation violation bug we've fixed and will need to rethink your design. If you need assistance with such a redesign, please stop by the Pony Zulip and we'll do what we can to help.

Change builtin/AsioEventNotify from an interface to a trait

The "Don't allow interfaces to have private methods" change that is part of this release required that we change the AsioEventNotify interface to a trait.
If you are one of the few users outside of the standard library to be using the ASIO subsystem directly in your Pony code, you'll need to make an update to
conform to this change.

Where previously you had something like:

class AsioEventReceivingClass
  be _event_notify(event: AsioEventID, flags: U32, arg: U32) =>
    ...

You'll need to switch to using nominal typing rather than structural:

class AsioEventReceivingClass is AsioEventNotify
  be _event_notify(event: AsioEventID, flags: U32, arg: U32) =>
    ...

As far as we know, there are two codebases that will be impacted by this change:

Fix compiler assertion failure when assigning error to a variable

This release fixes a compiler assertion failure being triggered when one attempted to assign an error expression surrounded by parenthesis to a variable.

Add "nodoc" annotation

The can be used to control the pony compilers documentation generation, any structure that can have a docstring (except packages) can be annotated with \nodoc\ to prevent documentation from being generated.

This replaces a hack that has existed in the documentation generation system for several years to filter out items that were "for testing" by looking for Test and _Test at the beginning of the name as well as providing UnitTest or TestList.

Note that the "should we include this package" hack to filter oupackages called "test" and "builtin_test" still exists for the timbeing until we have further discussion.

[0.47.0] - 2022-02-02

Fixed

  • Fix return checking in behaviours and constructors (PR #3971)
  • Fix issue that could lead to a muted actor being run (PR #3974)
  • Fix loophole that allowed interfaces to be used to violate encapsulation (PR #3973)
  • Fix compiler assertion failure when assigning error to a variable (PR #3980)

Added

Changed

  • Remove simplebuiltin compiler option (PR #3965)
  • Remove library mode option from ponyc (PR #3975)
  • Change builtin/AsioEventNotify from an interface to a trait (PR #3973)
  • Don't allow interfaces to have private methods (PR #3973)
  • Remove hack that prevented documentation generation for "test classes" (PR #3978)

0.46.0

16 Jan 03:11
Compare
Choose a tag to compare

Stop creating Centos 8 releases

CentOS 8 has been end-of-lifed and will be receiving no further updates. As per our policy, we will no longer be building regular releases for CentOS 8. Existing releases can still be installed via ponyup, but no additional releases will be done.

Our CentOS 8 support has been replaced by support for Rocky 8.

Hide C header implementation details related to actor pad size.

Previously, in the pony.h header that exposes the "public API" of the Pony runtime, information about the size of an actor struct was published as public information.

This change removes that from the public header into a private header, to hide
implementation details that may be subject to change in future versions of the Pony runtime.

This change does not impact Pony programs - only C programs using the pony.h header to use the Pony runtime in some other way than inside of a Pony program, or to create custom actors written in C.

Change type of Env.root to AmbientAuth

Previously, Env.root currently had the type (AmbientAuth | None) to allow for creation of artificial Env instances without AmbientAuth. Yet, there was no observable usage of this feature. It required extra work to make use of, as one always needs a pattern match or an as expression with a surrounding try. We've changed Env.root to only be AmbientAuth, no longer requiring a pattern match or a try.

To adjust your code to take this breaking change into account, you'd do the following. Where you previously had code like:

    try
      TCPListener(env.root as AmbientAuth, Listener(env.out))
    else
      env.out.print("unable to use the network")
    end

You can now do:

    TCPListener(env.root, Listener(env.out))

The same change can be made if you were pattern matching on the type of env.root.

[0.46.0] - 2022-01-16

Changed

  • Stop creating CentOS 8 prebuilt ponyc releases (PR #3955)
  • Hide C header implementation details related to actor pad size. (PR #3960)
  • Change type of Env.root to AmbientAuth (PR #3962)

0.45.2

01 Jan 01:06
Compare
Choose a tag to compare

Clarify wording for some subtyping errors

The wording of a small number of errors relating to the subtyping of capabilities were improved.
These were previously technically incorrect, or otherwise unnecessarily obtuse.

Fix inability to fully build pony on Raspberry PI 4's with 64-bit Raspbian

Building on 64-bit Raspbian needs the flag -fPIC instead of -fpic which is used by default on Unix builds.

We've added a Makefile flag pic_flag that you can set to either -fpic or -fPIC for both libs and configure steps, e.g. make libs pic_flag=-fPIC and make configure pic_flag=-fPIC. It will default to -fpic if not specified.

Added build instructions for 64-bit Raspbian

We've gotten Pony building on 64-bit Raspbian running on Raspberry Pi 4 model B boards. The installation is a little different than other Linux distributions that you can build Pony on, so we've added instructions specific to 64-bit Raspbian.

0.45.1

02 Dec 22:33
Compare
Choose a tag to compare

Fix underlying time source for Time.nanos() on macOS

Previously, we were using mach_absolute_time on macOS to get the number of ticks since boot, with the assumption that ticks increment at nanosecond intervals. However, as noted by Apple, this assumption is flawed on Apple Silicon, and will also affect any binaries that were built on Intel, as the Rosetta 2 translator will not apply any time conversion.

The recommended replacement to mach_absolute_time is to use clock_gettime_nsec_np with a clock of type CLOCK_UPTIME_RAW.

Fix cli package from mangling option arguments with equal signs

The current command parser in the cli package cuts option arguments of String type at the first equal sign. This release fixes the problem for long options (--option=foo=bar) and for short options such as -O=foo=bar. Short options such as -Ofoo=bar will continue to raise an "ambiguous args" error.

The code below shows the bug, with the option argument being cut short at the first equal sign. The code below prints "foo" instead of the complete value, "foo=bar". The same is true when uses the short version of the option, like -t=foo=bar.

use "cli"

actor Main
  new create(env: Env) =>
    try
      let cs =
        CommandSpec.leaf("simple", "", [
          OptionSpec.string("test" where short' = 't')
        ])?
      
      let args: Array[String] = [
        "ignored"; "--test=foo=bar"
      ]
      let cmdErr = CommandParser(cs).parse(args) as Command
      env.out.print(cmdErr.option("test").string())
    end

[0.45.1] - 2021-12-02

Fixed

  • Fix underlying time source for Time.nanos() on macOS (PR #3921)
  • Fix cli package from mangling option arguments with equal signs (PR #3925)