Skip to content
This repository has been archived by the owner on Oct 12, 2022. It is now read-only.

Clarify what "ambient" means #180

Closed
blakeembrey opened this issue Mar 11, 2016 · 8 comments
Closed

Clarify what "ambient" means #180

blakeembrey opened this issue Mar 11, 2016 · 8 comments

Comments

@blakeembrey
Copy link

While writing @typings I had to come up with a name for those non-external module definitions. I settled on ambient because it seemed intuitive, the TypeScript compiler would use it in error messages and all other "global"-like names are even more overloaded. However, there's one sentence with this interpretation that doesn't work in the handbook.

We call declarations that don't define an implementation "ambient".

So technically, does that mean even external module definitions are considered "ambient". Is there a better term we should adopt to explain external and non-external module definitions? Preferably something with less syllables and one word that can be used in CLI scripts.

@RyanCavanaugh
Copy link
Member

We prefer 'global' and 'module' to distinguish these cases. Sometimes we say 'script' and 'external module' as well. None of them are without other connotations, unfortunately.

'ambient' means "without implementation". It's a confusing term to use the scope of .d.ts files because all declarations in a .d.ts file are implicitly ambient.

@mhegazy
Copy link
Contributor

mhegazy commented Mar 11, 2016

"module"

A module is a file with a top level import or export, as defined by the ES6 spec. previously referred to as "external module"

"script"

A script is a file that is not a "module".
We should be using this instead of "global", as "global" is relative to the import, where as "script" is about the content of the file, not how it is used. this is also consistent with the ES6 termenology.

"ambient"

Anything that does not have an implementation, e.g.:

  • ambient variable declaration => declare var $: any
  • ambient class declaration => declare class C { foo(); } , etc..

A module can be ambient as well; so

  • "ambient module" is a .d.ts file with a top level import or export.
  • "ambient module declaration" is something of the form declare module "foo" { .. }

@blakeembrey
Copy link
Author

Ok, thanks. Perhaps I'll need to change this to globalDependencies and --global going forward, or --script and scriptDependencies according to the above comment? Which makes sense?

@unional
Copy link

unional commented Mar 14, 2016

About "script", will it always contribute to the "global" namespace?
http://www.ecma-international.org/ecma-262/6.0/#sec-runtime-semantics-scriptevaluation

Let globalEnv be realm.[[globalEnv]].
Let scriptCxt be a new ECMAScript code execution context.
Set the Function of scriptCxt to null.
Set the Realm of scriptCxt to realm.
Set the VariableEnvironment of scriptCxt to globalEnv.
Set the LexicalEnvironment of scriptCxt to globalEnv.

Sorry I'm not too good at reading specs.

If that is the case, what should it be called in the context of ".d.ts": "ambient declaration", "ambient script declaration", or "ambient script"?

UPDATE: An even harder question: what should it call if a module pollutes global namespace (such as jQuery)? Should jquery.d.ts be categorized as "ambient module", or "ambient script"?

@mhegazy
Copy link
Contributor

mhegazy commented Mar 14, 2016

module vs. script is about the file. i.e. does it have an import/export.
ambient vs concrete, is about declarations, whether they have implementation or not.
So, ambient script does not make much sense.

@unional
Copy link

unional commented Mar 14, 2016

module vs. script is about the file. i.e. does it have an import/export.

IMO that's the confusing part. Consider the following, which are modules and which are scripts?

// a.d.ts
import dr from 'domready';

// b.d.ts
declare function domready(): void;
export = domready;

// x.d.ts
declare module '~domready' {
  function domready(): void;
}

declare module 'domready' {
  import main = require('~domready');
  export = main;
}

// y.d.ts
declare namespace Y {
  export function foo() { ... }
}

If you mean top-level import/export, then "x.d.ts" and "y.d.ts" are script (while "x.d.ts" is a module),
if you mean any import/export, then all of them are modules (while "y.d.ts" should be script/global).

Another difficulty is to have different terms for "b.d.ts" and "x.d.ts".
That's essentially the difference between typings and tsd:

  • typed definitions in tsd are written in (similar to) "x.d.ts" format.
  • typings in typings should be written in "b.d.ts" format, the same format tsc -d exposes.

@unional
Copy link

unional commented Mar 14, 2016

Perhaps I'll need to change this to globalDependencies and --global going forward, or --script and scriptDependencies according to the above comment?

and

module vs. script is about the file.

If module vs script is about the file, then may be global is a better term in this context? What it tries to do is to describe the effect of the file, i.e. will it add the reference in the globalEnv or not.

@mhegazy
Copy link
Contributor

mhegazy commented Mar 14, 2016

b.d.ts is a module.
x.d.ts is a script

A script file dose not introduce a new scope; all its top level declarations live in the global scope. script file pollute the global namespace. you can, and should only have one of these per compilation per framework.

A module introduces its own scope, it provides isolation, and you can have multiple of them with no conflicts.

modules should be the way to go, unless you are really putting stuff in the global namespace, and you understand what that entails. This is the approach we tool with the changes in UMD work (see microsoft/TypeScript#7264). so something like jquery should be defined as a module with a UMD global export for $. this way it usable as a module and does not always live in the global namespace.

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

No branches or pull requests

4 participants