Origins of generic programming with parameters
The notion that seemingly opposing forces can beneficially transform each other has been around for millennia and is found in all facets of nature and human existence. Hardware description languages are no exception. HDLs are a delicate balance of declarative/procedural, combinational/sequential, and strongly/weakly typed behaviors.
Two concepts we shall examine are static and dynamic typed polymorphism. These terms alone conjure up opposing forces. SystemVerilog uses them in a variety of different contexts, but generally, static implies fixed, either in existence or in size, for an entire simulation, as opposed to dynamic, which implies something that can change during the simulation. Polymorphism is the ability to manipulate different data types with a uniform interface – reusability being the key benefit.
Generic programming is one application of static polymorphism, and the factory design pattern is one application of dynamic polymorphism. 
The concept of generic programming is based on the ability to write code for an algorithm in a particular programming language that is independent of certain parameters that will be specified at a later point. Many languages call these parameters generics, hence the term generic programming. Ada is widely credited with pioneering this style of programming, which is also a precursor of VHDL. 
The intent of generic programming is to facilitate reuse by writing a portion of code once and invoking or instantiating it many times with different sets of generic parameters. Verilog has had this since its inception, with the instantiation of modules using overridden module parameters. Verilog only allowed the parameterization of values that might control bit widths or array sizes, but SystemVerilog adds the full parameterization of all data types, including class declarations.