Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (2024)

Astronomical Graphics and Their Axes

It’s complicated to define where things are in the sky. There are four main coordinate systems that get used in doing this: horizon (relative to local horizon), equatorial (relative to the Earth’s equator), ecliptic (relative to the orbit of the Earth around the Sun) and galactic (relative to the plane of the galaxy). And when we draw a diagram of the sky (here on white for clarity) it’s typical to show the “axes” for all these coordinate systems:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (1)

But here’s a tricky thing: how should those axes be labeled? Each one is different: horizon is most naturally labeled by things like cardinal directions (N, E, S, W, etc.), equatorial by hours in the day (in sidereal time), ecliptic by months in the year, and galactic by angle from the center of the galaxy.

In ordinary plots axes are usually straight, and labeled uniformly (or perhaps, say, logarithmically). But in astronomy things are much more complicated: the axes are intrinsically circular, and then get rendered through whatever projection we’re using.

And we might have thought that such axes would require some kind of custom structure. But not in the Wolfram Language. Because in the Wolfram Language we try to make things general. And axes are no exception:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (2)

So in AstroGraphics all our various axes are just AxisObject constructs—that can be computed with. And so, for example, here’s a Mollweide projection of the sky:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (3)

If we insist on “seeing the whole sky”, the bottom half is just the Earth (and, yes, the Sun isn’t shown because I’m writing this after it’s set for the day…):

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (4)

Things get a bit wild if we start adding grid lines, here for galactic coordinates:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (5)

And, yes, the galactic coordinate axis is indeed aligned with the plane of the Milky Way (i.e. our galaxy):

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (6)

When Is Earthrise on Mars? New Level of Astronomical Computation

When will the Earth next rise above the horizon from where the Perseverance rover is on Mars? In Version 14.1 we can now compute this (and, yes, this is an “Earth time” converted from Mars time using the standard barycentric celestial reference system (BCRS) solar-system-wide spacetime coordinate system):

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (7)

This is a fairly complicated computation that takes into account not only the motion and rotation of the bodies involved, but also various other physical effects. A more “down to Earth” example that one might readily check by looking out of one’s window is to compute the rise and set times of the Moon from a particular point on the Earth:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (8)

There’s a slight variation in the times between moonrises:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (9)

Over the course of a year we see systematic variations associated with the periods of different kinds of lunar months:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (10)

There are all sorts of subtleties here. For example, when exactly does one define something (like the Sun) to have “risen”? Is it when the top of the Sun first peeks out? When the center appears? Or when the “whole Sun” is visible? In Version 14.1 you can ask about any of these:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (11)

Oh, and you could compute the same thing for the rise of Venus, but now to see the differences, you’ve got to go to millisecond granularity (and, by the way, granularities of milliseconds down to picoseconds are new in Version 14.1):

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (12)

By the way, particularly for the Sun, the concept of ReferenceAltitude is useful in specifying the various kinds of sunrise and sunset: for example, “civil twilight” corresponds to a reference altitude of –6°.

Geometry Goes Color, and Polar

Last year we introduced the function ARPublish to provide a streamlined way to take 3D geometry and publish it for viewing in augmented reality. In Version 14.1 we’ve now extended this pipeline to deal with color:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (13)

(Yes, the color is a little different on the phone because the phone tries to make it look “more natural”.)

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (14)

And now it’s easy to view this not just on a phone, but also, for example, on the Apple Vision Pro:

Graphics have always had color. But now in Version 14.1 symbolic geometric regions can have color too:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (15)

And constructive geometric operations on regions preserve color:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (16)

Two other new functions in Version 14.1 are PolarCurve and FilledPolarCurve:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (17)

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (18)

And while at this level this may look simple, what’s going on underneath is actually seriously complicated, with all sorts of symbolic analysis needed in order to determine what the “inside” of the parametric curve should be.

Talking about geometry and color brings up another enhancement in Version 14.1: plot themes for diagrams in synthetic geometry. Back in Version 12.0 we introduced symbolic synthetic geometry—in effect finally providing a streamlined computable way to do the kind of geometry that Euclid did two millennia ago. In the past few versions we’ve been steadily expanding our synthetic geometry capabilities, and now in Version 14.1 one notable thing we’ve added is the ability to use plot themes—and explicit graphics options—to style geometric diagrams. Here’s the default version of a geometric diagram:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (19)

Now we can “theme” this for the web:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (20)

New Computation Flow in Notebooks: Introducing Cell-Linked %

