The official site of Typescript get me ask a question,
"Do we need to use namespace or not?".
The following quote explains the 2 things well:
It’s important to note that in TypeScript 1.5, the nomenclature has
changed. “Internal modules” are now “namespaces”. “External modules”
are now simply “modules”, as to align with ECMAScript 2015’s
terminology, (namely that module X { is equivalent to the
now-preferred namespace X {).
So, they suggest that TS team prefer namespace.
Further, it says we should use "namespace" to struct the internal module:
This post outlines the various ways to organize your code using
namespaces (previously “internal modules”) in TypeScript. As we
alluded in our note about terminology, “internal modules” are now
referred to as “namespaces”. Additionally, anywhere the module keyword
was used when declaring an internal module, the namespace keyword can
and should be used instead. This avoids confusing new users by
overloading them with similarly named terms.
The above quote is all from the Namespace section, and yes, it says again, but in a internal secnario.
but in the module section, one paragraph, says that:
Starting with ECMAScript 2015, modules are native part of the
language, and should be supported by all compliant engine
implementations. Thus, for new projects modules would be the
recommended code organization mechanism.
Does it mean that I don't need to bother with namespace, use module all along is the suggested way to develop?
Does it mean that I don't need to bother with namespace, use module all along is the suggested way to develop?
I wouldn't put it exactly that way... here's another paraphrase of what has happened. One upon a time, there were two terms used in Typescript
"external modules" - this was the TS analog to what the JS community called AMD (e.g. RequireJS) or CommonJS (e.g. NodeJS) modules. This was optional, for some people who write browser-based code only, they don't always bother with this, especially if they use globals to communicate across files.
"internal modules" - this is a hierarchical way of organising your variables/functions so that not everything is global. The same pattern exists in JS, it's when people organise their variables into objects/nested objects rather than having them all global.
Along came Ecmascript 2015 (a.k.a. ES6), which added a new formal, standard format that belonged in the "external modules" category. Because of this change, Typescript wanted to change the terminology to match the new Javascript standard (being that it likes to be a superset of Javascript, and tries its best to avoid confusion for users coming from Javascript). Thus, the switch of "external modules" being simplified to just "modules", and "internal modules" being renamed to "namespaces".
The quote you found here:
Starting with ECMAScript 2015, modules are native part of the language, and should be supported by all compliant engine implementations. Thus, for new projects modules would be the recommended code organization mechanism.
Is likely alluding to guidance for users who were not yet using (external) modules. To at least consider using it now. However, support for ES6 modules is still incomplete in that browsers as of May 2016 don't have built-in module loaders. So, you either have to add a polyfill (which handles it at runtime) like RequireJS or SystemJS, or a bundler (like browserify or webpack) that handles it at build time (before you deploy to your website).
So, would you ever use both modules (formerly "external modules") and namespaces? Absolutely - I use them both frequently in my codebases. I use (external) modules to organise my code files.
Namespaces in Typescript are extremely useful. Specifically, I use namespace declaration merging as a typesafe way to add extra properties to function objects themselves (a pattern often used in JS). In addition, while namespaces are a lot like regular object variables, you can hang subtypes (nested interfaces, classes, enums, etc.) off of their names.
Here is an example of a function with a property (very common in NodeJS libs):
function someUsefulFunction() {
// asynchronous version
return ...; // some promise
}
namespace someUsefulFunction {
export function sync() {
// synchronous version
}
}
This allows for consumers to do this common NodeJS pattern:
// asynchronous consumer
someUsefulFunction()
.then(() => {
// ...
});
// synchronous consumer
someUsefulFunction.sync();
Similarly, say you have an API that takes in an options object. If that options type is specific to that API,
function myFunc(options?: myFunc.Options) {
// ...
}
namespace myFunc {
export interface Options {
opt1?: number;
opt2?: boolean;
opt3?: string;
}
}
In that case, you don't have to pollute a larger namespace (say whole module scope) with the type declaration for the options.
Hope this helps!
Related
Do you know how to use Web Speech API in KMM project for Web application: https://developer.mozilla.org/en-US/docs/Web/API/Web_Speech_API/Using_the_Web_Speech_API
I'm using Kotlin to build the web app, and the web app require speech to text feature.
I'm not familiar with this particular WEB API, but here's the general process of wrapping global JS APIs in Kotlin so hopefully you'll be able to correct the odd inconsistencies yourself via trial and error.
Firstly, since the target API is global, there's no need for any meta-information for the compiler about where to source JS code from - it's present in the global context. Therefore, we only need to declare the shape of that global context. Normally that would be a straightforward task as outlined in this article, however there's a caveat here which requires some trickery to make it work on all the browsers:
As mentioned earlier, Chrome currently supports speech recognition with prefixed properties, therefore at the start of our code we include these lines to feed the right objects to Chrome, and any future implementations that might support the features without a prefix:
var SpeechRecognition = window.SpeechRecognition || webkitSpeechRecognition;
var SpeechGrammarList = window.SpeechGrammarList || webkitSpeechGrammarList;
var SpeechRecognitionEvent = window.SpeechRecognitionEvent || >webkitSpeechRecognitionEvent;
But let's ignore that for now since the API shape is consistent across the implementation, and name is the only difference that we'll address later. Two main API entities we need to wrap here are SpeechRecognition and SpeechGrammarList, both being classes. However, to make it easier to bridge the inconsistent names for them later on, in Kotlin it's best to describe their shapes as external interfaces. The process for both is the same, so I'll just outline it for SpeechRecognition.
First, the interface declaration. Here we can already make use from EventTarget declaration in Kotlin/JS stdlib. Note that the name of it does not matter here and will not clash with webkitSpeechRecognition when present since we declare it as an interface and as such we only care about the API shape.
external interface SpeechRecognition: EventTarget {
val grammars: SpeechGrammarList // or dynamic if you don't want to declare nested types
var lang: String
// etc...
}
Once we have the API shape declared, we need to bridge naming inconsistencies and provide a unified way to construct its instances from Kotlin. For that, we'll inject some hacky Kotlin code to act as our constructors.
// We match the function name to the type name here so that from Kotlin consumer's perspective it's indistinguishable from an actual constructor.
fun SpeechRecognition(): SpeechRecognition {
// Using some direct JS code to get an appropriate class reference
val cls = js("window.SpeechRecognition || webkitSpeechRecognition")
// Using the class reference to construct an instance of it and then tell the kotlin compiler to assume it's type
return js("new cls()").unsafeCast<SpeechRecognition>()
}
Hopefully this gives you the general idea of how things tie together. Let me know if something's still not quite clear.
I prefer working with files that are less than 1000 lines long, so am thinking of breaking up some Erlang modules into more bite-sized pieces.
Is there a way of doing this without expanding the public API of my library?
What I mean is, any time there is a module, any user can do module:func_exported_from_the_module. The only way to really have something be private that I know of is to not export it from any module (and even then holes can be poked).
So if there is technically no way to accomplish what I'm looking for, is there a convention?
For example, there are no private methods in Python classes, but the convention is to use a leading _ in _my_private_method to mark it as private.
I accept that the answer may be, "no, you must have 4K LOC files."
The closest thing to a convention is to use edoc tags, like #private and #hidden.
From the docs:
#hidden
Marks the function so that it will not appear in the
documentation (even if "private" documentation is generated). Useful
for debug/test functions, etc. The content can be used as a comment;
it is ignored by EDoc.
#private
Marks the function as private (i.e., not part of the public
interface), so that it will not appear in the normal documentation.
(If "private" documentation is generated, the function will be
included.) Only useful for exported functions, e.g. entry points for
spawn. (Non-exported functions are always "private".) The content can
be used as a comment; it is ignored by EDoc.
Please note that this answer started as a comment to #legoscia's answer
Different visibilities for different methods is not currently supported.
The current convention, if you want to call it that way, is to have one (or several) 'facade' my_lib.erl module(s) that export the public API of your library/application. Calling any internal module of the library is playing with fire and should be avoided (call them at your own risk).
There are some very nice features in the BEAM VM that rely on being able to call exported functions from any module, such as
Callbacks (funs/anonymous funs), MFA, erlang:apply/3: The calling code does not need to know anything about the library, just that it's something that needs to be called
Behaviours such as gen_server need the previous point to work
Hot reloading: You can upgrade the bytecode of any module without stopping the VM. The code server inside the VM maintains at most two versions of the bytecode for any module, redirecting external calls (those with the Module:) to the most recent version and the internal calls to the current version. That's why you may see some ?MODULE: calls in long-running servers, to be able to upgrade the code
You'd be able to argue that these points'd be available with more fine-grained BEAM-oriented visibility levels, true. But I don't think it would solve anything that's not solved with the facade modules, and it'd complicate other parts of the VM/code a great deal.
Bonus
Something similar applies to records and opaque types, records only exist at compile time, and opaque types only at dialyzer time. Nothing stops you from accessing their internals anywhere, but you'll only find problems if you go that way:
You insert a new field in the record, suddenly, all your {record_name,...} = break
You use a library that returns an opaque_adt(), you know that it's a list and use like so. The library is upgraded to include the size of the list, so now opaque_adt() is a tuple() and chaos ensues
Only those functions that are specified in the -export attribute are visible to other modules i.e "public" functions. All other functions are private. If you have specified -compile(export_all) only then all functions in module are visible outside. It is not recommended to use -compile(export_all).
I don't know of any existing convention for Erlang, but why not adopt the Python convention? Let's say that "library-private" functions are prefixed with an underscore. You'll need to quote function names with single quotes for that to work:
-module(bar).
-export(['_my_private_function'/0]).
'_my_private_function'() ->
foo.
Then you can call it as:
> bar:'_my_private_function'().
foo
To me, that communicates clearly that I shouldn't be calling that function unless I know what I'm doing. (and probably not even then)
I've used typescript from some months now and i have not understand the difference from namespaces and modules yet.
I know that before they were named internal and external modules, but with both i can import classes from other files. So what is the real difference?
As it is stated in the TS-handbook
there are 2 kind of modules: "internal" & "external". The code in the internal module is written in Typescript and the "external" is written in Javascript.
In order to align with new ECMAScript 2015's terminology they decided to rename them as follows:
"Internal modules" are now "namespaces".
"External modules" are now simply "modules", as to align with ECMAScript
So:
The way you write your code is different
When using modules the classes are not exposed in the global scope, while using namespaces:
Example:
Let's say you have public namespace sequence NamespaceA.NamespaceB.NamespaceC which exposes public class ClassD.
You can access all of these globally this way:
window.NamespaceA
window.NamespaceA.NamespaceB
window.NamespaceA.NamespaceB.NamespaceC
window.NamespaceA.NamespaceB.NamespaceC.ClassD
without saying window.NamespaceA = NamespaceA
and if you use modules you have to use the "magic" above
Namespaces are TypeScript's way of structuring code when you don't want the outputed Javascript code to use a module loader.
You can find more about namespaces vs modules in the handbook here.
I am in the process of transitioning my 'regular' Backbone projects into a combination of Backbone and RequireJS. While this process works pretty flawless, I still have one question.
Previously I declared a global namespace for my app to which I then bound all my models, views an collections. This is a tip I actually got from the Backbone ToDoMVC project.
So for example, the initialize method of a view could look like this:
initialize: function () {
app.employees = new app.EmployeeCollection();
app.employees.fetch();
}
This works because at the beginning of every file, I've done this:
var app = app || {};
Now when defining my files as AMD modules, the app namespace doesn't exist anymore, which means everything is much more encapsulated:
initialize: function () {
var employees = new EmployeeCollection();
employees.fetch();
}
The EmployeeCollection is loaded with RequireJS:
var EmployeeCollection = require('collections/EmployeeCollection');
Unfortunately I am still very new to Backbone and MVC in general, so I am unsure if this is a good or a bad thing.
What impact will this have on my project – is it okay to use an app namespace like I did previously or does this break any MVC/OOP 'rule'? Are there any Backbone specific consequences I need to be aware of?
Yes, loading the EmployeeCollection via requirejs is a good thing. This explicitly lists each module's dependencies and lets requirejs help you with loading modules in the proper order.
Both the app namespace approach and the requirejs approach are both valid. Backbone won't care which approach you take since with either you have the necessary View/Collection/Model constructor available to use. Personally I like the above benefits I mentioned of requirejs but it's a personal preference you'll have to decide.
However, you shouldn't use requirejs and an all-knowing app namespace together. If you're committed to requirejs then you should only use the app namespace sparingly with top-level data that most of your app will need, rather than attaching all of your requirejs modules to it.
For example, you might use it for a global UserModel that contains information about the current user. To do this you'd create an app object as a requirejs module just like you did with your EmployeeCollection, and then whatever module constructs the UserModel would require 'app' and do a simple assignment: app.user=user.
I said do this sparingly because using a global app namespaces for all your modules would sacrifice much of the benefit of requirejs and would cause you some sequencing pain. Namely:
You can no longer see the actual dependencies for each module declaratively and visualize easily how all your modules fit together. Instead of having the initialize function of your view (or whatever that is) require in 'collections/EmployeeCollection' you'd be requiring 'app'; not a lot of context there.
Requirejs will take care of loading required modules first before allowing your defining function to run. But if everything just requires 'app' then requirejs will only ensure 'app' is defined first and you're on your own for everything else. If app.Bar requires app.Foo, you have to do something to make sure app.Foo gets loaded and defined first.
On a similar note, if requirejs can't figure out all your dependencies because everything just requires 'app' then requirejs's javascript concatenator and optimizer tool (called r.js) will be either useless to you or require a lot of maintenance to add all your modules to a list that it should compile.
If you decide to use requirejs, embrace what it can do for you and just require in the modules you want instead of relying heavily on a global namespace. But there's not a right or wrong way choosing between these two approaches; each is used by lots of smart people.
I am working on some extensions for Rebol 3 (posix/fann/math).
To avoid global namespace pollution, I am exporting the functions with a simple prefix source identifier. For example: POSIX-FORK for fork, or POSIX-NANOSLEEP for nanosleep.
Is there any better approach or official Rebol naming convention?
That's a pretty standard naming convention for Rebol exports, though they should be lowercase in the code of course. The all uppercase thing is just a naming convention when referring to functions in chat clients or web sites that can't show code like this. You generally don't uppercase any words in Rebol code unless they are used for something else.
However, if you want to avoid global namespace pollution, declare your extension module with the options: [private] header. That will make it so the exports of your module are only imported by modules or scripts that request them explicitly with import or the needs header. This especially goes for modules or extensions that export low-level C-like APIs, which are best only imported by the modules that implement the high-level wrappers. It's good to remember that the module part of the extension is a full Rebol module, and it is often best to put your high-level wrapper code there and not export the C-like functions at all, keeping them for internal use.
An additional trick is that when you are exporting constants or enum values, it is best to put them in an object in your module and export the object instead. That way you don't export to the global namespace and you can protect the words from modification.
Another trick is to not export stuff at all and have people import your module using the import function. Unless you mark your module's words as hidden they will still be available even if they're not exported. This is a little inconvenient in most cases though, so it's better to use a private module instead. You can also export your high-level API and not export your low-level API, so the low-level API is available to import if someone wants to use it.
Check here for a more thorough answer about how modules and extensions are used: How are words bound within a Rebol module?