-
Notifications
You must be signed in to change notification settings - Fork 591
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] Discussion on finding common scopes for import export related keywords. #2507
Comments
I don't have a strong opinion about this, except that JavaScript's
Import syntax varies wildly across different languages. Off the top of my head, I might mentally divide it into three cases: Dedicated syntaxIn these cases, there's probably a clearly identifiable JavaScript: import React from "react";
import "./style.css"; Python: import os.path
from os.path import join Just another functionWhen imports are done with a function or with function-like syntax, any of JavaScript: const fs = require("fs"); // Literally just a function call. Currently has a `support` scope.
import("./style.css"); // Technically special syntax, but works almost exactly like a function. Currently scoped `keyword.import`. Some kind of directiveLanguages that have multiple directives, including an import directive, should probably scope directives consistently, but we might add a Erlang: -import(lists, [map/2,foldl/3,foldr/3]). C: #include <stdio.h> Exports might be more diverse. A lot of languages have an explicit JavaScript (CommonJS): function foo () {}
module.exports = { foo }; Python: __all__ = ["foo"]
def foo():
pass Probably we can't hope to find a perfect solution that will handle every weird export system, but the well-behaved ones should be pretty easy. |
I agree It would be consistent to also have dedicated scope for keywords which denote statements which are evaluated at "compile-time" or "import-time". Import/export keywords are only one type of such pre-runtime stuff. I can remember of suggestions to introduce This discussion may therefore be related with #1860, which also makes a suggestion how to handle include/import keywords as Use of |
That would have been #1228 (comment) and the latest update on that seems to be #1860 (comment). Generally, we're unhappy with |
Imports tend to be declarations with side effects. They introduce names into scope (declaration), and include another module into your module graph (side effect). Consider JS: import 'pkg'
import A from 'pkg'
import * as A from 'pkg'
import {A, B, C} from 'pkg'
require('pkg')
const A = require('pkg')
const {A, B, C} = require('pkg') Logically, this means keywords that import should be scoped like Meanwhile, names declared by imports should be scoped somewhat like variable declarations, with appropriate symbol indexing. In most languages it would be local symbol index (only current buffer). This would be easy to decide if we had a generic scope for all declarations including variables, functions, types, imports, etc. |
Please note that a main intend is to distinguish preprocessor like (compile / import time) statements/keywords from normal runtime code. In C/C++ for instance we might want to highlight all kinds of Hence the idea is to use a common (2nd-level) scope such as
The question may be whether we want different colors for things like |
The rub is that in some languages (like C), imports are preprocessor-like, and in others (like Python and JavaScript) they are not. If we do choose a common scope for Given the diversity of import syntaxes, would it make sense to have more than one standard scope? We could have import foo from 'bar';
^^^^^^ keyword.declaration.import
// Dynamic imports are function-like, but technically special syntax.
const foo = await import('bar');
^^^^^^ support.function.import
// In Node.js, require is a bona fide function.
const foo = require('bar');
^^^^^^^ support.function.import
// FYI, JavaScript does have true directive syntax, though they're not currently scoped.
function f() {
'use strict';
^^^^^^^^^^ keyword.directive
} I know the whole point was to standardize on a single scope, but if we do that, then it would have to be something almost completely generic, like Personally, I could live with #include <stdio.h>
^^^^^^^^ keyword.directive.import
using namespace Foo;
^^^^^ keyword.declaration.import Thoughts? Is this the best of all worlds, or is it splitting the baby? |
A few more cases for consideration. Go's import _ "unicode/utf8" // Only side effect: add package to dependency DAG.
import "unicode/utf8" // Implicitly declare `utf8` (namespace).
import u "unicode/utf8" // Alias: declare namespace `u` but not `utf8`.
import . "unicode/utf8" // Include: declare all public symbols but not `utf8`.
var _ = utf8.UTFMax
var _ = u.UTFMax
var _ = UTFMax Swift's import Foundation // Declares `Foundation` and everything from it.
var a: Calendar // Comes from `Foundation`.
var b: Foundation.Calendar // Also allowed. I agree with Thom about schizo-scopes. Declaration keywords and compiler directives can be seen as intersecting concepts that overlap partially. All imports executed at compile time (which includes JS bundling) can be seen as compiler directives, but in languages without a distinct concept of compiler directives, it doesn't make sense to introduce that concept just for imports. Imports executed at runtime (like in Python) are most certainly not compiler directives. On the other hand, imports explicitly implemented as compiler directives, like C |
As the main intention behind It would look like:
|
Makes sense. One correction: the Node function Having a symmetric scope for In many languages, things are "exported" by making them public via modifier keywords such as Personally I would lean towards being precise with the semantics of individual keywords, which means |
One more to consider: in Haskell, one statement declares the current module and its exports, where submodules are exposed by using the same keyword: module CurrentModule (module SubModule, someFunction) where
import SubModule
-- the rest of the code This makes |
What I had in mind when writing down Same with export. Erlang has those I wouldn't ever have considdered visibility modifiers such as |
I have mainly opened this as an RFC issue to initiate some discussion on import export related keywords in various languages & to find (maybe ?) some common scopes.
This was mainly due to the fact that in JavaScript,
import
&export
are both scoped askeyword.control.import-export
(as well as any other keyword(s) likeexcept
,as
,from
in the said statements), which doesn't feel correct since one can explicitly mark animport
keyword askeyword.control.import
(|||ly forexport
) rather than having the current scope.Some of the other references I have been able to find are :-
keyword.control.import
keyword.control.directive.import
keyword.other.import
keyword.control.import
keyword.control.import
keyword.control.import
The text was updated successfully, but these errors were encountered: