Skip to content

Commit 84f8121

Browse files
committed
docs: describe changelog
1 parent 981e3b0 commit 84f8121

File tree

1 file changed

+38
-0
lines changed

1 file changed

+38
-0
lines changed

CHANGELOG.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# CHANGELOG
2+
3+
## 2.0.0
4+
5+
- Nodes can now have arbitrary numbers of children, not just binary trees. This was designed in such a way to have identical performance to the previous version. Essentially, the `Node{T,D}` type is a wrapper around a tuple of `D` children.
6+
- Note that `Node{T}` automatically converts to `Node{T,2}` in many contexts, for backwards compatibility.
7+
- Node type signature changed from `Node{T}` to `Node{T,D}`. Usually `D` is 2.
8+
- Direct property access `.l` and `.r` is automatically forwarded to `get_child(tree, 1)` and `get_child(tree, 2)`,
9+
but it is recommended to use the generic accessors instead.
10+
- Similarly, `.l = child` should be replaced with `set_child!(tree, child, 1)` and similar for `.r`.
11+
- All internal code migrated to use generic accessors.
12+
13+
### Backwards Compatibility
14+
15+
- Existing `.l` and `.r` access continues to work without warnings
16+
17+
### Breaking Changes
18+
19+
The only breaking change is if:
20+
21+
1. You have any types that are subtyped to `<:AbstractExpressionNode{T}` or `<:AbstractNode{T}`. These should now be subtyped to `<:AbstractExpressionNode{T,2}` or `<:AbstractNode{T,2}`. You may also allow a `D` parameter in case you want to support higher-arity trees.
22+
2. You assume a tree has type, e.g., `=== Node{T}`, rather than `<: Node{T}`. So any methods dispatched to `::Type{Node{T}}` will also break. (To be safe you should always use a form `<: Node{T}` in case of future type changes - in any library.)
23+
3. You assume `tree.degree <= 2` in conditional logic, and your code interacts with a tree that is _not_ a binary tree. For example, the following pattern was common before this change:
24+
25+
```julia
26+
if tree.degree == 0
27+
#= operations on leaf node =#
28+
elseif tree.degree == 1
29+
#= operations on unary node =#
30+
else
31+
# BAD: ASSUMED TO BE BINARY
32+
#= operations on binary node, using `.l` and `.r` only =#
33+
end
34+
```
35+
36+
This will obviously break if you pass a tree that is not binary, such as `tree::Node{T,3}`.
37+
- To fix this, you can use the `get_children` function to get the children of the tree as a tuple of `D` children, and then index up to `tree.degree`.
38+
- Inside DynamicExpressions, we commonly use `Base.Cartesian.@nif` to generate code for different degrees, to avoid any unstable types.

0 commit comments

Comments
 (0)