Skip to content

Releases: ponylang/ponyc

0.54.0

27 Feb 16:14
Compare
Choose a tag to compare

Enable building of libponyc-standalone on MacOS

We now ship a "standalone" version of libponyc for MacOS. libponyc-standalone allows applications to use Pony compiler functionality as a library. The standalone version contains "all dependencies" needed in a single library. On MacOS, sadly "all dependencies" means "all that can be statically linked", so unlike Linux, dynamically linking to C++ standard library is required on MacOS.

An example pony program linking against it would need to look like this:

use "lib:ponyc-standalone" if posix or osx
use "lib:c++" if osx

actor Main
  new create(env: Env) =>
    None

Update DTrace probes interface documentation

Our DTrace probes needed some care. Over time, the documented interface and the interface itself had drifted. We've updated all probe interface definitions to match the current implementations.

Improve usability of some DTrace probes

A number of runtime DTrace probes were lacking information required to make them useful. The probes for:

  • GC Collection Starting
  • GC Collection Ending
  • GC Object Receive Starting
  • GC Object Receive Ending
  • GC Object Send Starting
  • GC Object Send Ending
  • Heap Allocation

All lacked information about the actor in question. Instead they only contained information about the scheduler that was active at the time the operation took place. Without information about the actor doing a collection, allocating memory, etc the probes had little value.

Remove ambiguity from "not safe to write" compiler error message

Previously, when displaying the "not safe to write" error message, the information provided was incomplete in a way that lead to ambiguity. A "not safe to write" error involves two components, the left side type being assigned to and the right side type being assigned to the left side. We were only displaying the right side, not the left side type, thus making it somewhat difficult to know exactly what the error was.
As an example, when trying to write to a field in an iso class instance, we get:

Error:
/Users/jairocaro-accinoviciana/issues-pony-4290/demo.pony:10:11: not safe to write right side to left side
    x.foo = foo
          ^
    Info:
    /Users/jairocaro-accinoviciana/issues-pony-4290/demo.pony:9:14: right side type: Foo ref
        let foo: Foo ref = Foo
                 ^

The updated error message is now in the format:

Error:
/Users/jairocaro-accinoviciana/issues-pony-4290/demo.pony:10:11: not safe to write right side to left side
    x.foo = foo
          ^
    Info:
    /Users/jairocaro-accinoviciana/issues-pony-4290/demo.pony:9:14: right side type: Foo ref
        let foo: Foo ref = Foo
                 ^
    /Users/jairocaro-accinoviciana/issues-pony-4290/demo.pony:10:5: left side type: X iso
        x.foo = foo
        ^

Stop building "x86-64-unknown-linux-gnu" packages

Previously we built a "generic gnu" ponyc package and made it available via Cloudsmith and ponyup. Unfortunately, there is no such thing as a "generic gnu" ponyc build that is universally usable. The ponyc package only worked if the library versions on your Glibc based Linux distribution matched those of our build environment.

We've stoped building the "generic gnu" aka "x86-64-unknown-linux-gnu" packages of ponyc as they had limited utility and a couple of different ways of creating a very bad user experience. Please see our Linux installation instructions for a list of Linux distributions we currently create ponyc packages for.

Enable building of libponyc-standalone on Windows

We now ship a "standalone" version of libponyc for Windows. libponyc-standalone allows applications to use Pony compiler functionality as a library. The standalone version contains "all dependencies" needed in a single library. This library doesn't contain C or C++ runtime libs, as those get linked into every Pony program during compilation on Windows.

An example pony program linking against it on Windows would need to look like this:

use "lib:ponyc-standalone" if posix or osx or windows
use "lib:c++" if osx

actor Main
  new create(env: Env) =>
    None

Remove json package from the standard library

We accepted an RFC to remove the json package from the standard library.

Per the RFC, the motivation for removal was:

The json package is a regular source of difficult for Pony users. It is an ok API for some JSON handling needs and a poor API for other needs. The package
parses a String representation of some JSON into a mutable tree of objects.

This mutable tree is excellent for modifying the JSON, it is also an excellent representation for constructing a JSON document. However, it makes parsing a String into an shareable data structure that can be sent between actors very difficult.

The Pony ecosystem would be better served by not having an "official" JSON library that is part of the standard library. We would be better of by encouraging many different libraries that approach the problem differently. Sometimes, a purely functional approach like that taken by jay is called for. Other times, an approach that tightly controls memory usage and other performance oriented characteristics is better as seen in pony-jason.

Having the current json package in the standard library given all its failings is a bad look. Better to have someone ask "what's the best way to handle JSON" then to blindly start using the existing package.

The existing package could be improved and it is best improved outside of the standard library and RFC process. The RFC process intentionally moves slowly. The json package is at best "beta" level software and would be greatly enhanced by a process that allows for more rapid change and experimentation. Further, it isn't essential to the community that a JSON library be part of the standard library. There's no cross library communication mechanism that depends on the existence of a standard JSON handling interface.

The library version of the json library is now available at https://github.com/ponylang/json.

Fix waiting on Windows to properly admit I/O events

Previously, on Windows, we were calling WaitForSingleObject rather than WaitForSingleObjectEx when putting scheduler threads to sleep. This could have caused Windows I/O events to be missed.

[0.54.0] - 2023-02-27

Fixed

  • Remove ambiguity from "not safe to write" compiler error message (PR #4299)
  • Fix waiting on Windows to be sure I/O events can still come in. (PR #4325)

Added

  • Create libponyc-standalone on MacOS (PR #4303)
  • Build ponyc-standalone.lib for windows (PR #4307)

Changed

  • Update DTrace probes (PR #4302)
  • Stop building the "x86-64-unknown-linux-gnu" ponyc package (PR #4312)
  • Remove json package from the standard library ([PR #4323])(#4323)

0.53.0

04 Jan 21:47
Compare
Choose a tag to compare

Introduction of empty Ranges

Previously, it was easy to accidentally create infinite Ranges due to the implementation giving precedence to parameters min and inc and the iterative relationship that the next value be idx + inc where idx starts equal to min. Iteration stopped when idx was equal to or passed max. This resulted in infinite ranges when either 1) the inc was 0, or any of min, max, or inc were NaN, +Inf or -Inf, or 2) if no progress could be made from min to max due to the sign of inc. Therefore, even a seemingly correct range such as Range[ISize](-10, 10, -1) would be infinite -- producing values -10, -11, -12, ... rather than moving between values -10 and 10, as might be expected. In order to avoid this possible error of seemingly correct ranges, we decided to introduce empty ranges which produce no values and reclassify much of what was previously infinite to instead be empty. There are now three mutually exclusive classifications for ranges: finite, infinite, and empty ranges. Finite ranges will produce some number of values before terminating, infinite ranges will never terminate, and empty ranges will immediately terminate due to having no values.

User Code Changes

We conducted a search of public Pony code and it appears that the vast majority of Range usage should not require any changes. The most likely required change is any infinite Range producing an infinite iterator of a single value; for this we recommend switching to use of Iter[A].repeat_value(value) from the itertools package.

The only remaining infinite ranges are a positive and negative towards their respective infinities, so any code that previously relied on an infinite iterator will need to change. For example, any code that previously flipped the sign of the iterator or max parameter as a way to iterate in a given direction infinitely will need to change.

Previously, the code below would iterate infinitely.

// This code will no longer work
let nan = F64(0) / F64(0)
for i in Range[F64](nan) do
  // Previously infinite in the positive direction
end

Will now need to be specified as follows.

let inf = F64.max_value() + F64.max_value()
for i in Range[F64](0, inf) do
  // Infinite in the positive direction
end

We can flip this relationship for a negative iterator.

let inf = F64.max_value() + F64.max_value()
for i in Range[F64](0, -inf, -1) do
  // Infinite in the negative direction
end

Fix infinite loop in compiler

The following program used to cause an infinite loop in the compiler:

type Message is (String, String, None)

interface tag Manager
  be handle_message(msg: Message val)

actor Main
  new create(env: Env) =>
    Foo(env, recover tag this end)

  be handle_message(msg: Message val) =>
    None

actor Foo
  var manager: Manager

  new create(env: Env, manager': Manager) =>
    manager = manager'
    let notifier = InputNotifier(this)
    env.input(consume notifier)

  be handle_data(data: String) =>
    manager.handle_message(("","",None))

class InputNotifier is InputNotify
  let parent: Foo

  new iso create(parent': Foo) =>
    parent = parent'

  fun ref apply(data': Array[U8 val] iso) =>
    parent.handle_data("")

Fix compiler segfault caused by infinite recursion

The following program used to cause ponyc to segfault due to infinite recursion:

type Message is ((I64 | String), String, None)

interface tag Manager
  be handle_message(msg: Message val)

actor Main
  new create(env: Env) =>
    Foo(env, recover tag this end)

  be handle_message(msg: Message val) =>
    None

actor Foo
  var manager: Manager

  new create(env: Env, manager': Manager) =>
    manager = manager'
    let notifier = InputNotifier(this)
    env.input(consume notifier)

  be handle_data(data: String) =>
    manager.handle_message(("","",None))

class InputNotifier is InputNotify
  let parent: Foo

  new iso create(parent': Foo) =>
    parent = parent'

  fun ref apply(data': Array[U8 val] iso) =>
    parent.handle_data("")

Fix runtime segfault

A segfault was introduced in "Fix segfault caused by unsafe garbage collection optimization". tag objects were being incorrectly traced which could eventually result in a segfault.

If you are using Pony version 0.52.3 to 0.52.5, we recommend upgrading as soon as possible.

[0.53.0] - 2023-01-04

Fixed

  • Fix infinite loop in compiler (PR #4293)
  • Fix compiler segfault caused by infinite recursion (PR #4292)
  • Fix runtime segfault (PR #4294)

Changed

0.52.5

30 Dec 20:53
Compare
Choose a tag to compare

Fix compiler crash when attempting to mutate a val field

In Pony 0.52.4 we fixed an unsoundness bug that had been introduced over the summer. While fixing that bug, an error case was missed and as a result, a compiler crash was created where an error message should have been generated.

We've fixed the crash and it now displays a "left side is immutable" error message.

[0.52.5] - 2022-12-30

Fixed

0.52.4

29 Dec 11:07
Compare
Choose a tag to compare

Fix crash when handling parameters with invalid types

Fixes a compiler assert when checking a parameter for autorecovery that has an invalid type.

Fix some infinite loops during typechecking

Some recursive constraints could cause the typechecker to go into
an infinite loop while trying to check subtyping. These infinite
loops have now been fixed. An example program that demonstrates
the issue is below:

primitive Foo[T: (Unsigned & UnsignedInteger[T])]
  fun boom() =>
    iftype T <: U8 then
      None
    end

actor Main
  new create(env: Env) =>
    Foo[U8].boom()

The use of T: UnsignedInteger[T] is valid and expected, but wasn't
being handled correctly in this situation by the typechecker in this context.

Fix a major bug which allowed mutating fields of a val object

A bug was introduced in 0.51.2 which caused some checks to allow mutating fields of a val object due to changes to some operations on capabilities. This bug is fixed: immutability is now checked separately from other properties.

If you are using Pony 0.51.2 to 0.52.3, you should upgrade to the 0.52.4 release that contains this fix as soon as possible.

[0.52.4] - 2022-12-29

Fixed

  • Fix an assert in call.c when checking an invalid argument for autorecover (PR #4278)
  • Fix an issue with infinite loops while typechecking some expressions (PR #4274)
  • Fix soundness bug introduced in Pony 0.51.2 (PR #4283)

0.52.3

16 Dec 13:01
Compare
Choose a tag to compare

Deprecate macOS on Intel support

We have moved macOS on Intel from being a fully supported platform to a best effort platform. We are no longer providing prebuilt ponyc binaries for macOS on Intel. We also no longer do any CI testing using macOS on Intel. We are not planning on intentionally breaking macOS on Intel but supporting it is no longer a priority.

Fix segfault caused by unsafe garbage collection optimization

Prior to this change, there was an unsafe optimization in the Pony runtime. The optimization is detailed in the ORCA paper on the garbage collection protocol and is usually safe, but sadly not always.

The optimization cuts down on the amount of tracing that is done when an object is sent from one actor to another. It is based on the observation that for the sake of reference counting, we don't need to count every object in a graph that is sent from actor A to actor B so long as the root of the graph being sent is immutable. This optimization provides a large performance boost over tracing all objects sent from one actor to another. It also will from time to time, introduce a segfault that takes down the runtime.

Issue #1118 is the most obvious instance of the bug caused by the optimization. The core of the problem is that when an actor's reference count hits 0, it should be able to be reaped. However, if a reference to an actor is sent to another actor inside an immutable object, the actor will not be traced on send and might get reaped while references to it exist. Once that happens, a segfault is guaranteed.

We have fixed the safety problem by tracing every object sent between actors. In not very rigorous testing using a modified version of message-ubench, we saw a 1/3 drop in performance compared to running with the safety problem/optimization enabled. It should be noted that the 1/3 drop in performance is probably the high-end in terms of performance hit and many Pony programs will see little to no performance change.

Our plan moving forward is to start adding smarts to the compiler in an incremental fashion so that we can turn the "problematic optimization" back on when it isn't problematic. We will never recover "all lost performance" because there are times when the optimization is unsafe and no amount of compiler smarts will allow us to turn the optimization on in those situations. We can however, over time, turn the optimization back on for more and more types. We expect this process to take a while and welcome community involvement in the project.

Fix "Don't include 'home file' in documentation search"

PR #4243 incorrectly implemented the "don't include 'home file' in documentation search". It has been fixed.

The original release notes are now accurate (before it wasn't working!):

We've updated the documentation generation to not include the "home file" that lists the packages in the search index. The "exclude from search engine" functionality is only available in the mkdocs-material-insiders theme.

The home file is extra noise in the index that provides no value. For anyone using the insiders theme, this will be an improvement in the search experience.

[0.52.3] - 2022-12-16

Fixed

  • Fix segfault caused by unsafe garbage collection optimization (PR #4256)
  • Fix incorrectly implemented PR #4243 (PR #4276)

Changed

  • Remove macOS on Intel as a supported platform (PR #4270)

0.52.2

01 Dec 13:53
Compare
Choose a tag to compare

Don't include generated documentation "home file" in search index

We've updated the documentation generation to not include the "home file" that lists the packages in the search index. The "exclude from search engine" functionality is only available in the mkdocs-material-insiders theme.

The home file is extra noise in the index that provides no value. For anyone using the insiders theme, this will be an improvement in the search experience.

Add support for erase left and erase line in term.ANSI

We've implemented RFC #75 that set out a means of updating ANSI in the term package to support not just ANSI erase right, but also erase left, and erase line.

Existing functionality continues to work as is. All existing erase right functionality will continue to work without breakage. The erase method has been augmented to take an option parameter for the direction to erase. EraseRight is the default, thus keeping existing behavior. EraseLeft and EraseLine options have been added as well.

To erase left, one would do:

ANSI.erase(EraseLeft)

To erase right, you could do either of the following:

ANSI.erase()
ANSI.erase(EraseRight)

And finally, to erase an entire line:

ANSI.erase(EraseLine)

Improve TCP Backpressure on Windows

Our prior setting of backpressure for TCP writes on Windows was naive. It was based purely on the number of buffers currently outstanding on an IOCP socket. The amount of data didn't matter at all. Whether more data could be accepted or not, also wasn't taken into consideration. We've enhanced the backpressure support at both the Pony level in TCPConnection and in the runtime API.

Two runtime API methods have been updated on Windows.

pony_os_writev

The Windows version of pony_os_writev will now return the number of buffers accepted or zero if backpressure is encountered. All other errors still cause an error that must be handled on the Pony side of the API via a try block.

pony_os_send

The Windows version of pony_os_send will now return the number of bytes accepted or zero if backpressure is encountered. All other errors still cause an error that must be handled on the Pony side of the API via a try block.

The changes are considered non-breaking as previously, the return values from both functions had no meaning.

Fix multiple races within actor/cycle detector interactions

The Pony runtime includes an optional cycle detector that is on by default. The cycle detector runs and looks for groups of blocked actors that will have reference counts above 0 but are unable to do any more work as all members are blocked and don't have additional work to do.

Over time, we have made a number of changes to the cycle detector to improve it's performance and mitigate its impact on running Pony programs. In the process of improving the cycle detectors performance, it has become more and more complicated. That complication led to several race conditions that existed in the interaction between actors and the cycle detector. Each of these race conditions could lead to an actor getting freed more than once, causing an application crash or an attempt to access an actor after it had been deleted.

We've identified and fixed what we believe are all the existing race conditions in the current design.

Update supported FreeBSD to 13.1

Prebuilt FreeBSD ponyc binaries are now built for FreeBSD 13.1. All CI is also done using FreeBSD 13.1. We will make a "best effort" attempt to not break FreeBSD 13.0, but the only supported version of FreeBSD going forward is 13.1.

Previously built ponyc versions targeting FreeBSD 13.0 will continue to be available.

Drop Rocky 8 support

In July of 2021, we added prebuilt binaries for Rocky 8. We did this at the request of a ponyc user. However, after attempting an update to get Rocky 8 building again, we hit a problem where in the new CI environment we built, we are no longer able to build ponyc. We do not have time to investigate beyond the few hours we have already put in. If anyone in the community would like to get the Rocky 8 environment working again, we would be happy to add support back in.

The current issue involves libatomic not being found during linking. If you would like to assist, hop into the CI stream on the ponylang Zulip.

Fix compiler crash when calling (this.)create()

Fixed a crash when calling .create() (with an implicit this).

[0.52.2] - 2022-12-01

Fixed

  • Fix multiple races within actor/cycle detector interactions (PR #4251)
  • Fix crash when calling (this.)create() (PR #4263)

Added

  • Don't include "home file" in documentation search (PR #4243)
  • Add support for erase left and erase line in term.ANSI (PR #4246)

Changed

  • Improve TCP backpressure handling on Windows (PR #4252)
  • Update supported FreeBSD to 13.1 (PR #4185)
  • Drop Rocky 8 support (PR #4262)

0.52.1

14 Nov 18:05
Compare
Choose a tag to compare

"Exclude source files" from documentation source

In the previous ponyc release, we updated the default theme used by our documentation generation from a custom theme based on mkdocs-material to using the latest mkdocs-material. With the change came the possibility of using all the latests mkdocs-material features. Mkdocs-material is a heavily developed theme that has a ton of great features. Some of mkdocs-material's features are only available to sponsors of the project.

One of the many excellent insider's features is the ability to exclude some files from the mkdocs search index. We've added support for this feature in the generated documentation so that, iff you are a mkdocs-material sponsor, the source code files that we link to from generated documentation will no longer be included in the source index.

If you've used our generated documentation extensively, you know that having the source implementation linked is a great boon, but it is also a pain as it clutters up the search index and you often end up on a source implementation page from a search.

If you are using the built in documentation generation that comes with ponyc, we suggest that you take a look into becoming a sponsor of mkdocs-material as we will be adding support for additional insiders features if folks find them to be useful as part of the generated documentation.

[0.52.1] - 2022-11-14

Added

  • Update docgen to generate source files that are ignored (PR #4239)

0.52.0

10 Nov 20:24
Compare
Choose a tag to compare

Fixed an overflow in Time.nanos() values on Windows

Based on how were were calculating nanos based of the QueryPerformanceCounter and QueryPerformanceFrequency on Windows, it was quite likely that we would eventually overflow the U64 we used to represent nanos and "go backwards in time".

Fix incorrect interaction between String/Array reserve and Pointer realloc

This was an interesting one. So, there's was an interesting interaction between String and Array's reserve and Pointer's realloc. Generally, it went like this:

reserve when it called realloc would give realloc a single value, the size of the newly reserved chunk of memory. This would result in realloc copying not just the in-use items from old memory to newly allocated memory, but in fact, the entire old memory chunk.

This could lead to very surprising results if reserve had been called by undefined. And in general, it could lead to suboptimal performance as we could end up copying more than was needed.

realloc has been updated to take to parameters, now, the amount of memory to alloc and the number of bytes to copy from old memory to new.

Sort package types in documentation

In order to make documentation on a class, actor, primitive or struct easier to find, they are now sorted alphabetically inside their package.

Adapt documentation generation to only depend the mkdocs material theme

We used to have our own mkdocs theme for ponylang documentation, it was based off of the mkdocs-material theme. This change puts the adaptations we need into the mkdocs.yml file itself, so we don't depend on our own theme anymore, but only on the upstream mkdocs-material. This eases the maintenance burden by not having to catch up with the material theme codebase.

This is a Breaking Change in so far that users that want to generate documentation with ponyc now have to install the python package mkdocs-material instead of mkdocs-ponylang to generate their documentation in HTML form with mkdocs. The library documentation github action will have the correct dependencies installed, so no changes should be needed when using it.

Fix broken documentation generation on Windows

Generating documentation has been broken on Windows: ponyc was not able to write the documentation files, due to path handling issues on Windows. This is now fixed and documentation generation is working again on Windows.

[0.52.0] - 2022-11-10

Fixed

  • Avoid fairly easy to trigger overflow in Windows Time.nanos code (PR #4227)
  • Fix incorrect interaction between String/Array reserve and Pointer realloc (PR #4223)
  • Fix broken documentation generation on Windows (PR #4226)

Changed

  • Sort package types in documentation (PR #4228)
  • Adapt documentation generation to use the mkdocs material theme (PR #4226

0.51.4

29 Oct 10:14
Compare
Choose a tag to compare

Reverts Ansi.erase to erase to the right, not the left

With the release of 0.49.0, we changed Ansi.erase to be erasing left rather than right. This made sense based on the comment on the Ansi.erase method. However, the actual usage in the standard library of Ansi.erase was expecting it to erase to the right. Because of this change, since 0.49.0, the readline support in the term package has been broken.

We've reverted the changes from the original PR and updated the comment on Ansi.erase to note that it erases to right, not the left.

We would welcome an RFC to discuss supporting both left and right erasure as part of the Ansi primitive.

[0.51.4] - 2022-10-29

Fixed

  • Fix broken readline package (PR #4199)

0.51.3

02 Oct 12:07
Compare
Choose a tag to compare

Fix bug in StdStream.print

When printing via StdStream.print strings containing null bytes, the standard library was printing the string until the first null byte and then padding the printed string with space characters until the string size was reached.

This bug was introduced in Pony 0.12.0 while fixing a different printing bug.

We've fixed the bug so that printing strings with null bytes works as expected.

Enhance checking for identity comparison with new objects

Consider the following program:

class C

actor Main
  new create(env: Env) =>
    env.out.print(if C is C then "C is C" else "C is NOT C" end)

This will fail to compile with the message identity comparison with a new object will always be false.

Nevertheless, the checking wasn't exhaustive and some cases weren't covered, like the one in the following example:

class C

actor Main
  new create(env: Env) =>
    env.out.print(if C.create() is C.create() then "C is C" else "C is NOT C" end)

We've made the check exhaustive and we believe it now covers all possible cases.

[0.51.3] - 2022-10-02

Fixed

  • Fix bug in StdStream.print (PR #4180)
  • Fix identity comparison check with desugared creations (PR #4182)