To sum up this thread, "#" is used in two different contexts: In a procedural context, it is used as a delay control to block execution of the current procedural thread, and in a structural context, it is used to declare or override a set of parameters.
Using the # allows you to override the parameter from above. If you do not provide an override, it uses the default value. SystemVerilog adds the ability to have no default, which forces the user to provide an override when instantiating a module instance. It also adds the ability to parameterize types as well as values.
It is unlikely the defparam statement will ever be removed; there is too much existing code out there using it. We been trying to get people to stop using it since 1990, but old habits are hard to remove. The reason this construct is bad is because it relies on hierarchical references to perform the override.
The latest version of the LRM can be found .