In building up computations in notebooks, one very often finds oneself wanting to take a result one just got and then do something with it. And ever since Version 1.0 one’s been able to do this by referring to the result one just got as %. It’s very convenient. But there are some subtle and sometimes frustrating issues with it, the most important of which has to do with what happens when one reevaluates an input that contains %.

Let’s say you’ve done this:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (21)

But now you decide that actually you wanted Median[ % ^ 2 ] instead. So you edit that input and reevaluate it:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (22)

Oops! Even though what’s right above your input in the notebook is a list, the value of % is the latest result that was computed, which you can’t now see, but which was 3.

OK, so what can one do about this? We’ve thought about it for a long time (and by “long” I mean decades). And finally now in Version 14.1 we have a solution—that I think is very nice and very convenient. The core of it is a new notebook-oriented analog of %, that lets one refer not just to things like “the last result that was computed” but instead to things like “the result computed in a particular cell in the notebook”.

So let’s look at our sequence from above again. Let’s start typing another cell—say to “try to get it right”. In Version 14.1 as soon as we type % we see an autosuggest menu:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (23)

The menu is giving us a choice of (output) cells that we might want to refer to. Let’s pick the last one listed:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (24)

The Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (25) object is a reference to the output from the cell that’s currently labeled In[1]—and using Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (26) now gives us what we wanted.

But let’s say we go back and change the first (input) cell in the notebook—and reevaluate it:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (27)

The cell now gets labeled In[5]—and the Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (28) (in In[4]) that refers to that cell will immediately change to Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (29):

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (30)

And if we now evaluate this cell, it’ll pick up the value of the output associated with In[5], and give us a new answer:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (31)

So what’s really going on here? The key idea is that Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (32) signifies a new type of notebook element that’s a kind of cell-linked analog of %. It represents the latest result from evaluating a particular cell, wherever the cell may be, and whatever the cell may be labeled. (The Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (33) object always shows the current label of the cell it’s linked to.) In effect Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (34) is “notebook front end oriented”, while ordinary % is kernel oriented. Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (35) is linked to the contents of a particular cell in a notebook; % refers to the state of the Wolfram Language kernel at a certain time.

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (36) gets updated whenever the cell it’s referring to is reevaluated. So its value can change either through the cell being explicitly edited (as in the example above) or because reevaluation gives a different value, say because it involves generating a random number:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (37)

OK, so Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (38) always refers to “a particular cell”. But what makes a cell a particular cell? It’s defined by a unique ID that’s assigned to every cell. When a new cell is created it’s given a universally unique ID, and it carries that same ID wherever it’s placed and whatever its contents may be (and even across different sessions). If the cell is copied, then the copy gets a new ID. And although you won’t explicitly see cell IDs, Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (39) works by linking to a cell with a particular ID.

One can think of Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (40) as providing a “more stable” way to refer to outputs in a notebook. And actually, that’s true not just within a single session, but also across sessions. Say one saves the notebook above and opens it in a new session. Here’s what you’ll see:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (41)

The Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (42) is now grayed out. So what happens if we try to reevaluate it? Well, we get this:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (43)

If we press Reconstruct from output cell the system will take the contents of the first output cell that was saved in the notebook, and use this to get input for the cell we’re evaluating:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (44)

In almost all cases the contents of the output cell will be sufficient to allow the expression “behind it” to be reconstructed. But in some cases—like when the original output was too big, and so was elided—there won’t be enough in the output cell to do the reconstruction. And in such cases it’s time to take the Go to input cell branch, which in this case will just take us back to the first cell in the notebook, and let us reevaluate it to recompute the output expression it gives.

By the way, whenever you see a “positional %” you can hover over it to highlight the cell it’s referring to:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (45)

Having talked a bit about “cell-linked %” it’s worth pointing out that there are still cases when you’ll want to use “ordinary %”. A typical example is if you have an input line that you’re using a bit like a function (say for post-processing) and that you want to repeatedly reevaluate to see what it produces when applied to your latest output.

In a sense, ordinary % is the “most volatile” in what it refers to. Cell-linked % is “less volatile”. But sometimes you want no volatility at all in what you’re referring to; you basically just want to burn a particular expression into your notebook. And in fact the % autosuggest menu gives you a way to do just that.

Notice the Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (46) that appears in whatever row of the menu you’re selecting:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (47)

Press this and you’ll insert (in iconized form) the whole expression that’s being referred to:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (48)

Now—for better or worse—whatever changes you make in the notebook won’t affect the expression, because it’s right there, in literal form, “inside” the icon. And yes, you can explicitly “uniconize” to get back the original expression:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (49)

Once you have a cell-linked % it always has a contextual menu with various actions:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (50)

One of those actions is to do what we just mentioned, and replace the positional Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (51) by an iconized version of the expression it’s currently referring to. You can also highlight the output and input cells that the Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (52) is “linked to”. (Incidentally, another way to replace a Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (53) by the expression it’s referring to is simply to “evaluate in place” Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (54), which you can do by selecting it and pressing CMDReturn or ShiftControlEnter.)

Another item in the Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (55) menu is Replace With Rolled-Up Inputs. What this does is—as it says—to “roll up” a sequence of “Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (56) references” and create a single expression from them:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (57)

What we’ve talked about so far one can think of as being “normal and customary” uses of Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (58). But there are all sorts of corner cases that can show up. For example, what happens if you have a Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (59) that refers to a cell you delete? Well, within a single (kernel) session that’s OK, because the expression “behind” the cell is still available in the kernel (unless you reset your $HistoryLength etc.). Still, the Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (60) will show up with a “red broken link” to indicate that “there could be trouble”:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (61)

And indeed if you go to a different (kernel) session there will be trouble—because the information you need to get the expression to which the Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (62) refers is simply no longer available, so it has no choice but to show up in a kind of everything-has-fallen-apart “surrender state” as:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (63)

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (64) is primarily useful when it refers to cells in the notebook you’re currently using (and indeed the autosuggest menu will contain only cells from your current notebook). But what if it ends up referring to a cell in a different notebook, say because you copied the cell from one notebook to another? It’s a precarious situation. But if all relevant notebooks are open, Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (65) can still work, though it’s displayed in purple with an action-at-a-distance “wi-fi icon” to indicate its precariousness:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (66)

And if, for example, you start a new session, and the notebook containing the “source” of the Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (67) isn’t open, then you’ll get the “surrender state”. (If you open the necessary notebook it’ll “unsurrender” again.)

Yes, there are lots of tricky cases to cover (in fact, many more than we’ve explicitly discussed here). And indeed seeing all these cases makes us not feel bad about how long it’s taken for us to conceptualize and implement Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (68).

The most common way to access Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (69) is to use the % autosuggest menu. But if you know you want a Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (70), you can always get it by “pure typing”, using for example ESC%ESC. (And, yes, ESC%%ESC or ESC%5ESC etc. also work, so long as the necessary cells are present in your notebook.)

The UX Journey Continues: New Typing Affordances, and More

We invented Wolfram Notebooks more than 36 years ago, and we’ve been improving and polishing them ever since. And in Version 14.1 we’re implementing several new ideas, particularly around making it even easier to type Wolfram Language code.

It’s worth saying at the outset that good UX ideas quickly become essentially invisible. They just give you hints about how to interpret something or what to do with it. And if they’re doing their job well, you’ll barely notice them, and everything will just seem “obvious”.

So what’s new in UX for Version 14.1? First, there’s a story around brackets. We first introduced syntax coloring for unmatched brackets back in the late 1990s, and gradually polished it over the following two decades. Then in 2021 we started “automatching” brackets (and other delimiters), so that as soon as you type “f[” you immediately get f[ ].

But how do you keep on typing? You could use an Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (71) to “move through” the ]. But we’ve set it up so you can just “type through” ] by typing ]. In one of those typical pieces of UX subtlety, however, “type through” doesn’t always make sense. For example, let’s say you typed f[x]. Now you click right after [ and you type g[, so you’ve got f[g[x]. You might think there should be an autotyped ] to go along with the [ after g. But where should it go? Maybe you want to get f[g[x]], or maybe you’re really trying to type f[g[],x]. We definitely don’t want to autotype ] in the wrong place. So the best we can do is not autotype anything at all, and just let you type the ] yourself, where you want it. But remember that with f[x] on its own, the ] is autotyped, and so if you type ] yourself in this case, it’ll just type through the autotyped ] and you won’t explicitly see it.

So how can you tell whether a ] you type will explicitly show up, or will just be “absorbed” as type-through? In Version 14.1 there’s now different syntax coloring for these cases: yellow if it’ll be “absorbed”, and pink if it’ll explicitly show up.

This is an example of non-type-through, so Range is colored yellow and the ] you type is “absorbed”:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (72)

And this is an example of non-type-through, so Round is colored pink and the ] you type is explicitly inserted:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (73)

