I have seen a couple of examples using either syntax of:
import Browser exposing (..)
or
import Browser
Are these equivalent? Does the second syntax implicitly exposes everything?
No those are not equivalent.
import Browser
is a qualified import where
import Browser exposing (..)
is an unqualified import.
When using qualified imports you still have to use the fully qualified names of the imported functions and types. With unqualified imports those become available without having to fully qualify them.
See Elm Modules and Imports for a good introduction.
Related
I want to make my custom inline function in .kt file using checkRadix function already implemented by Kotlin.
But I cannot import it. How can I import and use it?
I tried
import kotlin.jvm.JvmMultifileClass.*
kotlin.jvm.JvmMultifileClass.checkRadix(radix)
But I can't compile and there is no recommended resolution by IDE.
That function is marked as internal, which means it's only available within that module — i.e. within the Kotlin stdlib, not to your code.
I don't know why it's marked like that; maybe JetBrains consider it an implementation detail. But they clearly don't want it being used by any other code.
(Of course, it wouldn't be hard to reimplement yourself.)
When I import a library in elm, will importing only specific functions be more efficient than exposing everything ?
For example, when I import the Html module I usually just expose everything
import Html exposing (..)
This is convenient so as i keep writing I don't have to keep modifying the definition to add more Html tags, but is it efficient ? Will the compiler realize I don't need the entire library in my source code or will it import it all ?
I don't think there is a performance advantage in importing exactly the functions that you want to use. As farmio mentioned, before 0.19 the whole module is imported anyway and after 0.19 you can pass --optimize to eliminate dead code.
However, I strongly recommend against importing all the functions exposed by a module because it makes code very hard to read. Imagine this case:
import Html exposing (..)
import Svg exposing (..)
import Html.Attributes exposing (..)
import Svg.Attributes exposing (..)
We have pulled all the functions from those four modules into our own namespace, so everytime I read the name of a function which is not defined I have to guess where that function is coming from. The alternative is just exposing types but never functions:
import Html exposing (Html)
import Svg exposing (Svg)
import Html.Attributes as HAttr
import Svg.Attributes as SAttr
In this way, not once you will have to guess where the function is coming from.
Since elm 0.19 the compiler has function level dead code elimination. So your compiled App should be the same either way.
I'm not sure if exposing only used functions would shorten compile time tough.
https://elm-lang.org/blog/small-assets-without-the-headache
I'm confused about what the module specifier in these statements refer to:
export {bar} from "foo";
import {bar} from "foo";
What does "foo" refer to? It can't be a file since it would be something like "./foo". If it's not a file, I assume it's an ID. How is the ID defined?
I'm exporting from a js file, but the import would be part of an inline html script (type="module") in the firefox browser.
The browser version (and browser settings) have been verified to work with es6 modules.
Thanks in advance.
ES6 does not specify what the module specifier refers to.
It is indeed just that: an identifier. Nothing more.
It is left to the environment to resolve these identifiers to an actual module. A loader might interpret them as relative file paths, as global ids, as npm module names, as anything else.
In browsers, <script type="module"> took some time to specify, but it's here finally. A module specifier of "foo" is currently invalid, a browser will ignore that module as it doesn't know what to do with it. It will need something that resolves to an URL to load. Jake Archibald wrapped it up succinctly:
"Bare" import specifiers aren't currently supported. Valid module
specifiers must match one of the following:
A full non-relative URL. As in, it doesn't throw an error when put
through new URL(moduleSpecifier).
Starts with /.
Starts with ./.
Starts with ../.
Other specifiers are reserved for future-use, such as importing built-in
modules.
I am studying the Revised7 Report on the Algorithmic Language Scheme. My question is on section 5.6 Libraries.
In this section, it says:
When a library is loaded, its expressions are executed in textual order. If a library's definitions are referenced in the expanded form of a program or library body, then that library must be loaded before the expanded program or library body is evaluated. This rule applies transitively. If a library is imported by more than one program or library, it may possibly be loaded additional times.
What is this supposed to mean? Does it mean that a library is loaded only if an imported identifier is actually being referenced or already when the library is part of an import set of an expanded program or library? If the same library is being referenced by two other library imported by the same program, is the library loaded twice or just once?
As the loading of a library may have side-effects due to the execution of its expressions, the answers to these questions seem important to me. Also, do share the two libraries that import a third library its internal global variables?
I have done some experiments with chibi-scheme: Per program, chibi-scheme loads every library only once and even if none of its exported identifiers are actually referenced. In fact, this looks like a sensible and easily implementable thing to me.
P.S.: There is another point where I think the specification is a bit vague: What happens if, in a program, an import set imports an identifier named import? Does it mean that an immediately following line (import ...) is interpretated as a command or definition (depending on what the imported identifier import stands for) or still as an import set?
P.P.S.: What is even the reason for allowing more than one import declaration in a top-level program?
Let me attempt to answer each of your questions one-at-a-time. Also, if it would help, here is a link to the meta-language used to implement libraries in chibi scheme.
A library is loaded when it is imported via an import statement.
If a library's definitions are referenced in the expanded form of a program or library body, then that library must be loaded before the expanded program or library body is evaluated.
This just means that the library must be loaded before its definitions are referenced (or it would be an error, since the definitions would not be found).
If a library is imported by more than one program or library, it may possibly be loaded additional times.
This is implementation-dependent, so your library code should not make assumptions that it will only be loaded once.
What happens if, in a program, an import set imports an identifier named import?
Most likely, the new import identifier would shadow or replace the import, so that any import statements in the same scope would no longer work as expected. This might be implementation-dependent - if import is implemented as a special form then it would not be overridden by a newly introduced identifier.
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?