Between 0.2.0 and 0.3.0 the focus moved from growing the function library
to running real notebooks: Woxi Studio executes complete Wolfram
Demonstrations end to end, the plotters draw what wolframscript draws, and
hundreds of conformance and robustness fixes — many found by differential
fuzzing against wolframscript — closed gaps between the two engines.
Windows became a supported platform with prebuilt binaries. The list only
includes the most prominent changes; the Demonstration-driven fixes are
described in detail in the last section.
Woxi Studio & Wolfram Demonstrations
- Woxi Studio opens and runs complete Wolfram Demonstration notebooks end
to end — including definition notebooks and notebooks with embedded
raster photos — and re-instantiates storedManipulatewidgets when a
notebook is reopened. Demonstrations such as Kepler's Second Law,
Parabolic Mirror, Doyle Spirals, Dedekind Cut, Damped Forced Pendulum
and Merging Schools of Fish serve as end-to-end tests. Manipulatecovers the Demonstrations control vocabulary: interactive
Locators (withLocatorAutoCreate),Trigger,Button,
ButtonBar,SetterBar,PopupMenu,Checkbox/CheckboxBar,
Toggler,Opener/OpenerBar, controls nested inTabView,
PaneSelectororGridlayouts, per-controlControlTypelists,
dynamic control bounds, controls depending on other controls,
TrackedSymbols,Animatebodies andAnimationRunning.- Typeset notebook input is read back as code: inline box syntax, typeset
Sum/Productboxes, the partial-derivative operator,Partwritten
as a bracketed subscript, the radical prefix operators, and the×
and÷characters.
Plotting & graphics
- List plots grew
Arounderror bars,IntervalMarkers -> "Bands",
CalloutandLabeledwrappers,PlotMarkers,Epilog,Filling
(including between datasets),FillingStyle,DataRange,
InterpolationOrder,Mesh -> Full,PlotLayout, association keys
as point labels, andTimeSeriesinput;ComplexListPlotand
ListLinePlot3Dare new. PlotsupportsBackground,Evaluated,EvaluationMonitorand
Infinityendpoints; automatic ticks match Wolfram's algorithm, tick
labels switch to scientific notation outside[10^-5, 10^6), frames
takeFrameLabelcaptions andAxesLabelsits at the end of its
axis. Contour and density plots fix the marching-squares case table,
draw their mesh, and keep their shading throughShow.- Graphics primitives and options: polygons with holes (and their
measures),Arrowheads,Tube,CapForm,Textoffsets,
TranslateandScalein SVG export,Framed/Highlighted
rendering, andAspectRatioapplied to the plotting area rather than
the whole image. - Graphics3D draws curved surfaces without facet edges, triangulates
concave polygons, honoursEdgeForm[],SphericalRegionand
ViewAngle, and outlines flat faces the way Wolfram does.
PolyhedronDatagained face lists with Wolfram's vertex order and
the icosahedral Archimedean solids. - Exported SVG embeds the fonts it uses, renders
TableForm/MatrixForm
and the display-form wrappers as grids, and shows machine reals at
six significant figures.
Calculus, algebra & equation solving
Integratelearned the antiderivatives of the error, Fresnel, inverse
hyperbolic and exponential-integral families,Sin/Cos[x^2]to
Fresnel integrals,Exp[a x^2]toErfi,1/Log[x]to
LogIntegral, trigonometric integrals over a linear term to
Si/Ci,u = x^nsubstitution, Euler's log-trig definite
integrals andAbsof a linear argument.NIntegratehandles
endpoint singularities, multi-segment ranges and iterated
multi-dimensional integrals (NSum/NProductlikewise).- Differentiation covers
Piecewise,HeavisideTheta(toDiracDelta,
with its scaling law),KroneckerDelta,Floor/Ceiling, argument
derivatives of the Bessel and Hankel functions,PolyLog,
ExpIntegralE, the Airy primes and the incomplete elliptic
integrals, plus the fractionalCaputoD. SeriesexpandsGammaat its pole,Zetaat 1 (Laurent) and
algebraic expressions atInfinity; limits are decided from the
leading exponent at infinity, andMaxLimit/MinLimithandle
bounded trigonometric oscillations.- Solving:
x^n == cin radicals, polynomials with machine-real
coefficients, systems over a modulus,ModulusandMaxRoots
options,NSolvedomain argument,NSolveValues,SolveValues
result shaping, andReduceover higher-degree polynomial
inequalities.DSolvehandles non-constant forcing and orders its
fundamental pairs;NDSolvesolves systems and constrained ODEs;
RSolvesolves the logistic map atr = 4and golden-ratio
recurrences in the Fibonacci/Lucas basis. - Optimization:
LinearProgramming(exact simplex solver with variable
bounds), constrainedFindMinimum/FindMaximum/NArgMin/NArgMax,
the domain argument,NonlinearModelFit, constrained and weighted
Fit, and the minimum-norm fit for rank-deficient designs. - Structural algebra:
RootReduceandRootApproximant,Rootobjects
treated as the numbers they are, polynomial reduction modulo
polynomials, hyperbolic support inTrigReduce/TrigFactor, and
many canonical-ordering fixes so sums, products and radicals print
exactly as wolframscript prints them.
Special functions, statistics & number theory
- Symbolic reductions for the hypergeometric families (
0F1,1F1,
HypergeometricU,HypergeometricPFQBessel forms),PolyLog,
LerchPhi, the incompleteBetaandGammafunctions,
GegenbauerC[n, 1/2, x], parity ofGudermannian,Haversine,
Sinc,Erfand the Fresnel functions, hyperbolic
imaginary-period shifts, and exact values of the Carlson elliptic
integrals. Factorial Taylor sums fold toSin/Cos/Sinh/Cosh,
Sum[1/n^s]givesZeta[s], and sums ofHarmonicNumbergive
hyperharmonic closed forms. - Numeric evaluation of the Coulomb wavefunctions at nonzero
eta,
CarlsonRFat complex arguments, two-argumentErf,PolyLogwith
real order, and inverse trigonometric functions at complex floats. - Astronomy:
SunPosition,MoonPosition,MoonPhase, eclipses and
related functions compute from platform-independent ephemerides, as
an observer on the ground sees them. - Distributions:
SkewNormalDistribution;CDF/Quantile/Medianfor
the discrete families (NegativeBinomial,Pascal,BetaBinomial,
Zipf,Benford, …); skewness, kurtosis, raw moments,
characteristic functions and MGFs for many more; moments of
TruncatedDistributionandCensoredDistribution;RandomVariate
sampling forBinomialDistributionand hand-written distributions;
and parameter-range validation instead of silent nonsense.
Lists, arrays & structured data
SparseArraybehaves like the array it stores: arithmetic stays
sparse,Partreaches into higher ranks, the structural list
operations densify transparently, and the array predicates and grid
queries see through it.Datasetanswers queries through theQueryengine instead of a few
fixed shapes, and the statistics functions see through it.
TimeSeriescan be transformed, combined, resampled, windowed and
rescaled;MovingMapsupports padded and time-windowed forms.- List operations rounded out:
Periodic/Reflected/Cyclicpadding
(with nested padding arrays), two-dimensionalListConvolveand
ListCorrelatewith generalized operations,MapAtwithAlland
Span, ordering functions inSortBy/KeySort, nestedGroupBy
classifiers, rule-basedStringSplit/SequenceSplit, and the
structured matrices (CauchyMatrix,BlockDiagonalMatrix,
CompanionMatrix) plusSymmetrize/SymmetrizedArrayand
TensorExpand.
Strings, dates, import & export
- XML imports to symbolic XML (namespaces included) and writes back out
the way wolframscript does; CSV fixes cell quoting, empty fields and
header inference; JSON export fails cleanly on unrepresentable
values;URLBuild,URLQueryEncode/URLQueryDecode,TextCases
for words and sentences,CharacterNameandCharacterNormalize
are new. - Dates:
MaxDate/MinDate, ISO and week-based date elements, exact
rationalDateDifferencesub-day units, month rollover in
AbsoluteTime, andDateObjectgranularity truncation. - Output forms:
TeXFormsets matrices as LaTeX arrays and matches
wolframscript,CForm/FortranFormfix their operators and
numbers, and theNumberFormdisplay family shares one
option-aware renderer (NumberSigns,ExponentFunction,
NumberPadding, decimal-point alignment,BaseForminner values). - Patterns:
Verbatimheads,Longest/Shortest/
OrderlessPatternSequence,Overlaps -> Allreporting every match
at every start, string-pattern back-references, and implicitly named
blanks inStringSplit.
Images & audio
- Image processing:
ImagePad,ImageCrop,ImageFilter,
MeanFilter,ImageDifference,ImageMeasurements,
MorphologicalComponents,ComponentMeasurements,
DeleteSmallComponentsandMaxDetect/MinDetecton matrices;
Bluris theGaussianFilterit claims to be,Sharpensharpens
by Wolfram's amount, andEdgeDetectruns on the gradient Woxi
already had. - Audio: the accessors,
AudioNormalize/AudioReverse/AudioPad, and
ListPlaywith playback in the Playground and Woxi Studio.
Robustness & conformance
- Several rounds of differential fuzzing against wolframscript fixed
dozens of silent divergences in arithmetic, ordering,Simplify,
Togetherand friends. - Edge cases that used to abort the evaluator or panic now return the
message Wolfram reports:FactorIntegernear2^64, degenerate
random specifications, empty-list arguments, invalid permutation
lists, out-of-range arguments and bad string positions across many
heads. - Evaluation-semantics fixes: the builtin attribute table,
Switch
pattern evaluation,Returnno longer escapingTable/Map/
Select,Sequencethrough postfix application,Unevaluated
wrappers, chainedReplaceAll,Conditionprecedence, postfix++
binding, and a parser call-limit fix for deeply nested brackets. Encloseand theConfirmfamily,Successand theFailure
object family, and$MessageList(preserved aroundQuiet) are
implemented.
Platform, performance & tooling
- Windows is a supported platform: the unit tests pass and run in CI,
and the nightly builds produce Windows binaries of bothwoxiand
Woxi Studio. - Prebuilt binaries for Linux, macOS and Windows are attached to every
GitHub release, with a checksum file. - The browser (WASM) build supports
Export, including PNG/JPEG plot
export via host rasterization. - CI checks formatting and clippy (the codebase is clippy-clean outside
three allowed lints), debug builds useopt-level = 1, and the
crate metadata was fixed for crates.io publishing.
Demonstration-driven fixes in detail
- Fixes driven by a Wolfram Demonstration that draws a rational cyclic
polygon inside its circumcircle:SphereandBalldraw in a two-dimensionalGraphics: in the plane
a sphere is the circle bounding it and a ball the filled disk. Both
used to be dropped, and sinceCircumspherereturns aSphere
whatever the dimension, a picture built around a circumcircle came
out with no circle at all. A list of centres draws one per point,
andBall[2]is the unit disk at the origin.- A
Stylearound a label paints itsBackgroundbehind the text —
Style[Text[…], 12, Background -> White]is what keeps a distance
label readable over the line it sits on. Only aBackgroundwritten
on theTextitself was drawn before. - A square factor too large to reach by trial division comes out of a
radical:Sqrt[100003^2 * 115]is100003 Sqrt[115].Sqrtand the
c Sqrt[r]merge used to look for square factors to different
depths, so each rewrote what the other produced and halving such a
coefficient — theMeanof two points carrying a radical — never
returned.
- Fixes driven by the plane-geometry Wolfram Demonstrations that stack a
numeric readout over a drawing:- A
Pane[…]grid cell shows what it holds.Paneonly reserves an
area for its content, so a body laid out as
Grid[{{Pane[…]}, {Graphics[…]}}]used to print the whole
Pane[…]call as source text in place of the readout — and
stretch the grid to the width of that source.Item[…]and
Text[…]cells are peeled the same way, through the one helper
every display pass already shares. Dividers -> Allrules every position of a grid, the outer edges
included, so the grid is drawn as a closed box. Only the
boundaries between cells were ruled before, which is what
Dividers -> Centermeans; the two now differ, and either can be
set per direction asDividers -> {colspec, rowspec}.Spacings -> {{i -> s, …}, …}sets the gap at individual column
positions — positioniis the gap to the left of columni, and
positionncols + 1the margin after the last column. A
list-valued horizontal spec used to be dropped, so a readout that
groups its columns with wide and tight gaps came out evenly and
far too widely spaced. A plain{s1, s2, …}names the positions
in order, and positions left out keep the default gap.
- A
- Manipulate improvements (driven by the "Recursive Exercises" Wolfram
Demonstrations, which nest circles inside circles):- The leading assignments a body makes before anything else are
evaluated with the control variables at their initial values, the
way Wolfram evaluates the body before laying the controls out.
A body opening withu = {…, ss[-1., 1., n, dc]}, wheress
recurses down to a literal-1base case, used to recurse on a
symbolic depth that never reached the base case, so extraction
never returned and no widget appeared at all. - A choice list built from another control's variable
(Range[1, If[flat, 3, 6], 1]) is re-resolved against the live
bindings, so a level setter offering six levels flat narrows to
three in 3D. A selected value the narrowed list no longer offers
falls back to the last one it does, and the body is rendered again
for it. Previously the list was fixed at build time. ControlType -> Sliderover a choice list renders a slider that
steps through the choices, matching Wolfram; a twenty-entry
colour-scheme list used to become a dropdown.
- The leading assignments a body makes before anything else are
- Fixes driven by a Wolfram Demonstration that runs a cellular automaton
over a dendrite and compares it with the linear case:- A layout that holds pictures —
Grid[{{plot1, plot2}, …}], a
Columnof them, aPanearound either — is composed into the one
picture a notebook shows. The visual hosts (Playground, Woxi Studio)
only ever reported the last graphic drawn while the layout was
evaluated, so a Manipulate body that arranges several plots in a
grid displayed a single one of them and dropped the rest. - A
Grid's columns line up when its rows hold different things: the
caption under a picture is centred on that picture instead of
being packed against the left edge of the grid. LayeredGraphPlotandTreePlotdraw the layered embedding they
name, rather than the circular one every graph got. Vertices are
placed by distance from a root, and the second argument (Left,
Right,Top,Bottom) says which edge the roots go on.DirectedEdges -> Falsedraws a graph's edges as plain lines
instead of arrows, andImageSizesizes a graph plot — a
Demonstration asking for a wide, short strip used to get the
360-point default square.ArrayPlotdraws itsFrameLabel, on any of the four edges, with
the left and right labels rotated onto theirs.
- A layout that holds pictures —
- Fixes driven by the "Selectivity in a Semibatch Reactor" Wolfram
Demonstration:Textinside aGraphics3Dscene is drawn — a labelled 3D
schematic used to arrive with no lettering at all. It honours the
Stylesize and colour, typesetsSubscript/Superscript, and
respects the alignment offset ofText[expr, pos, offset].Scaled[{sx, sy}]places aTextorInsetby fraction of the
plot range, inGraphicsand in a plot'sEpilogalike. The
fractions used to be unreadable, dropping every such label onto
the origin.Inset[Graphics3D[…], pos]embeds a three-dimensional picture in a
flat one at its own size, instead of printing-Graphics3D-.Framed[…]around a label draws its box — a border, and a panel
when aBackgroundis given — rather than printing its own
source over the picture.FrameStyle -> Nonekeeps the panel and
drops the border.Subscript/Superscriptin aTextlabel typeset as scripts
instead of falling through to the two-lineOutputFormbox.GraphicsacceptsPrologandEpilog, drawn under and over its
content and taking no part in the plot range.- A
Manipulatecontrol panel written as aGriddrops its
SpanFromLeft/SpanFromAbovecell markers; they used to
survive as display elements and appear as literal text under the
widget, one row per marker. - A control label computed with
Row[Flatten[{…, Riffle[…], …}]]is
evaluated before it is typeset, so the button shows the caption
rather than the source of the computation.
- Fixes driven by the "Illustrative Performance Characteristics of Modern
Motorcycles" Wolfram Demonstration:Piecewiseholds its pieces, so the value of a piece whose condition
isFalseis never evaluated. This is what makes the construct a
guard:Piecewise[{{f[w], 0 <= w <= wmax}}, 0]no longer callsf
out of range, and the messages that call emitted are gone.FindRootfalls back to a difference quotient when the symbolic
derivative does not reduce to a number at the current iterate —
differentiating a non-smooth function leavesDerivative[1, 0][Max][…]
standing. It used to give up withFindRoot::nlnumand return
unevaluated. Messages emitted by the discarded attempt (D::ivar
and friends) no longer reach the user.- A
ControlType -> …given to theManipulateitself types every
control that does not pick one, and a list value assigns one type per
control in spec order. The Demonstrations idiom — controls laid out in
aGrid[…], typed once for the whole panel — now renders the dropdowns
the author asked for instead of over-wide SetterBars.
- Fixes driven by a Wolfram Demonstration that draws a complex function as
a colored vector field:ColorData[name, "ColorFunction"]gives the gradient's color
function, the same objectColorData[name]gives on its own. It
used to be reported as unimplemented, so every primitive colored
through it fell back to black.ColorData[name, "Range"]reads
the parameter interval alongside it.Graphics[…, ImagePadding -> …]honours the padding (it was only
read by the plot functions), so the drawing area sits where the
notebook puts it instead of at the automatic frame margins.- A named
Arrowheadssize is a fraction of the plot width and
nothing else. It used to be capped at 45% of the arrow carrying
it, which shrank the heads of a dense vector field — where each
arrow is barely longer than its head — to unreadable specks.
- Fixes driven by the "Mass with a Spring and a Rubber Band" Wolfram
Demonstration:- Substituting an
NDSolvesolution into a derivative
(y'[t] /. sol) evaluates numerically instead of echoing a
Derivative[…]expression, so a phase portrait of a numeric
solution can be plotted. - A plot nested in a
Rowinside aColumnkeeps its own coordinate
space and is drawn (it used to render blank). Frame -> Truelabels its frame ticks even withAxes -> False.AspectRatiotogether withImagePaddingsizes the image so the
plot area spans the full width, instead of shrinking it into a
canvas sized by the default ratio.- Labels written as a function of the plot variable typeset the way
Wolfram draws them —AxesLabel -> {t, y[t]}readsy(t)and a
derivative readsy′(t), where both used to be dropped — and a
Manipulatecontrol labelledStyle["y", Italic]'showsy′.
- Substituting an
- Symbol names may contain
$anywhere (a$b,signal$1), matching Wolfram. PlotRangebounds given in reversed order (e.g.{3, -3}) normalize to
the same plot as the sorted form, matching Wolfram.- Manipulate improvements (driven by the "Oscilloscope with Two Signal
Inputs" Wolfram Demonstration):Style[…], bare-string, andDelimiterarguments are treated as
static annotation rows between controls (no more spurious
Manipulate::vsformmessages) and render as headings/separators
in Woxi Studio and the Playground.- Compound control variables such as
Subscript[signal, 1]work: they
are bound through synthesized symbols and keep a typeset label
(signal₁). - Control specs may carry trailing options (
ControlType -> PopupMenu,
ImageSize -> Tiny, …);ControlType -> PopupMenualways renders
a dropdown. - A
Manipulatewhose body is anAnimate[…]renders as one combined
widget,AnimationRunning -> Falsebuilds the widget paused, and
anInfinityanimation bound gets a finite looping window.
- Woxi Studio re-instantiates stored
Manipulatewidgets when opening a
notebook (instead of showing the savedDynamicModuleBox[…]text dump). - Manipulate improvements (driven by the "Center of Mass of a Polygon"
Wolfram Demonstration):Locatorcontrols are interactive: a single point binds as a 2D
slider, a point list becomes a per-point X/Y control (with
add/remove whenLocatorAutoCreate -> True, and a multi-handle
drag pad in the Playground), instead of freezing the variable at
its initial value.- Discrete choices whose rule label is a graphic (
"+" -> myIcon[2])
render the icon in the SetterBar instead of dumping the label's
InputForm. - A bare control-type shorthand in the range position
({{p, init}, Locator}) is no longer misread as aDynamic[…]
range.
- InputForm keeps required parentheses around loose operands of
@@,/@,
@@@, and.(Plus @@ (x*y)/2,a . (b - c)); previously the
printed form re-parsed to a different expression, silently corrupting
re-evaluated Manipulate bodies. PlotLabelworks on plainGraphics[…](rendered as a centered title),
and labels may be arbitrary expressions such as
Row[{"center of mass: ", CM}]on all plot types.- An operator that binds tighter than
Timesnow reaches into an adjacent
implicit product:2 Times @@ {3, 4}is2 (Times @@ {3, 4})and
a b . cisa (b . c), matching Wolfram. Previously the whole product
became one operand, solcm^n Times @@ Table[…]applied the wrong head. - Manipulate improvements (driven by the "Descartes's Rule of Signs"
Wolfram Demonstration):Setter,Toggler,CheckboxBar,OpenerandOpenerBarare
recognised as control types. ASetterspec used to be read as a
slider bound, and since one unparsable spec aborts the whole
extraction, the entire Manipulate fell back to a text echo.{v, domain, ControlType -> None}startsvat the first choice of
its domain rather than binding the choice list itself.TrackedSymbols :> {…}limits which controls re-run the body; the
others move without re-rendering, as in Wolfram.
- Display of
Text[content]in the visual hosts (Woxi Studio, the
Playground) shows the content, so aText@Pane[Column[{…}]]body
renders the whole column instead of only the picture inside it. TraditionalForminside a layout is typeset in conventional notation
rather than being stripped to StandardForm markup:Equalreads=
(≤,≥,≠likewise), aRowof strings andStyle[…]s is set as
the text it displays, and a term with a negative coefficient carries
its sign on the operator (a - 130 x³, nota + -130 x³).