<< Back to previous view

[ALGOM-10] :when clause in domonad relies on optional m-zero monad operation Created: 30/May/13  Updated: 05/Feb/14  Resolved: 05/Feb/14

Status: Closed
Project: algo.monads
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Glenn Vanderburg Assignee: Konrad Hinsen
Resolution: Completed Votes: 0
Labels: None


 Description   

In add-monad-step, the :when clause is implemented by this line:

(identical? bform :when)  `(if ~expr ~mexpr ~'m-zero)

which makes sense, except that m-zero is an optional operation for monads.
If :when is used with a monad that does not provide an m-zero operation,
the result (in cases where the condition evaluates to false) is an incorrect monadic value,
and strange, difficult-to-understand errors result.

I don't know that it's possible to make this work reasonably for all monads,
but at the very least the limitation should be documented, and ideally the use of :when
with a monad that does not define m-zero should issue a warning with a recommendation that
{:if :then :else} should be used instead.d



 Comments   
Comment by Glenn Vanderburg [ 03/Jun/13 8:23 AM ]

After more thinking, I think the best behavior would be to evaluate to m-zero if it's defined, and (m-result nil) otherwise. The behavior of :when is too useful with the state monad, and too cumbersome to duplicate with :if :then :else, to simply document the issue. The standard Clojure when macro evaluates to nil if the condition is false.

Comment by Konrad Hinsen [ 05/Feb/14 9:50 AM ]

The docstring for domonad clearly says that :when requires a definition of m-zero. I am not in favor of removing this rule, which has a clear role in the monad framework. "No value" is not in general the same as "a value of nil", so substituting (m-result nil) as a default for m-zero doesn't look like a good idea.

A better error message would indeed be desirable but I see no obvious implementation, because of the possibility of generic domonad forms for which the monad is specified later. As a workaround, I have replaced the ::undefined value by more descriptive symbols that convey a useful message to the reader:
https://github.com/clojure/algo.monads/commit/8b04e7b0bc9e70d27a497c4ce3bdb5cad37d7a1d

Generated at Thu Oct 23 08:48:23 CDT 2014 using JIRA 4.4#649-r158309.