11

I was thinking that Nothing was doing the same job as the vanishing sequence ##&[].

Yet this exemple shows it doesn't.

Association[If[True,Nothing]] (*returns Association[Nothing]*)
Association[If[True,##&[]]] (*returns Association[]*)

Is it normal ?

faysou
  • 10,999
  • 3
  • 50
  • 125
  • Which Mathematica version do you use? With version 10.4.1 Association[If[True, Nothing]] returns <||>. – Alexey Popkov Jun 24 '16 at 08:26
  • ref: "represents an element of a list that will automatically be removed. " the list is a key here. – Kuba Jun 24 '16 at 08:29
  • So it behaves correctly, but worth to mention that one can't predict what is done internally: 102555 – Kuba Jun 24 '16 at 08:32
  • I should have checked first, this also works with version 10.4.0. So what version is it not working in? – Ymareth Jun 24 '16 at 08:42
  • 1
    According to Heidegger: "The Nothing itself nothings", but I'm sure he didn't have MMA in mind when he wrote that. – N.J.Evans Jun 24 '16 at 16:53

1 Answers1

15

Nothing is like Sequence[]: it gets removed during evaluation. But there is one significant difference: it only gets removed from lists.

{{Nothing}, {Sequence[]}}
(* {{}, {}} *)

{foo[Nothing], foo[Sequence[]]}
(* {foo[Nothing], foo[]} *)

Update from @ilian

It only gets removed from lists is correct for Mathematica 10.4.0 and later; Nothing did get removed from associations in 10.2 and 10.3.


This makes it easier to work with Nothing than Sequence[] (or at least it requires a less complete understanding of the evaluation sequence before one can use it productively).

Example:

{1, 2, 3, 4} /. x_Integer :> If[OddQ[x], x, Sequence[]]
(* {1, Null, 3, Null} *)

Oops! Why didn't this remove the even numbers? It just replaced them with Null! This can be confusing for something not experienced with Sequence[]. The explanation is that Sequence[] gets removed from If before the evaluation of If starts, so we effectively end up with If[OddQ[x], x], which evaluates to Null. The traditional solution is If[OddQ[x], x, Unevaluated@Sequence[]]

With Nothing, we can simply use

{1, 2, 3, 4} /. x_Integer :> If[OddQ[x], x, Nothing]

This reads in a clear, intuitive way: "Replace odd numbers with themselves and even numbers with nothing." In the most common use case, i.e. list manipulation, it behave according to the most naive expectation.


Side note: Association[something] is not correct syntax in the sense that it does not evaluate to a true association data structure.

AssociationQ@Association[something]
(* False *)

Association["foo" -> something] does evaluate to a real association.


Since you mention the vanishing function ##&[], I want to point out an important difference between it and Sequence[]/Nothing:

Both Sequence[] and Nothing are removed at the beginning of the evaluation sequence, before any transformation rules are tried at all.

##&[] simply evaluates to Sequence[], which then is treated as usual. Thus it behaves the same as vanisher := Sequence[] would.

This causes differences like the following:

{Hold[Sequence[]], Hold[## &[]]}
(* {Hold[], Hold[(##1 &)[]]} *)

{{If[False, x, Sequence[]]}, {If[False, x, ## &[]]}}
(* {{Null}, {}} *)
Szabolcs
  • 234,956
  • 30
  • 623
  • 1,263
  • @Kuba My guess for why it was added is what I just described in the update. – Szabolcs Jun 24 '16 at 08:48
  • I think it is a good guess. +1 – Kuba Jun 24 '16 at 08:49
  • 4
    It only gets removed from lists is correct for Mathematica 10.4.0 and later; Nothing did get removed from associations in 10.2 and 10.3. Also Information[Nothing] is apparently in need of fixing. – ilian Jun 24 '16 at 16:15
  • 1
    @ilian - I wouldn't have expected it but recently saw some code with <|"key"->val,"key2"->val2,Nothing|> and thought it odd that the Nothing disappears. I guess a list is used as an intermediate – Jason B. May 16 '22 at 19:57