Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

How to make Moose more "functional"?

by einhverfr (Monk)
on May 23, 2014 at 02:59 UTC ( #1087155=perlquestion: print w/ replies, xml ) Need Help??
einhverfr has asked for the wisdom of the Perl Monks concerning the following question:

fellow Monks,

I have been looking at exception handling in a few projects, as well as discussing functional programming with a few Scala developers. I really like the ideal of referentially transparent errors as an output of a function. This makes it possible to reason equationally about things.

So I have thought a bit about trying to create a tied hash type, which would always evaluate as undef in a scalar context, but would have fields for error messages, inputs that are out of bounds, etc. This could be returned from a function in place of an undef as a failure value.

Where I am having some difficulties is in finding a way to apply this to my work with Moose. In particular, the question is how to apply this in lazy builders in particular. I would assume that if a value in a lazy builder does not validate, it should return the error instead of raising it as an exception.

Has anyone tried to do this before? How deep am I looking at regarding modifications?

Comment on How to make Moose more "functional"?
Re: How to make Moose more "functional"?
by Anonymous Monk on May 23, 2014 at 06:51 UTC
Re: How to make Moose more "functional"?
by tobyink (Abbot) on May 23, 2014 at 06:59 UTC

    The way most people use them, builders (lazy or otherwise) are generally expected to throw an exception if they encounter an error building the value. In some cases, if undef is considered an acceptable value for the attribute, it may be preferable to return undef instead of throwing an exception. But this is probably not often.

    If you're wanting to achieve referential transparency, the best place to start is by making all your objects immutable - that is, use is => "ro" for all your attributes, use something like Sub::Trigger::Lock to lock down arrayref and hashref attribute values, don't use native attribute traits which act like mutators, etc.

    use Moops; class Cow :rw { has name => (default => 'Ermintrude') }; say Cow->new->name

      I understand that and I understand the reasoning behind it. The problem though is that exceptions break functional programming. Sometimes you have to use them anyway, such as something went wrong with the system outside the function (operating system error in a system call) but they are to be used sparingly.

      The basic guarantee of functional programming is that for any given x, f(x) has a definite value. If x is not in the domain of the function, then you have an undefined result. If you are having to stop execution of your program because you got a bad input and start recovery from that, then you are doing functional programming wrong.

      The way that this works in Scala is that you can raise exceptions which behave more or less the way they do in Java, but these should be used in very rare circumstances. You can also return errors from functions, thus preserving referential integrity.

      So I am trying to get away from the typical flow-oriented "oops I didn't expect that" approach to exceptions and try to have more referential integrity. But to do that, one needs to be able to annotate failures.

      What I am thinking is that maybe having a role which can wrap getters/setters of immutable objects and log error conditions in a further namespace might be a good way to go. If I had a tied hash that in scalar context always evaluated to undef but in a hash environment always evaluated to a system that would give me a proper view of the error, that might help.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1087155]
Approved by boftx
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (11)
As of 2014-09-22 21:03 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (202 votes), past polls