Providing this capability in a program is not trivial. The programs must be designed to to accept user-written components in appropriate places. There must be a way to store and manage them. Most important, since most users do not have the time or inclination to learn the tools and skills of a professional programmer, reasonable compromises are required. The expressiveness and generality of full-fledged programming languages are traded for usability by a variety of metaphors and tricks. Programming can be done much more easily within the metaphor -- a desktop with file cabinets and wastebaskets; a formula of spreadsheet locations or mathematical symbols; a sequence of GUI actions; a circuit diagram; an application-specific language -- than with conventional programming.
Because the appropriate metaphors, with their capabilities and limitations, differ widely depending on the users and their purposes, there is no one method of end-user programming. Instead there is a variety of techniques, such as Programming by Demonstration, visual programming, and many domain-specific languages and formalisms. Ideally there is a smooth progression from simple but limited metaphors, to more complex and powerful techniques as the user-programmer advances.