*ns* returns a namespace, not a namespace declaration. clojure.tools.namespace.parse.deps-from-ns-decl requires a declaration. There are many ways to read declarations from files. How do I get the declaration from the current namespace (*ns*). If this helps, here's what the REPL coughs up:
(deps-from-ns-decl *ns*)
IllegalArgumentException Don't know how to create ISeq from: clojure.lang.Namespace clojure.lang.RT.seqFrom (RT.java:542)
It turns out that asking questions like this one arises out of "meta" namespace work. In conjunction with Tawny OWL ontology definitions, my app rides on top of Clojure's namespace thinking. To answer my question, I had to create a sense of namespace in the app with it's own dependency declarations. Substrate namespace constructs are just that.
Related
As we know, using using namespace std; in header files is banned in all nontrivial projects. I hate this verbosity but understand its rationale behind.
However, I'm wondering if using C++20/23 modules could be a solution to this.
AFAIK declaring using namespace std; in global scope of headers has two biggest problems:
It pollutes the namespace of all users who include the header.
It pollutes the namespace of all identifiers within the header.
Personally I don't think the second problem is that severe, because the affected scope of identifiers is restricted within a single translation unit. So as far as I know the main reason why people are frowned upon is the first one.
And it seems to me that modules can solve the first one, like this:
export module frozenca;
import std.compat;
// ↓ I think this is definitely NOT OK
// export using namespace std;
// I think this is OK as this is not "propagated" outside of the module.
// Am I correct?
using namespace std;
// .. other details ..
I couldn't find any implementation that the code above compiles, so I couldn't test.
Am I correct?
For the factual form of your question, you are correct. using directives declared in a module unit don't get exported to the interface of that unit. Therefore, they and their effects are locally contained within the module TU which declares them. An import will not using namespace anything.
And for what it's worth, you cannot export using namespace at all. That's a compile error.
That having been said, you should be aware that std contains a lot of names. Many of those names are short, single-word names like begin or sort and the like. Names that you might want to use yourself in certain places.
By bringing in the entirety of std into the local scope, you're opening yourself up to all kinds of potential conflicts.
std:: is just five characters. Get used to them.
In some piece of code, I saw this declaration without understanding the exact meaning...
namespace std {}; // why?
using namespace std;
int main(){
...
}
That's a forward declaration of a namespace. You are not allowed to 'use' a namespace before it has been declared, so the declaration is necessary if you don't have any includes that bring in any part of 'std' beforehand.
Is it actually useful or necessary... That's doubtful. If you are including anything that brings in any part of std, you don't need the forward declaration. And if you are not, you don't need that using namespace std. So it might be a bit of boilerplate code - someone who was taught to 'always write using namespace std', and writes it even if it doesn't make any sense.
There is no point. I guess that code was written by someone who didn't really know what they were doing.
You'll get access to the namespace as soon as you include something anyway, so forward declaring it here doesn't really serve any purpose.
Contrary to the answers given above, I want to demonstrate a particular case where forward-declaring a namespace can be useful.
I make heavy use of Boost.Log in my application, where I use namespace lg = boost::log; for abbreviating long statements like boost::log::core::get()->.... The alias is declared in a general header file included by all components of my software, but I don't want to have all Boost.Log includes in this file, since not all components use logging. But in order to define the alias, I need to forward-declare boost::log. So my header file contains the following lines:
// boost::log namespace "forward" declaration
namespace boost { namespace log {}}
// Alternatively (from C++17 onwards):
namespace boost::log {}
// Namespace alias for boost::log.
namespace lg = boost::log;
That way, I don't need to define the lg alias in every file, which would be error-prone and tedious (and also I don't need to include the Boost.Log in the global header, which would possibly increase build times a lot).
If boost::log doesn't tell you much, think of other nested namespaces like std::chrono that one might want to alias.
I've read this thread, but it seems like there are no load and load-file in ClojureScript. Is it possible to separate a single namespace over multiple files?
The reason I want to do that is because I'm using Om and I want to separate components into different files. I can do it using separate namespaces, but then I will have to write the same requires in the beginning of each file and also the only way to call those components in the main file is like that:
(:require [some-project.sidebar :as sidebar])
...
(om/build sidebar/sidebar app-state)
i.e. I have to specify namespace before each component's name, which doesn't look pretty. Any ideas on how to improve it? I'm new to Clojure and ClojureScript, so maybe I'm missing something obvious?
There are a few things to note here
You can use :refer in your :require to import unqualified vars into a namespace. This is ok if there are a few, but can quickly get unwieldy if you tried to do it for everything.
Clojure applications are often structured in a tree like fashion where a main namespace requires sub namespaces, and so on, so you won't necessarily be importing the same namespaces into every namespace.
Even if it was possible to split a namespace across multiple files, it wouldn't be idiomatic Clojure. One file = one namespace is the norm.
If you wanted, you can def vars from one namespace into another to make one 'master' namespace to use in your other namespaces.
If you want to minimise the number of imports you have to do, make fewer namespaces and make them bigger.
I use cocos2dx. When I use classes from it I need to type cocos2d:: very often unless I type using namespace cocos2d;.
How can I avoid having to repeat the namespace all the time?
There are several ways to use stuff from other namespaces without having to repeat the namespace on every instance.
Import the entire namespace: using namespace cocos2d; You can now use all members of that namespace by only their name without the namespace prefix. This pollutes your own namespace with possibly quite a few names (depending on the contents of the imported namespace) which might not be desirable.
Import single names from that namespace: using cocos2d::MyClassName; This only imports the given name. The upside is that your namespace is not polluted. The downside is that you will have to do it for every namespace member you want to import. If you only need a few then this approach is fine.
Create a namespace alias: namespace co = cocos2d; Now you can refer to members of the cocos2d namespace as if they were members of the co namespace.
Create a type alias (since C++11): using CoClass = cocos2d::MyClassName; You can then refer to the aliased member with the identifier you chose. This can be especially helpful when an imported type shadows a type in your own namespace.
Chris's answer is correct and complete, but I would add that it's a better idea to explicitly specify every member's namespace to avoid ambiguity in other files that included your header file.
using namespace cocos2d; will implicitly use that namespace in every file that includes your header. You may put it inside the .cpp file. Same thing goes for using cocos2d::MyClassName; and namespace aliases.
Those will all work, but you shouldn't use them.
See that answer to the question: “using namespace” in c++ headers
I've often found myself in a situation where a 3rd party library could use some features or utilities that do not currently exist. In writing those companion utilties, the question arises as to which namespace to put them in.
I've picked a convention to shadow the 3rd party's namespace within my own, but I've not entirely convinced myself that there aren't unwanted repercussions lurking.
Example utility header:
#include <third_party/Thing.hpp>
namespace my_namespace
{
namespace third_party
{
typedef ::third_party::Thing<int,3> Thing3i
}
}
So the question is: Are there any significant negative consequences of doing this?
I don't particularly see anything wrong but I would caution that you do not pollute your namespace with the 3rd party one in case of ambiguity or bloat, there is a good answer to this issue with whether it is a good idea to nest namespaces: C++ namespaces advice, Nested NameSpaces in C++ and here Usage of namespaces in c++.
In general it should be safe and I would restrict using namespace third_party usage to just cpp files, otherwise if you were to declare using namespace third_party in your header then the code that #includes your header will accidentally acquire the third party namespace unless you really want that to happen.