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

Coretype suggestion: LazyType #8

Open
oliverpool opened this issue Jan 4, 2016 · 2 comments
Open

Coretype suggestion: LazyType #8

oliverpool opened this issue Jan 4, 2016 · 2 comments
Labels

Comments

@oliverpool
Copy link

Hi,

I have a suggestion for a new coretype.

I want to validate a recursive schema (an item list where each item can itself be an item list).
Instead of creating a //recursive type, I propose a //lazy type:

# /.meta/lazy, the schema for //lazy definitions:
{
  "type": "//rec",
  "required": {
    "type": { "type": "//str", "value": "//lazy" },
    "of": { "type": "//str" }
  }
}

Example if we define a new /example/itemlist type (a list of elements, that are either string or itemlist):

  type: //seq
  contents:
    - //str
    - type: //lazy
      of: /example/itemlist

The //lazy type should not be resolved during the schema construction, but at validation time.

Implementation example in python:

class LazyType(_CoreType):
  @staticmethod
  def subname(): return 'lazy'

  def __init__(self, schema, rx):
    if not {'type', 'of'}.issuperset(schema):
      raise SchemaError('unknown parameter for //lazy')

    if not schema.get('of'):
      raise SchemaError('no actual type provided for //lazy')

    self.schema = schema['of']
    self.rx = rx

  def validate(self, value, name='value'):
    validator = self.rx.make_schema(self.schema)
    validator.validate(value)

More than recursive schema, it allows to use a schema that will be later defined (in case of circular inclusion)

@rjbs
Copy link
Owner

rjbs commented Jan 8, 2016

The problems you're solving are things worth solving, but I don't like this solution. It requires that the user know the order in which things are loaded: they need to make things lazy only if (for example) the thing they depend on is not yet loaded.

Here is my counter-suggestion: add a means to pre-declare a namespace, promising that it will be added later.

rx = Rx.Factory()
rx.predeclare_type('tag:whatever:thingy')
...

Now you can use that type, and it will become a placeholder for later inflation. Nothing needs to know about it. Further, you could make learn_type automatically predeclare the name of the type being learned when they are configured, so recursion works without any extra work.

What do you think about that?

@oliverpool
Copy link
Author

Your idea looks quite good!

It enables recursion automatically and offers the advanced user a quite handy mechanism.

The only drawback that I see, is that it may be harder to implement (but the advantages are, I think, worth it)

jayvdb pushed a commit to jayvdb/Rx that referenced this issue Nov 21, 2017
@rjbs rjbs added the Wishlist label Jan 25, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants