Simply issue the statement 'use Carrot::Modularity;' on top of your package and all of your code automagically becomes modular. Even the most monolithic parts with 10 levels of indentation transform into cool, powerful, encapsulated, polymorphic, abstract, re-usable, pro-active, agile units with cherry flavor. Of course not. But the mechanism is the default expectation for a Perl module, so it has to be briefly discussed here.
In simple Perl speak, the expressiveness provided by Carrot is the opposite of DWIM. The often promoted attitude 'Do What I Mean' might work nicely in a one-author setting, because there is only one meaning: that of the one and only author. But in a multi-author setting the opposite is more naturally: that meanings will be different. The interference of different meanings impose a high risk of failure to any project, not only for application development. The risk can be controlled by communication among programmers. Which relies on expressiveness.
One way to understand expressiveness is quantitatively as a measure. If language A is more expressive than language B, then... actually what? More can be expressed with it? Or expression is more efficient? Regarding to space or time, both of which exclude each other? What is the best rate between the number of constructs and their average parametrization? These questions lead to a complicated understanding of expressiveness which also depends on the problem domain. A simpler understanding is targeted here.
For the purpose of higher quality Perl code, expressiveness is seen as a simple qualitative model already mentioned in the preface. It corresponds to a directory structure with the following details:
::Diversity folding conceptual levels ::Attribute_Type classified choices ::Block_Modifiers extending proved ideas ::English instead of punctuation ::Modularity alignment to unities ::Constant global, local, familiar ::Package name management ::Object structure of objects ::Subroutine autoloading, generation ::Individuality bridging development speeds ::Controlled ::Singular ::Continuity utilization of time ::Coordination ::Operation ::Personality creating capabilities from possibilities ::Abstract, ::Reflective, ::Structured, ::Valued, ::Elemental, ::Functional ::Productivity ::Text, ::Internet ::Meta the core engine ::Monad ::Greenhouse
It's easiest to understand Carrot by looking at the Mica Environment (which isn't released yet, oops). If you look at Carrot code to understand Carrot, you might get lost. That standard route is as expensive as learning C by looking at the internals of a C compiler. If you still want to go this route despite the warning, be aware of recursive expectations: you can't use a feature which is going to be build. This isn't as obvious as it sounds, because there is no formal indication what feature is already available when. Again, these are internals you have to deal with the closer you come to ::Meta::.
Expressiveness shouldn't be confused with long names. Length aids readability and comprehension, both of which are a matter of intake. Expressiveness is (also) the out-take.
Nature is the most experienced developer - in principle. It doesn't develop computer software, or only indirectly through humans. But through a process called evolution it's developing life. Evolutionary biology is the science which provides us with the knowledge about life development. The knowledge and terminology was partly translated for computer programs in form of Object Orientation (OO). Inheritance, parent, class, homology, etc. have become useful concepts for the development of software, too.
However, there is a fundamental difference between evolutionary biology and object orientation. Simple genealogical trees explain development which happened in the past. But computer software requires an explaination of the future. One can extrapolate the future from the past, but how far and how accurate? That also depends on the quality of the model of the past.
Over-simplified models assume life forms consisting of one single organisms. That's justified to aim comprehension. But has little to do with reality. When you see a cow, you see the biggest partner in a meta-organism consisting of many life forms. The cow couldn't digest grass without the help of myriads of monads in its stomachs. It's a symbiosis of mammal and monads. (Biologists might prefer the term 'unicellular organisms' instead of moands. However, for a consistent style this document stays with 'monads'.)
The cow provides the physical work on the grass, while the monads provide the chemical work. Physical means, the cow chews the grasss in its mouth and warms it up in its stomach. Bite size and temperature are then ideal for the monads to do their work of splitting cellulose into carbohydrates, which can enter the blood stream of the cow.
The symbiosis gives the cow access to a rapid development cycle. That is essential for survival, because new types of grass appear faster than adopted types of cows. Though grass is slower than the cow in space (roots/seeds on the lawn), it could escape from the cow in time. The monads are a perfect match for the cow, because they can progress faster in time than grass.
One cow generation equivalents to 50.000 generations of monads. During a generation cycle of grasss, still around 4.000 generations of monads can be produced. Well, the numbers are sensational, but mammal reproduction cycles are apples and monad reproduction cycles are oranges. You cannot really compare these two. Monads achieve reproductive speed based on limited individuality. When a monad clones itself, there is no distinction between original and copy afterwards. Though monads are capable of sexual reproduction, the default is no individuality.
Now, the situation is not that lovely little monads feed the lucky cow with carbohydrates. Of course not. The cow needs to control the symbiosis, otherwise no carbohydrates will be left. Control means, which type of monads, how much of them and where. For example, even if just a few monads would grow in the blood stream instead of the stomach it'd be the quick and certain end of the cow due to sepsis.
Exercise of control is essential for a successful symbiosis. Control means that you can regulate which type of monads come to existence where. And where they go out of existence. That's a main point in Carrot. It's important to realize that Carrot goes beyond 'no individuality' which is just one extreme. There are many monads with no individuality at all. But there are also a handful of frequently used monads with limited individuality.
Monads have always been around in computer programs, they're not an invention of Carrot. For example, the exit status of a program is a monad by design. The operating system expects it, so the application has to deliver. It corresponds to the global variable $PROCESS_EXIT_CODE. Use of this monad is reasonably safe, because it won't grow due to external restrictions.
A monad like a global database handle (dbh) is more suspect. A global variable $dbh would certainly conflict with local variables of the same name. (A global variable is a name that is available regardless of the package name space you are in.) While $dbh is a immediate solution for programming, it kills development later. Because it's clear that one day there will be an improved database handle, $dbh2 and/or $dhb_improved and/or $ng_dbh and/or ... Until you can't really resolve conflicts with local variables and routines any longer. Uncontrolled monadic growth is a problem.
Like in biology, the monads provided in Carrot interface with the outside world. The operating system, files, or data of a different format in general. They should not be confused with factories, because all instances come from a factory, monadic or not. Here is a list of controlled monads shipped with Carrot. All of them are subject to inheritance:
- Class_Names - resolution of package names using an anchor for relative names and a mapping for absolute names. Restriction to a certain name space in form of ::Tamed.
- Customized_Settings - settings specified in terms of class names and default values in a .cdf file. Values are overridden with .cfg files in a search path.
- Localized_Messages - messages from plain text .tpl files in corresponding languages. Inheritance means, the .tpl file might be taken from
- Distinguished_Exceptions - fatal localized messages.
- Named_Data - shared class attributes.
- Mica Environment - not published, yet. More complex formats than .cdf or .tpl require a standalone approach.
- Contextfree_Grammar - not published, yet. The counterpart in the discussion of the Mica Environment.
There are too many simpler monads to list them here. Often these are classes based on a global variable. The classes add value on top of the global variables, so that they are more than mere wrappers.
Expressiveness is 'just' a monad. A meta monad to be more specific. Like with life forms it allows you to quickly compose different organisms into a bigger one. It's not always obvious what is being composed: organs to form an organism or organisms to form a meta organism? If limited individuality plays a role, then the latter might be the case.
It might sound trivial to have a monad for a package. It's pulled within the same namespace, but during three different phases. The name of the package stays the same, but it represents different things during the phases of diversity, modularity, and individuality. Therefore individuality of the meta monad can be experienced.
The same broad topic might be handled by similar monads. For example, error messages and exceptions might first be handled with die(), then with ::Translated_Errors, and finally with ::Distinguished_Exceptions. It's very important to understand that Carrot requires such similar but separate monads for development.
There is little point in trying to handle everything with ::Distinguished_Exceptions. The circular dependencies imposed by such an attempt were far worse than having two or even three monads for a similar looking purpose. It's vital for Carrot to recognize and maintain conceptual levels. That's actually expressiveness.
The controlled monads mentioned above are subject to object oriented inheritance. For example, the $distinguished_exceptions of a child uses the monad of parents as a search path (beware that other monads might work differently). Any specific distinguished exception in a parent will be available to the child as well.
However, inheritance is kept to one list (internally @ISA). There is no separate specification of inheritance for each monad.