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

Implement generators #29

Open
frostburn opened this issue Aug 22, 2017 · 5 comments
Open

Implement generators #29

frostburn opened this issue Aug 22, 2017 · 5 comments
Assignees

Comments

@frostburn
Copy link
Collaborator

frostburn commented Aug 22, 2017

Make it possible to turn quotes into interruptible programs.
Proposed example:

# Push an endlessly running quote onto the stack.
(
  0
  ( true )
  (
    dup yield  # New word similar to println on top level.
    1 +
  )
  while
)
*            # Turns the quote into a generator.
next         #=> 0
drop next    #=> 1
drop 5 take  #=> [2, 3, 4, 5, 6]
drop dup     # Saves generator state
2 take       #=> [7, 8]  (Takes from the duplicate instance)
2drop
3 take       #=> [7, 8, 9]  (Resumes taking from the first instance)
@frostburn frostburn self-assigned this Aug 22, 2017
@frostburn
Copy link
Collaborator Author

Some way of passing data back to the generator would also be nice.

@RauliL
Copy link
Owner

RauliL commented Aug 23, 2017

Iterators with similiar API could be implemented without any modifications to the interpreter.

@frostburn
Copy link
Collaborator Author

How would they work? Use an array as a stack or something?

@RauliL
Copy link
Owner

RauliL commented Aug 23, 2017

This is how I implemented them:

{
  "prototype": {
    "constructor": (
      "quote" swap !
    ),

    "next": (
      "state" swap has-own? ( "state" swap @ swap ) if
      "quote" swap @ rot swap call
      dup rot "state" swap ! swap
    ),
  },
} "generator" const

Usage:

( 1 + ) generator new  # Turn quote into generator.
0 swap                 # Sets initial value of generator to 0.
next println           # Returns 1
next println           # Returns 2
next println           # Returns 3

@frostburn
Copy link
Collaborator Author

If I understand correctly this only allows a single value to act as the state of the generator. It is also quite brittle if the quote happens to misuse the stack. Having a generator accidentally read or write onto your stack creates hard-to-debug issues.
In my proposed implementation any misuse would raise a range error on the generator's local stack.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants