www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Calling std.variant.visit from a pure function

reply Paul Backus <snarwin gmail.com> writes:
As a learning exercise, I'm writing a simple AST evaluator for 
arithmetic expressions in D. (See 
https://gist.github.com/ckirkendall/2934374) In order to get a 
feel for functional programming in D, I decided to try and 
implement my solution in a functional style, using algebraic data 
types and pure functions.

Here's the code:

import std.variant;
import std.typecons;

enum Op { Plus, Minus, Times, Div }

alias Expr = Algebraic!(
     double,
     string,
     Tuple!(Op, "op", This*, "lhs", This*, "rhs")
);


double eval(Expr expr, double[string] env) pure {
     return expr.visit!(
         (double x) pure => x,
         (string v) pure => env[v],
         (Tuple!(Op, "op", Expr*, "lhs", Expr*, "rhs") bop) pure {
             final switch (bop.op) with (Op) {
             case Plus:
                 return eval(*bop.lhs, env) + eval(*bop.rhs, env);
                 break;
             case Minus:
                 return eval(*bop.lhs, env) - eval(*bop.rhs, env);
                 break;
             case Times:
                 return eval(*bop.lhs, env) * eval(*bop.rhs, env);
                 break;
             case Div:
                 return eval(*bop.lhs, env) / eval(*bop.rhs, env);
                 break;
             }
         }
     )();
}

When I compile this (using DMD 2.069 on Debian Linux), I get an 
error saying that I can't call visit from a pure function. This 
is surprising, since all visit does (in theory) is call the 
provided functions, and all of _them_ are pure.

My question is, is this an unavoidable limitation of visit's 
implementation, or is there a way to work around this?
Nov 03 2016
parent reply sarn <sarn theartofmachinery.com> writes:
On Friday, 4 November 2016 at 02:56:07 UTC, Paul Backus wrote:
 When I compile this (using DMD 2.069 on Debian Linux), I get an 
 error saying that I can't call visit from a pure function. This 
 is surprising, since all visit does (in theory) is call the 
 provided functions, and all of _them_ are pure.

 My question is, is this an unavoidable limitation of visit's 
 implementation, or is there a way to work around this?
I get the same error with 2.071. (I haven't installed the new dmd yet.) I suggest trying it with the latest dmd and filing a bug report. Taking a quick look at the library code (https://github.com/dlang/phobos/blob/master/std/variant.d), it *seems* like everything uses templates and functions returning auto, so the pureness of visit should be inferred if possible.
Nov 04 2016
parent Paul Backus <snarwin gmail.com> writes:
On Friday, 4 November 2016 at 23:38:47 UTC, sarn wrote:
 I suggest trying it with the latest dmd and filing a bug 
 report.  Taking a quick look at the library code 
 (https://github.com/dlang/phobos/blob/master/std/variant.d), it 
 *seems* like everything uses templates and functions returning 
 auto, so the pureness of visit should be inferred if possible.
Just tried it with 2.072, and I get the same error, so I've submitted a bug report: https://issues.dlang.org/show_bug.cgi?id=16662
Nov 04 2016