This may all sound very fiddly and detailed—and for us in developing it, it is. But the point is that you don’t explicitly have to think about it. You quickly learn to just “take the hint” from the syntax coloring about when your closing delimiters will be “absorbed” and when they won’t. And the result is that you’ll have an even smoother and faster typing experience, with even less chance of unmatched (or incorrectly matched) delimiters.

The new syntax coloring we just discussed helps in typing code. In Version 14.1 there’s also something new that helps in reading code. It’s an enhanced version of something that’s actually common in IDEs: when you click (or select) a variable, every instance of that variable immediately gets highlighted:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (74)

What’s subtle in our case is that we take account of the scoping of localized variables—putting a more colorful highlight on instances of a variable that are in scope:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (75)

One place this tends to be particularly useful is in understanding nested pure functions that use #. By clicking a # you can see which other instances of # are in the same pure function, and which are in different ones (the highlight is bluer inside the same function, and grayer outside):

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (76)

On the subject of finding variables, another change in Version 14.1 is that fuzzy name autocompletion now also works for contexts. So if you have a symbol whose full name is context1`subx`var2 you can type c1x and you’ll get a completion for the context; then accept this and you get a completion for the symbol.

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (77)

There are also several other notable UX “tune-ups” in Version 14.1. For many years, there’s been an “information box” that comes up whenever you hover over a symbol. Now that’s been extended to entities—so (alongside their explicit form) you can immediately get to information about them and their properties:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (78)

Next there’s something that, yes, I personally have found frustrating in the past. Say you’ve a file, or an image, or something else somewhere on your computer’s desktop. Normally if you want it in a Wolfram Notebook you can just drag it there, and it will very beautifully appear. But what if the thing you’re dragging is very big, or has some other kind of issue? In the past, the drag just failed. Now what happens is that you get the explicit Import that the dragging would have done, so that you can run it yourself (getting progress information, etc.), or you can modify it, say adding relevant options.

Another small piece of polish that’s been added in Version 14.1 has to do with Preferences. There are a lot of things you can set in the notebook front end. And they’re explained, at least briefly, in the many Preferences panels. But in Version 14.1 there are now (i) buttons that give direct links to the relevant workflow documentation:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (79)

Syntax for Natural Language Input

Ever since shortly after Wolfram|Alpha was released in 2009, there’ve been ways to access its natural language understanding capabilities in the Wolfram Language. Foremost among these has been CTRL=—which lets you type free-form natural language and immediately get a Wolfram Language version, often in terms of entities, etc.:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (80)

Generally this is a very convenient and elegant capability. But sometimes one may want to just use plain text to specify natural language input, for example so that one doesn’t interrupt one’s textual typing of input.

In Version 14.1 there’s a new mechanism for this: syntax for directly entering free-form natural language input. The syntax is a kind of a “textified” version of CTRL=: =[…]. When you type =[...] as input nothing immediately happens. It’s only when you evaluate your input that the natural language gets interpreted—and then whatever it specifies is computed.

Here’s a very simple example, where each =[…] just turns into an entity:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (81)

But when the result of interpreting the natural language is an expression that can be further evaluated, what will come out is the result of that evaluation:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (82)

One feature of using =[…] instead of CTRL= is that =[…] is something anyone can immediately see how to type:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (83)

But what actually is =[…]? Well, it’s just input syntax for the new function FreeformEvaluate:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (84)

You can use FreeformEvaluate inside a program—here, rather whimsically, to see what interpretations are chosen by default for “a” followed by each letter of the alphabet:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (85)

By default, FreeformEvaluate interprets your input, then evaluates it. But you can also specify that you want to hold the result of the interpretation:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (86)

Diff[ ] … for Notebooks and More!

It’s been a very long-requested capability: give me a way to tell what changed, particularly in a notebook. It’s fairly easy to do “diffs” for plain text. But for notebooks—as structured symbolic documents—it’s a much more complicated story. But in Version 14.1 it’s here! We’ve got a function Diff for doing diffs in notebooks, and actually also in many other kinds of things.

Here’s an example, where we’re requesting a “side-by-side view” of the diff between two notebooks:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (87)

And here’s an “alignment chart view” of the diff:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (88)

Like everything else in the Wolfram Language, a “diff” is a symbolic expression. Here’s an example:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (89)

There are lots of different ways to display a diff object; many of them one can select interactively with the menu:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (90)

But the most important thing about diff objects is that they can be used programmatically. And in particular DiffApply applies the diffs from a diff object to an existing object, say a notebook.

What’s the point of this? Well, let’s imagine you’ve made a notebook, and given a copy of it to someone else. Then both you and the person to whom you’ve given the copy make changes. You can create a diff object of the diffs between the original version of the notebook, and the version with your changes. And if the changes the other person made don’t overlap with yours, you can just take your diffs and use DiffApply to apply your diffs to their version, thereby getting a “merged notebook” with both sets of changes made.

But what if your changes might conflict? Well, then you need to use the function Diff3. Diff3 takes your original notebook and two modified versions, and does a “three-way diff” to give you a diff object in which any conflicts are explicitly identified. (And, yes, three-way diffs are familiar from source control systems in which they provide the back end for making the merging of files as automated as possible.)

Notebooks are an important use case for Diff and related functions. But they’re not the only one. Diff can perfectly well be applied, for example, just to lists:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (91)

There are many ways to display this diff object; here’s a side-by-side view:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (92)

And here’s a “unified view” reminiscent of how one might display diffs for lines of text in a file:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (93)

And, speaking of files, Diff, etc. can immediately be applied to files:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (94)

Diff, etc. can also be applied to cells, where they can analyze changes in both content and styles or metadata. Here we’re creating two cells and then diffing them—showing the result in a side by side:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (95)

In “Combined” view the “pure insertions” are highlighted in green, the “pure deletions” in red, and the “edits” are shown as deletion/insertion stacks:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (96)

Many uses of diff technology revolve around content development—editing, software engineering, etc. But in the Wolfram Language Diff, etc. are set up also to be convenient for information visualization and for various kinds of algorithmic operations. For example, to see what letters differ between the Spanish and Polish alphabets, we can just use Diff:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (97)

Here’s the “pure visualization”:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (98)

And here’s an alternate “unified summary” form:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (99)

Another use case for Diff is bioinformatics. We retrieve two genome sequences—as strings—then use Diff:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (100)

We can take the resulting diff object and show it in a different form—here character alignment:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (101)

Under the hood, by the way, Diff is finding the differences using SequenceAlignment. But while Diff is giving a “high-level symbolic diff object”, SequenceAlignment is giving a direct low-level representation of the sequence alignment:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (102)

Information visualization isn’t restricted to two-way diffs; here’s an example with a three-way diff:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (103)

And here it is as a “unified summary”:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (104)

There are all sorts of options for diffs. One that is sometimes important is DiffGranularity. By default the granularity for diffs of strings is "Characters":

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (105)

But it’s also possible to set it to be "Words":

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (106)

Coming back to notebooks, the most “interactive” form of diff is a “report”:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (107)

In such a report, you can open cells to see the details of a specific change, and you can also click to jump to where the change occurred in the underlying notebooks.

When it comes to analyzing notebooks, there’s another new feature in Version 14.1: NotebookCellData. NotebookCellData gives you direct programmatic access to lots of properties of notebooks. By default it generates a dataset of some of them, here for the notebook in which I’m currently authoring this:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (108)

There are properties like the word count in each cell, the style of each cell, the memory footprint of each cell, and a thumbnail image of each cell.

Ever since Version 6 in 2007 we’ve had the CellChangeTimes option which records when cells in notebooks are created or modified. And now in Version 14.1 NotebookCellData provides direct programmatic access to this data. So, for example, here’s a date histogram of when the cells in the current notebook were last changed:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (109)

Lots of Little Language Tune-Ups

It’s part of a journey of almost four decades. Steadily discovering—and inventing—new “lumps of computational work” that make sense to implement as functions or features in the Wolfram Language. The Wolfram Language is of course very much strong enough that one can build essentially any functionality from the primitives that already exist in it. But part of the point of the language is to define the best “elements of computational thought”. And particularly as the language progresses, there’s a continual stream of new opportunities for convenient elements that get exposed. And in Version 14.1 we’ve implemented quite a diverse collection of them.

Let’s say you want to nestedly compose a function. Ever since Version 1.0 there’s been Nest for that:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (110)

But what if you want the abstract nested function, not yet applied to anything? Well, in Version 14.1 there’s now an operator form of Nest (and NestList) that represents an abstract nested function that can, for example, be composed with other functions, as in

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (111)

or equivalently:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (112)

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (113)

A decade ago we introduced functions like AllTrue and AnyTrue that effectively “in one gulp” do a whole collection of separate tests. If one wanted to test whether there are any primes in a list, one can always do:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (114)

