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

RFC: Host types for dentaku #14

Closed
wants to merge 9 commits into from
Closed

RFC: Host types for dentaku #14

wants to merge 9 commits into from

Conversation

jneen
Copy link
Contributor

@jneen jneen commented Dec 18, 2020

The Problem

We currently have a good deal of dentaku code that deals with functions or complicated dictionaries, whose values are currently represented by :numeric or complex dictionary types. It would be much simpler if we could write functions against some sort of :use-code type, and choose how to represent those values at runtime.

This proposal

This is a proposal to add "host types" - types that Dentaku doesn't necessarily know about, but that can be accessed or created through Opencounter-provided functions. They use the same syntax as concrete types - for example :entity or :use-code would be considered a host type. They may also take arguments - for example :my-cool-container(:numeric).

For example,

Dentaku::AST::Function.register 'calculate_zoning(:address, :use-code, :string) = :zoning', ->(address, use_code, locale) {
  # implement here
}

This places no restrictions on how these values are represented at runtime - they could be numbers, strings, Ruby objects, or hashes. But the checker will guarantee that a value of type :my-cool-type will only ever show up in places where it is expected.

Potential Issues

  • The syntax is confusing, since they look very similar to concrete types like :numeric. Should this be different? This would require a little bit of customization to the :param TypeExpression, since they have identical solving semantics and I'd like to avoid duplication.
  • If there is code in production that uses "use codes" as numbers (i.e. doing math on them, etc) this will break. On the other hand, this will in the future guarantee that such things are not possible.

@jneen
Copy link
Contributor Author

jneen commented Dec 18, 2020

For reviewers, please look at the last two commits only - the rest are from dependencies of this branch.

@rtlong
Copy link
Contributor

rtlong commented Dec 18, 2020

  • This seems interesting! I'm not sure I see the use-case clearly, so perhaps if you could give a more concrete example it would clarify.

  • I worry about that these look identical to concrete types while being implicitly defined. If there's a typo in one function definition it could lead to confusion. What if we had to explicitly register host types before use? I would feel okay about them looking like the concrete types in that case.

@jneen
Copy link
Contributor Author

jneen commented Dec 18, 2020

Explicitly registering them is a good idea.

@jneen
Copy link
Contributor Author

jneen commented Dec 18, 2020

The use-case is to allow us to have dentaku functions (in lib/dentaku_global_functions.rb) that operate on higher-level values, instead of using :numeric for things like :use-code, or dictionary types for :zoning-data. This will prevent config bugs that are currently possible like doing math on use codes.

http://jneen.net/ added 9 commits December 21, 2020 12:58
and report only at the very end in an ErrorSet. this patch causes the
checker to continue trying to typecheck after it has found an unbound
identifier (one where the type resolver returns nil). this means we
can still find type errors and other unbound identifiers and report a
more comprehensive and useful error at the end of the check.
@jneen jneen force-pushed the feature.host-types branch from 338f4ac to 9d6fa8a Compare December 21, 2020 17:58
@jneen
Copy link
Contributor Author

jneen commented Jan 7, 2021

After a conversation with @joshuabates, I think we're happy with having everything declared. This can also be used internally to Dentaku for its basic types like :string and :list (and actually makes a number of things cleaner). It would look something like this:

Dentaku::Type.declare(:string) # within Dentaku
Dentaku::Type.declare(:'use-code') # for all our bespoke OC types, incl. :zoning, :address, etc
Dentaku::Type.declare(:list, 1) # one type argument indicating the type of value in the list
Dentaku::Type.declare(:dict, 1) # similar to the above - a dict with arbitrary keys but one type of value

@jneen jneen mentioned this pull request Jan 7, 2021
@jneen
Copy link
Contributor Author

jneen commented Jan 7, 2021

Closing as superseded by #20

@jneen jneen closed this Jan 7, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants