Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clarify language and add notes what types of allocation patterns are acceptable. #2

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions Design.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,18 +49,19 @@ Hence, invalid Unicode will be ignored when practical, and if not practical the

If the user chooses, a separate adapter can be used to detect invalid Unicode and handle it as desired.

### No Memory Allocation
### Avoid Memory Allocation

Enormous troubles and inefficiencies stem from general purpose library code allocating memory as the library sees fit. This makes the library code far less usable. Memory allocation strategies should be decided upon by the user of the library, not the library.

The easiest way to achieve this is to design the library to not use memory allocation at all. For example, std.path assembles paths from parts without doing allocations - it returns Voldemort ranges that the user can then use to emit the result into a buffer of the user's choosing.

Library routines may allocate memory internally, but not in a way that affects the user.
In cases where allocation is necessary, Library routines may allocate memory internally, in such a way that it does not effect the user. Additionally, allocation patterns that use internal allocations, such as Dependency Injection, may be used to allocate. Note that this may require compiler support to fully implement.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/effect/affect/.

What requires compiler support?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am just leaving the door open to potential future cases.


### No Exceptions
### Avoid Exceptions

Exceptions are inefficient and use the GC. Of course, they cannot be used in `nothrow` code. Examine each use of an Exception to see if it can be designed out of existence, like the Replacement Character method above. Design the return value such that an error is not necessary - for example, a string search function can return an empty string if not found rather than throw an Exception.
Investigate the use of Option types for error returns.

Investigate the use of "Option" or "Sum" types for error returns.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem with this is that bubbling up errors becomes a pain.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, value type exceptions aka zero cost exceptions would be the option here as it'll bubble up.

Waiting on sumtypes before continuing that DIP work.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem with this is that bubbling up errors becomes a pain.

How about polymorphic variants? That's a good idea from OCaml. See: https://keleshev.com/composable-error-handling-in-ocaml

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need to wait for built-in sum types to address this. Ideally, any solution we come up with for the error-bubbling problem would apply equally well to built-in types and library types (like how Rust's ? operator can be overloaded by implementing the Try trait).


### Header Only

Expand Down