But it’s better to “package” this “lump of computational work” into the single function AnyTrue:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (115)

In Version 14.1 we’re extending this idea by introducing AllMatch, AnyMatch and NoneMatch:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (116)

Another somewhat related new function is AllSameBy. SameQ tests whether a collection of expressions are immediately the same. AllSameBy tests whether expressions are the same by the criterion that the value of some function applied to them is the same:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (117)

Talking of tests, another new feature in Version 14.1 is a second argument to QuantityQ (and KnownUnitQ), which lets you test not only whether something is a quantity, but also whether it’s a specific type of physical quantity:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (118)

And now talking about “rounding things out”, Version 14.1 does that in a very literal way by enhancing the RoundingRadius option. For a start, you can now specify a different rounding radius for particular corners:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (119)

And, yes, that’s useful if you’re trying to fit button-like constructs together:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (120)

By the way, RoundingRadius now also works for rectangles inside Graphics:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (121)

Let’s say you have a string, like “hello”. There are many functions that operate directly on strings. But sometimes you really just want to use a function that operates on lists—and apply it to the characters in a string. Now in Version 14.1 you can do this using StringApply:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (122)

Another little convenience in Version 14.1 is the function BitFlip, which, yes, flips a bit in the binary representation of a number:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (123)

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (124)

When it comes to Boolean functions, a detail that’s been improved in Version 14.1 is the conversion to NAND representation. By default, functions like BooleanConvert have allowed Nand[p] (which is equivalent to Not[p]). But in Version 14.1 there’s now "BinaryNAND" which yields for example Nand[p, p] instead of just Nand[p] (i.e. Not[p]). So here’s a representation of Or in terms of Nand:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (125)

Making the Wolfram Compiler Easier to Use

Let’s say you have a piece of Wolfram Language code that you know you’re going to run a zillion times—so you want it to run absolutely as fast as possible. Well, you’ll want to make sure you’re doing the best algorithmic things you can (and making the best possible use of Wolfram Language superfunctions, etc.). And perhaps you’ll find it helpful to use things like DataStructure constructs. But ultimately if you really want your code to run absolutely as fast as your computer can make it, you’ll probably want to set it up so that it can be compiled using the Wolfram Compiler, directly to LLVM code and then machine code.

We’ve been developing the Wolfram Compiler for many years, and it’s becoming steadily more capable (and efficient). And for example it’s become increasingly important in our own internal development efforts. In the past, when we wrote critical inner-loop internal code for the Wolfram Language, we did it in C. But in the past few years we’ve almost completely transitioned instead to writing pure Wolfram Language code that we then compile with the Wolfram Compiler. And the result of this has been a dramatically faster and more reliable development pipeline for writing inner-loop code.

Ultimately what the Wolfram Compiler needs to do is to take the code you write and align it with the low-level capabilities of your computer, figuring out what low-level data types can be used for what, etc. Some of this can be done automatically (using all sorts of fancy symbolic and theorem-proving-like techniques). But some needs to be based on collaboration between the programmer and the compiler. And in Version 14.1 we’re adding several important ways to enhance that collaboration.

The first thing is that it’s now easy to get access to information the compiler has. For example, here’s the type declaration the compiler has for the built-in function Dimensions:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (126)

And here’s the source code of the actual implementation the compiler is using for Dimensions, calling its intrinsic low-level internal functions like CopyTo:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (127)

A function like Map has a vastly more complex set of type declarations:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (128)

For types themselves, CompilerInformation lets you see their type hierarchy:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (129)

And for data structure types, you can do things like see the fields they contain, and the operations they support:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (130)

And, by the way, something new in Version 14.1 is the function OperationDeclaration which lets you declare operations to add to a data structure type you’ve defined.

Once you actually start running the compiler, a convenient new feature in Version 14.1 is a detailed progress monitor that lets you see what the compiler is doing at each step:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (131)

As we said, the key to compilation is figuring out how to align your code with the low-level capabilities of your computer. The Wolfram Language can do arbitrary symbolic operations. But many of those don’t align with low-level capabilities of your computer, and can’t meaningfully be compiled. Sometimes those failures to align are the result of sophistication that’s possible only with symbolic operations. But sometimes the failures can be avoided if you “unpack” things a bit. And sometimes the failures are just the result of programming mistakes. And now in Version 14.1 the Wolfram Compiler is starting to be able to annotate your code to show where the misalignments are happening, so you can go through and figure out what to do with them. (It’s something that’s uniquely possible because of the symbolic structure of the Wolfram Language and even more so of Wolfram Notebooks.)

Here’s a very simple example:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (132)

In compiled code, Sin expects a numerical argument, so a Boolean argument won’t work. Clicking the Source button lets you see where specifically something went wrong:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (133)

If you have several levels of definitions, the Source button will show you the whole chain:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (134)Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (135)

Here’s a slightly more complicated piece of code, in which the specific place where there’s a problem is highlighted:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (136)Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (137)

In a typical workflow you might start from pure Wolfram Language code, without Typed and other compilation information. Then you start adding such information, repeatedly trying the compilation, seeing what issues arise, and fixing them. And, by the way, because it’s completely efficient to call small pieces of compiled code within ordinary Wolfram Language code, it’s common to start by annotating and compiling the “innermost inner loops” in your code, and gradually “working outwards”.

But, OK, let’s say you’ve successfully compiled a piece of code. Most of the time it’ll handle certain cases, but not others (for example, it might work fine with machine-precision numbers, but not be capable of handling arbitrary precision). By default, compiled code that’s running is set up to generate a message and revert to ordinary Wolfram Language evaluation if it can’t handle something:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (138)

But in Version 14.1 there a new option CompilerRuntimeErrorAction that lets you specify an action to take (or, in general, a function to apply) whenever a runtime error occurs. A setting of None aborts the whole computation if there’s a runtime error:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (139)

Even Smoother Integration with External Languages

Let’s say there’s some functionality you want to use, but the only implementation you have is in a package in some external language, like Python. Well, it’s now basically seamless to work with such functionality directly in the Wolfram Language—plugging into the whole symbolic framework and functionality of the Wolfram Language.

As a simple example, here’s a function that uses the Python package faker to produce a random sentence (which of course would also be straightforward to do directly in Wolfram Language):

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (140)

The first time you run RandomSentence, the progress monitor will show you all sorts of messy things happening under the hood, as Python versions get loaded, dependencies get set up, and so on. But the point is that it’s all automatic, and so you don’t have to worry about it. And in the end, out pops the answer:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (141)

And if you run the function again, all the setup will already have been done, and the answer will pop out immediately:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (142)

An important piece of automation here is the conversion of data types. One of the great things about the Wolfram Language is that it has fully integrated symbolic representations for a very wide range of things—from videos to molecules to IP addresses. And when there are standard representations for these things in a language like Python, we’ll automatically convert to and from them.

But particularly with more sophisticated packages, there’ll be a need to let the package deal with its own “external objects” that are basically opaque to the Wolfram Language, but can be handled as atomic symbolic constructs there.

For example, let’s say we’ve started a Python external package chess (and, yes, there’s a paclet in the Wolfram Paclet Repository that has considerably more chess functionality):

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (143)

Now the state of a chessboard can be represented by an external object:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (144)

We can define a function to plot the board:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (145)

And now in Version 14.1 you can just pass your external object to the external function:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (146)

You can also directly extract attributes of the external object:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (147)

And you can call methods (here to make a chess move), changing the state of the external object:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (148)

Here’s a plot of a new board configuration:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (149)

This computes all legal moves from the current position, representing them as external objects:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (150)

Here are UCI string representations of these:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (151)

In what we’re doing here we’re immediately performing each external operation. But Version 14.1 introduces the construct ExternalOperation which lets you symbolically represent an external operation, and for example build up collections of such operations that can all be performed together in a single external evaluation. ExternalObject supports various built-in operations for each environment. So, for example, in Python we can use Call and GetAttribute to get the symbolic representation:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (152)

If we evaluate this, all these operations will get done together in the external environment:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (153)

Standalone Wolfram Language Applications!

Let’s say you’re writing an application in pretty much any programming language—and inside it you want to call Wolfram Language functionality. Well, you could always do that by using a web API served from the Wolfram Cloud. And you could also do it locally by running the Wolfram Engine. But in Version 14.1 there’s something new: a way of integrating a standalone Wolfram Language runtime right into your application. The Wolfram Language runtime is a dynamic library that you link into your program, and then call using a C-based API. How big is the runtime? Well, it depends on what you want to use in the Wolfram Language. Because we now have the technology to prune a runtime to include only capabilities needed for particular Wolfram Language code. And the result is that adding the Wolfram Language will often increase the disk requirements of your application only by a remarkably small amount—like just a few hundred megabytes or even less. And, by the way, you can distribute the Wolfram runtime as an integrated part of an application, with its users not needing their own licenses to run it.

