32

I was surprised to see Graph objects are atomic. Is there a way (through documentation or programmatically) to find all atomic heads?

The ones I know of are:

Integer
Rational
Real
Complex
Symbol
String
SparseArray
StructuredArray
Image (* since v9 *)
Image3D
Graph
ColorProfileData
Association
MeshRegion
BoundaryMeshRegion
Language`ArrayObject
ByteArray
QuantityArray
RawArray
RawData
Audio

Are there any others?

Others mentioned in the comments

Internal`Bag
System`Utilities`HashTable
System`RawArray
BooleanFunction
Dispatch (* since v10 *)
Dataset

Neural net functionality

AggregationLayer
BasicRecurrentLayer
BatchNormalizationLayer
CatenateLayer
ConstantArrayLayer
ConstantPlusLayer
ConstantTimesLayer
ContrastiveLossLayer
ConvolutionLayer
CrossEntropyLossLayer
DeconvolutionLayer
DotLayer
DropoutLayer
ElementwiseLayer
EmbeddingLayer
FlattenLayer
GatedRecurrentLayer
ImageAugmentationLayer
InstanceNormalizationLayer
LinearLayer
LocalResponseNormalizationLayer
LongShortTermMemoryLayer
MeanAbsoluteLossLayer
MeanSquaredLossLayer
NetChain
NetDecoder
NetEncoder
NetEvaluationMode
NetExtract
NetFoldOperator
NetGraph
NetInitialize
NetMapOperator
NetModel
NetNestOperator
NetPairEmbeddingOperator
NetPort
NetPortGradient
NetReplacePart
PaddingLayer
PartLayer
PoolingLayer
ReplicateLayer
ReshapeLayer
ResizeLayer
SequenceAttentionLayer
SequenceLastLayer
SequenceMostLayer
SequenceRestLayer
SequenceReverseLayer
SoftmaxLayer
SpatialTransformationLayer
SummationLayer
ThreadingLayer
TotalLayer
TransposeLayer
UnitVectorLayer
Greg Hurst
  • 35,921
  • 1
  • 90
  • 136
  • 7
    Strangely, SparseArrays are actually not atomic, but just treated for most purposes as if they were. They are the only non-atomic atoms, though, as far as I know. And in addition to your list, there are several other undocumented atomic objects as well, such as the Internal\Bag, theSystem`Utilities`HashTable, theSystem`RawArray, and probably others besides. Several objects that should be atomic (by the standards of theSparseArray) aren't, such asCompiledFunctionandLibraryFunction`. – Oleksandr R. Apr 27 '14 at 03:38
  • @OleksandrR. : see help file on AtomQ : like Complexand Rational numbers, SparseArray is atomic. List 'm using Cases[ Names["System*"], _?AtomQ]` – Wouter Apr 27 '14 at 15:55
  • 1
    @Wouter the definition of an atomic object is one that "cannot be divided into subexpressions" (although I would argue that a better definition is that its structure does not correspond to its FullForm). SparseArray clearly can be, regardless of whether AtomQ is true or false. Further down the documentation page for AtomQ we see some discussion about this, which shows the contradiction inherent in considering SparseArrays as atomic. Now, it may be that SparseArray truly is atomic in terms of its underlying implementation, but unlike other atoms it has a meaningful FullForm. – Oleksandr R. Apr 27 '14 at 17:10
  • 5
    The same question on Stack Overflow: (5964469) – Mr.Wizard Apr 28 '14 at 19:19
  • 6
    What is atomic and what isn't changes with versions. Image isn't atomic in v7 and v8. – Szabolcs Apr 29 '14 at 16:54
  • 2
    Associations should not be Atomic, based on the documented definition we currently use for what atomic means (doesn't have arbitrary subparts, can't be Mapped, etc). I hope we'll be taking that flag off in the next few point releases. – Taliesin Beynon Jul 14 '14 at 20:24
  • 2
    @TaliesinBeynon but on the other hand since <|a -> 1, b -> 2|>[[1]] does not equal a -> 1 as seen in FullForm[<|a -> 1, b -> 2|>], shouldn't it be considered atomic? – Greg Hurst Jul 17 '14 at 18:00
  • 4
    @ChipHurst AtomQ is defined as "an expression which cannot be divided into subexpressions", and has notes such as "You can use AtomQ in a recursive procedure to tell when you have reached the bottom of the tree corresponding to an expression." and "AtomQ gives True for any object whose subparts cannot be accessed using functions like Map". Clearly Association should not be AtomQ by these measures. But as you point out, it is also not NormalQ (which would mean that it behaves like its FullForm), if we had such a thing. AtomQ and NormalQ are currently "mixed together", we should separate them. – Taliesin Beynon Jul 17 '14 at 18:20
  • 1
    @TaliesinBeynon I would find it confusing if Associations were not AtomQ. If an expression is compound (not atomic) that usually implies that it always behaves as one would expect based on its full form, including for the purposes of pattern matching, part extraction, etc. This is a simple and predictable model, so I think that there's value in preserving it. Also consider that Hold[Association[1->2]] is a true compound expression. If Association is not considered atomic any more, then Hold[Association[1->2]] should behave precisely the same way as ... – Szabolcs Aug 05 '14 at 14:36
  • 3
    @TaliesinBeynon ... With[{a = Association[1 -> 2]}, Hold[a]]. But it doesn't, there are differences (again, part extraction, pattern matching). Also consider SparseArray, which also has parts, but again doesn't behave identically to its FullForm. SparseArray is also marked as AtomQ for this reason. Perhaps you could consider changing the description of AtomQ in the documentation instead of letting AtomQ return False for associations. What AtomQ really means is a bit complicated, but it's valuable to have it, and changing it would break either consistency ... – Szabolcs Aug 05 '14 at 14:39
  • 2
    @TaliesinBeynon ... or backwards compatibility, and has the potential to cause a lot of confusion. Of course the decision is up to you, I'm just trying to explain why Association is indeed AtomQ according to my mental model of what is atomic. It is definitely true that it is not as simple as "an expression which cannot be divided into subexpressions", but the real question is not whether AtomQ follows this definition. It is: which kind of AtomQ is a practically useful function? The actual one or the one that would be based on this simple definition? – Szabolcs Aug 05 '14 at 14:39
  • 2
    Dataset is atomic – Rojo Aug 05 '14 at 19:18
  • @Rojo Thank you! – Greg Hurst Aug 05 '14 at 19:59
  • 1
    Raw is outdated, but it is still atomic. – ybeltukov Oct 08 '14 at 15:00
  • @Xavier Graphics objects are not atomic. Try running AtomQ[Graphics[{Circle[]}]] or First[Graphics[{Circle[]}]]. – Greg Hurst Sep 23 '15 at 22:21
  • 2
    Let me also note, that AtomQ[Underflow[]] is True. Underflow[][[0]] is Real, but Hold[Underflow[]][[1,0]] is Underflow. But Hold[Evaluate[Underflow[]]][[1, 0]] is Real again, despite that Hold[Underflow[]] and Hold[Evaluate[Underflow[]]] look identical in FullForm. The same note applies to Overflow[]. – Vladimir Reshetnikov Mar 08 '16 at 19:34
  • 1
    Another word of caution: Hold[1/2], Hold[2^-1], Hold[Evaluate[1/2]] and Hold[Rational[1,2]] are all different expressions despite that some of them have the same FullForm and reported as identical by SameQ. Among them, Rational is atomic only in Hold[Evaluate[1/2]]. Also, it is not atomic in Rational[1, 2] &. So, Rational is not necessarily atomic, but only after it has had an opportunity to be evaluated. The same applies to other heads. The exact structure and atomicity of expressions may be not always preserved by Uncompress[Compress[…]]]. – Vladimir Reshetnikov Mar 08 '16 at 19:44
  • 1
    Also, it may seem surprising that both AtomQ[Infinity] and AtomQ[ComplexInfinity] are False. Both symbols are converted to expessions with DirectedInfinity head when evaluated, but it remains hidden both in StandardForm and InputForm. – Vladimir Reshetnikov Mar 08 '16 at 19:50
  • You also can create an atomic list if you want: {AtomQ[Raw[List, ""]], Head[Raw[List, ""]]}. But I suppose it counts as cheating. – Vladimir Reshetnikov Mar 10 '16 at 00:13

2 Answers2

17

You can executive the code in mma 10 or above version

EntityClass["WolframLanguageSymbol", "Atomic"]//EntityList

But is not all atomic function,as I know.

yode
  • 26,686
  • 4
  • 62
  • 167
6

Since it's the only "answer" I can see to post (as CW) there is also BooleanFunction as originally pointed out by Sasha.


In version 10 Dispatch tables are atomic.(1)

Array[# -> 2 # &, 5] // Dispatch // AtomQ
True
Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371