Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support generators #388

Open
pschachte opened this issue May 2, 2023 · 2 comments
Open

Support generators #388

pschachte opened this issue May 2, 2023 · 2 comments
Labels
enhancement New feature or request research project

Comments

@pschachte
Copy link
Owner

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 pschachte added enhancement New feature or request research project labels May 2, 2023
@PaulBone
Copy link

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.

@pschachte
Copy link
Owner Author

pschachte commented May 17, 2023

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
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request research project
Projects
None yet
Development

No branches or pull requests

2 participants