wybe icon indicating copy to clipboard operation
wybe copied to clipboard

Support generators

Open pschachte opened this issue 2 years ago • 2 comments

Tests in Wybe are akin to the Maybe monad in Haskell, or Prolog predicates that can fail (sometimes called semidet). Generators are a planned feature like the list Monad in Haskell or Prolog predicates that can have more than one solution(nondet). This would work in Wybe by providing a | operator that indicates that both what comes before and what comes after are results. This can be used in an expression, so the expression has multiple values, or as a statement, so the outputs of both statement sequences are valid outputs. Generators can then be used in a for loop to iterate over the results of the generator.

pschachte avatar May 02 '23 02:05 pschachte

You could also have a yield keyword for statements. Is this possible without yield?


gen myGenerator(...) -> ... {
   for(x in xs) {
      if (condition(x)) {
         yeild f(x)
      }
   }
}

In other words filter_map. I can write it with | in expressions but I'm not sure about | in statements.

PaulBone avatar May 16 '23 23:05 PaulBone

Good point; I hadn't thought about something like that. You could certainly do that with recursion, but I agree, it would be nice to be able to do it in a loop.

Generators are much more like nondeterminsim in a Mercury than they are like generators in a language like python. First, functions/expressions can't be generators, or you would lose referential transparency (consider x=gen(a,b), !print(x-x) vs. !print(gen(a,b)-gen(a,b))).

In a procedure, output parameters are specified in the signature, with their values specified by assigning the parameter names in the body. So you wouldn't yield a value, but it would make sense to assign some output parameters and then yield. Effectively, yield would create a disjunction between exiting the loop with the current variable bindings and continuing the computation. With a yield statement like that, you could write:

def {generator} myGenerator(xs, ?y) {
    for ?x in xs {
        when condition(x)
        ?y = f(x)
        yield
    }
}

pschachte avatar May 17 '23 06:05 pschachte