OK, so how does creating a standalone Wolfram-enabled application actually work? There’s a lot of software engineering (associated with the Wolfram Language runtime, how it’s called, etc.) under the hood. But at the level of the application programmer you only have to deal with our Standalone Applications SDK—whose interface is rather simple.

As an example, here’s the C code part of a standalone application that uses the Wolfram Language to identify what (human) language a piece of text is in. The program here takes a string of text on its command line, then runs the Wolfram Language LanguageIdentify function on it, and then prints a string giving the result:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (154)

If we ignore issues of pruning, etc. we can compile this program just with (and, yes, the file paths are necessarily a bit long):

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (155)

Now we can run the resulting executable directly from the command line—and it’ll act just like any other executable, even though inside it’s got all the power of a Wolfram Language runtime:

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (156)

If we look at the C program above, it basically begins just by starting the Wolfram Language runtime (using WLR_SDK_START_RUNTIME()). But then it takes the string (argv[1]) from the command line, embeds it in a Wolfram Language expression LanguageIdentify[string], evaluates this expression, and extracts a raw string from the result.

The functions, etc. that are involved here are part of the new Expression API supported by the Wolfram Language runtime dynamic library. The Expression API provides very clean capabilities for building up and taking apart Wolfram Language expressions from C. There are functions like wlr_Symbol("string") that form symbols, as well as macros like wlr_List(elem$1, elem$2, …) and wlr_E(head, arg$1, arg$2, …) that build up lists and general expressions. Then there’s the function wlr_Eval(expr) that calls the Wolfram Language evaluator. With functions like wlr_StringData(expr, &result, …) you can then extract content from expressions (here the characters in a string) and put it into C data structures.

How does the Expression API relate to WSTP? WSTP (“Wolfram Symbolic Transfer Protocol”) is our protocol for transferring symbolic expressions between processes. The Expression API, on the other hand, operates within a single process, providing the “glue” that connects C code to expressions in the Wolfram Language runtime.

One example of a real-world use of our new Standalone Applications technology is the LSPServer application that will soon be in full distribution. LSPServer started from a pure (though somewhat lengthy) Wolfram Language paclet that provides Language Server Protocol services for annotating Wolfram Language code in programs like Visual Studio Code. To build the LSPServer standalone application we just wrote a tiny C program that calls the paclet, then compiled this and linked it against our Standalone Applications SDK. Along the way (using tools that we’re planning to soon make available)—and based on the fact that only a small part of the full functionality of the Wolfram Language is needed to support LSPServer—we pruned the Wolfram Language runtime, in the end getting a complete LSPServer application that’s only about 170 MB in size, and that shows no outside signs of having Wolfram Language functionality inside.

And Yet More…

Is that all? Well, no. There’s more. Like new formatting of Root objects (yes, I was frustrated with the old one). Or like a new drag-and-drop-to-answer option for QuestionObject quizzes. Or like all the documentation we’ve added for new types of entities and interpreters.

In addition, there’s also the continual stream of new data that we’ve curated, or that’s flowed in real time into the Wolfram Knowledgebase. And beyond the core Wolfram Language itself, there’ve also been lots of functions added to the Wolfram Function Repository, lots of paclets added to the Wolfram Language Paclet Repository, not to mention new entries in the Wolfram Neural Net Repository, Wolfram Data Repository, etc.

Yes, as always it’s been a lot of work. But today it’s here, and we’re proud of it: Version 14.1!

Yet More New Ideas and New Functions: Launching Version 14.1 of Wolfram Language & Mathematica (2024)
Top Articles
Latest Posts
Recommended Articles
Article information

Author: Velia Krajcik

Last Updated:

Views: 5904

Rating: 4.3 / 5 (74 voted)

Reviews: 89% of readers found this page helpful

Author information

Name: Velia Krajcik

Birthday: 1996-07-27

Address: 520 Balistreri Mount, South Armand, OR 60528

Phone: +466880739437

Job: Future Retail Associate

Hobby: Polo, Scouting, Worldbuilding, Cosplaying, Photography, Rowing, Nordic skating

Introduction: My name is Velia Krajcik, I am a handsome, clean, lucky, gleaming, magnificent, proud, glorious person who loves writing and wants to share my knowledge and understanding with you.