[erlang-questions] Fear and Loathing in Programming La La Land

Jan Burse janburse@REDACTED
Thu Mar 29 11:31:35 CEST 2012

Richard O'Keefe schrieb:
> 	fs = new FileReader();
> 	fs.SetFileName("foo/bar.txt");
> 	fs.SetSharing(Sharing.NONE);
> 	ln = fs.ReadLine();
> 	...

The above programming pattern has a couple of
advantages. It is not suitable to keep the
original file reader semantics, where the
constructor would for example fail when no
file is found, and thus no object reference
would be returned in the first place.

But otherwise it is very suitable for large
scale software development. It allows some
neat object evolution. The basic idea is to
start with a small set of classes and a
small set of attributes. In the above
example this would for example mean to only

    class: FileReader
    attribute: FileName

Then over the time it can happen that
it becomes necessary to support additional
attributes, i.e. a refinement of the classes
can happen. In the above example this could
for example mean to then have:

    class: FileReader
    attribute: FileName
    attribute: Sharing

The idea is then that the legacy code, or any
code that doesn't need the refinement, would
simply not set the sharing attribute. If no
setter is called then the object will have
the default value that the constructor assigns
to it. So that legacy code or any code that
doesn't need the refinement will not break.

The above technique is especially useful when
writing concurrent programs. Classes will
then be used to represent moment-intervals.
The basic idea is to have represented tasks
and their parameters by objects. The programming
pattern is then:

    Task task = new Task();

The performTask() method need not be synchronized,
since the object task is created on the fly by
the thread that needs the task. So it will not
be invoked by other threads. In the inner working
of the implementation of the perform task method
the code will then have easy access to the
parameter 1 and parameter 2.

The defaulting can then again be applied. For
example if the task is "buy milk", I can default
the shop location. So if I do:

    BuyMilk buyMilk = new BuyMilk();

This will go to the default shop location, i.e.
the farmer around the corner. If I want that the
milk is bought from a non default location, I can
use the corresponding parameter:

    BuyMilk buyMilk = new BuyMilk();
    buyMilk.setShop("shopping mal");

Interestingly the programming pattern can also be
used to compose tasks. This has been favored
Peter Coad's 'modeling in color' technique. See
for example:


Unfortunately the above approach is not found in
large shops. For example where MDA is used in bigger
companies the approach is effectively to have services
of the form:

        in parameter 1
        in parameter 2
        out parameter 1
        out parameter 2)

The MDA generated code, in one incarnation that I saw it, is a
class for the in/out parameter block and a service entry point
which takes this parameter argument, since Java does not
have out parameters:

     class ServiceNameParameter {
        in parameter 1
        in parameter 2
        out parameter 1
        out parameter 2)

     serviceName(ServiceNameParameter p);

Setter are then used to set the out parameters (sic!). The
resulting code is not only bloathed by the many parameter blocks,
but also the defaulting is done via service names. Namely we
might then end up with:


Erlang would be found somewhere in the MDA camp. Where a
functional service view is adopted. The out parameters would
not be passed as arguments, but returned in an agregate
result, right? With the same disadvantage of service verb name

I think one has a choice. Having attributes even in services
is as old as the internet. Look for example at the SMTP protocol,
it is nothing else than a setter sequence before a perform
instruction happens.


In Erlang I would do it properly functional
with the record type. So the Java programming pattern
can be modelled as follows:

     - record(buymilk, {shop='next farmer'}}

     BuyMilk = #buymilk{},
     pid ! BuyMilk

     BuyMilk1 = #buymilk{},
     BuyMilk2 = BuyMilk1#buymilk{shop='shopping mal'}
     pid ! BuyMilk2

But I guess more elaborate solutions are also
possible in Erlang.


More information about the erlang-questions mailing list