Wolfram Language Warts
this is a collection of weirdness or usual behavior in Wolfram language.
Equality Problem
Equal
does not return True
or False
even for obvious cases.
This is probably because, equal needs to represent equations, e.g.
x^2+ 3 == y
{} == 2 (* return expression as is. Version 13 *) (* using Reduce makes it true *) Reduce[ {} == 2 ] === True {{1}} == {2} (* return expression as is. Version 13 *) {{1.0}} == {2.0} (* return expression as is *)
Dynamic Scope (Block, Table, Do, Sum)
leaked variable when using Table
, due to dynamic scope.
(same happens with
• Block
• Do
• Sum
)
Solution: Avoid defining global variables with common short names, or, use uncommon names in Table
or Block
etc.
Example. Table
(* leaked x. *) y = x; Table[ x+y, {x, 1, 4}] (* output {2, 4, 6, 8} expect {1 + x, 2 + x, 3 + x, 4 + x} *)
Example. Block
(* dynamic scope of Block *) Clear[x,y]; y = x; Block[ {x=3}, y ] (* 3 *)
Module and With, No Variable Chain
Module
and With
, later variable do not see previous local variable's value.
(* Module, later variable do not see previous local variable's value *) Module[ {x=3, y=x+1}, y ] (* 1 + x *) (* expect 4 *) (* work around is to always assign values in the body. *) Module[ {x, y}, x=3; y=x+1; y] (* 4 *)
(* With, later variable do not see previous local variable's value *) With[ {x=3, y=x}, y ] (* return x *)
Block
do not have this problem
(* with Block, later variables do see previous local variable's value *) Block[ {x=3, y=x}, y ] (* return 3 *)
Module, Slow and Creating Temp Symbols
Module
is lexical scope.
but is slow.
Module
works by creating temp symbols for each of your local variable, and also internally increment a module variable counter in doing so.
practically, this means:
- do not use
Module
in a loop (slow) - sometimes you may see names such as x$1218 that you never declared, in the result.
(* scoping construct complexity *) Print[ $ModuleNumber ] (* 1218 *) Module[ {x}, Print[ x ] ] (* x$1218 *) Print[ $ModuleNumber ] (* 1219 *)
note, With
, do not have this creating new symbols problem.
however, later variable do not see previous variable value.
this makes With
much less useful.
Block
also do not have this creating new symbols problem.
however, its dynamic scoping creates unexpected leaking values from outside.
Clear[x,y]; y = x; With[ {x=3}, y ] (* x *)
Function is Not a Black Box
This is some weird effect, due to the nature of term rewriting system.
A function (here, the Function
), is not a black box unit.
It is merely a sequence of symbols (terms), that is ready to interact, be replaced, by rewriting rules.
xx = Module[{aa = (1 + x)}, Function[x, aa]] (* Function[x$, aa$1539] *) xx[y] (* 1 + x *)
(* correct behavior *) Clear[x,y]; y = x; Function[{x}, x+y][4] (* 4 + x *)
this is some sort of referencial transparency issue, or non-functional semantics.
(* example of non-functional semantics in WolframLang. or, violate referencial transparency principle. or, something. *) Clear[ f ]; (* defining a function with optional named parameters *) Options[ f ] = {xyz -> 4}; f[OptionsPattern[]] := OptionValue[ xyz ] ;
Syntax Shortcut Exception, Breaking Systematic Grammar?
not sure how to describe this, but it seems to break some minor syntactic consistency.
Optional

is this a bug
(* why is this, bug ? *) ReplaceAll[ {1, 2, 9, 3, 8, 2}, {x__, s:OrderlessPatternSequence[ 3,8,9 ], y__} -> {x, y, g[s]} ] (* {1, 2, 9, 3, 8, 2} *)
Credit: most of these are are documented in Wolfram language documentation.