-
Notifications
You must be signed in to change notification settings - Fork 57
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
Proposal for ATD modules #265
Comments
A poor's man alternative is to simply use the C preprocessor (or another preprocessor) with #include to split an ATD file in different parts and have a Makefile generate the final .atd from those different parts. |
Thanks for this proposal. I am not sure I understand what are the upsides in terms of functionality.
Isn't this problem solved already with
I am not sure I understand what this means. Could you show an example maybe to illustrate the problem and how this proposal would fix it, please? |
@jchavarri in a previous company, we have an application-wide 2000-line file named
What bothers me about this is:
The many File
File
A difference is that
Yes, sure. I see no urgent need to remove the existing features, though. Deprecation notices should be good enough for a while, I think. |
This is an example of a partial export to JSON. We have a
Handwritten
This saves the application from defining whole different types for internal use and for JSON export. |
Yes, but with such an approach, the namespace remains global i.e. all the definitions are in scope whether you want it or not, which isn't great. For example, I want to be able to define a new
|
another issue with the "abstract" trick for modularity is that you can't inherit a property defined in another file:
But maybe this would not be supported either by the ATD module system because of this sentence "External types may remain opaque" ? |
Right. The goal of the current proposal is to compile an ATD file without inspecting its dependencies (other ATD files, OCaml implementation, Python implementation, etc.). The following wouldn't be possible:
We could consider another proposal where this is possible, but it seems to me that it would be strictly more complicated and could be implemented later as an extension if we change our minds. |
yes, less important for now. I can always move the definitions to the file that does the inherit. |
Do you really need to use |
well the JSON output of the CLI is inlining for example the location: field in its parent, so inherit is perfect for that. |
the semgrep-core JSON output for a match result has a location: (with inside a start: end: path:), but the JSON output of the CLI for a match result has directly the start: end: path: |
Still, I've also got a growing atd file, and all of its types are currently in the global namespace (which is mostly fine in my use case). I'm looking at splitting the atd file, and although I can do it at the build level by concatenating all the splitted files, a textual |
This looks like a fantastic idea, to me. In particular, I don't see the only benefit as 'remove extra lines at the top'; there's also the benefit of namespacing and readability. Content-aware inheritance is also important for our use-case, but I'd personally rather that use a different keyword. It's a fundamentally distinct set of constraints and trade-offs. Stick with |
The ATD language currently doesn't have a dedicated syntax for expressing dependencies on external type definitions and implementations. The current mechanisms use the special pseudo-type
abstract
or use the specialwrap
constructor. This is all clunky and hard to remember. As a result, users do their best to fit all the definitions in a single.atd
file. It's usually fine but in some cases, it's limiting.Issues being addressed
date
can be defined inA.atd
while two other APIsB.atd
andC.atd
use types defined inA.atd
but are otherwise independent of one another.Proposal
import
construct that declares which ATD-compatible units the current ATD file depends on, e.g.import basic_types
.basic_types.date
.atdgen
,atdj
,atdpy
, etc. should not be forced to access external ATD files when generating code for one given ATD file. The existence of an external type or its arity (number of type parameters of a polymorphic type) may not be checked because of this.Syntax
We introduce a new top-level
import
construct, which should (must?) occur at the beginning of the ATD file as it will affect all type definitions (since type definitions are reordered based on their mutual dependencies anyway).e.g.
REAL_NAME should be the name of the original ATD file without the
.atd
extension if such file exists.Referencing the types they provide must be unambiguous without having access to the external definitions. For that, the type names use the dot notation:
Note that this import semantics is similar to Python's. We don't really need to support the form
from MODULE import MEMBER
because it can be achieved using type aliases. For shorter type names, we can do this:Mapping to target languages
Each target programming language has a slightly different way of managing program units. It's up to the translator (
atdgen
,atdpy
, ...) to do the right thing and support language-specific ATD annotations. For the OCaml and Python targets (atdgen, atdpy), useful annotations could look like this:or more directly:
For commonly used external modules such as a
JSON
module, a code generator can place them in scope automatically. In OCaml for example, atdgen could emit the codeopen Atdgen_runtime
which would make aJSON
module directly available. For Python where the convention is for modules to use lowercase and where ajson
module already exists, we might want the nameJSON
to map toatdpy_json
rather than mapping toJSON
(nonstandard) orjson
(already taken). The goal is to make the use of common or standard external libraries not require ATD annotations. We want the following to just work:Note that the
t
represents the type of the main data structure provided by the module as is conventional in OCaml. It's a little nicer thanJSON.json
or than having to create an aliastype json = JSON.json
. It's not a requirement imposed by ATD.So far, all the implementations of an ATD module must provide the same collection of types and functions that work on those types. We could provide a way to express "hey, Python's JSON.t isn't named
t
but is namedjson
" but it's not clear if it's necessary since many other constraints exist for a module interface to be ATD-compatible. Whoever decides that a cross-language module such asJSON
should exist, should also specify the set of types it provides.The text was updated successfully, but these errors were encountered: