Why is F# having a problem with partially overlapping module names? - f#

This one always gets me, and I fail to understand the problem the F# compiler is having here.
I have two files for two modules.
A.fs:
module A
//rest of the module goes here
B.fs
module A.B
//rest of the module goes here
When I build this project, I get:
A.fs(1, 8): [FS0247] A namespace and a module named 'A' both occur in two parts of this assembly
Why? There is nothing else in the project, other than the Program.fs. Am I wrong to assume I can break down modules into multiple files to keep things under control, while using a namespace like naming scheme? (obviously the compiler thinks so).
I want to understand the problem the compiler is having here and why I'm presented an error that refers to namespaces, even though I have no namespace declarations in my code.

Here is an answer to this question, just in case someone encounters the same error and googles their way here.
This bit from the modules documentation explains what is going on:
In the syntax for the top-level module declaration, the optional
qualified-namespace is the sequence of nested namespace names that
contains the module.
By declaring a module as A.B I'm actually declaring a module B in namespace A as per the above description. So I'm ending up with a module named A due to
module A and a namespace A due to module A.B and the compiler is telling me that I now have both a module and a namespace named A in this assembly.
I'll change this answer or un-accept it in case I'm wrong.

Related

How can I create a link to a random text in the same document? [duplicate]

I'm using :class: and getting a lot of warnings
WARNING: py:class reference target not found: mypkg.submodule.class.
I can't find anywhere in the documentation what exactly the requirements are for a correct cross-reference.
This is currently an incomplete list of requirements I think there are:
The module of the object needs to be importable
The object needs to exist inside of the module
The object needs to be documented somewhere else in the build with a :py:class::, :py:func:: or similar directive
This directive can be generated by the autodoc extension, in which case the object needs to have a docstring associated to it.
For something to be cross-referenced it has to first be "declared".
The Python domain (name py) provides the following directives for module declarations:
There are 2 cases to consider:
domain directives (.. domain:directive_name::) and
roles (:domain:role_name:).
The case of :class: you specify is actually the shortened syntax of writing the role :py:class: not to be confused with the directive declaration .. py:class::.
This directive can be generated by the autodoc extension, in which case the object needs to have a docstring associated to it.
The directive declarations are done implicitly by autodoc, but for objects without docstrings to be declared by autodoc you must use :undoc-members: option with the autodoc directives.
Members without docstrings will be left out, unless you give the undoc-members flag option:
.. automodule:: noodle
:members:
:undoc-members:
One effect of declaring an object is that it is inserted in the index. So you can check the index to make sure it has been declared and inserted. (However note that labels used in referencing arbitrary locations are not inserted in the index.)

How to add alias for extension namespace in wikimedia?

I am trying to create my custom copy of italian wikipedia from the dump.
I encounter the problem with some of extensions.
I have got the error:
Lua error in package.lua at line 80: module 'Modulo:String' not found.
The problem is that there is no 'Modulo:String' in my copy, but there is 'Module:String'.
I have tried to add alias for this namespace in my LocalSettings.php, as I did for categories, but for modules it didn't help.
$wgNamespaceAliases['Categoria'] = NS_CATEGORY; //this helped for categories
$wgNamespaceAliases['Modulo'] = NS_MODULE; //this does not work
Module namespace is part of Scribunto default namespace.
https://www.mediawiki.org/wiki/Extension_default_namespaces
How to solve the Lua error with loading modules?
The actual set of namespace aliases for Italian Wikipedia is (1); Categoria and Modulo are translations. To use them, just set $wgLanguageCode to it.
(I'm not sure why setting Modulo as an alias does not work; in theory it should. But it's not the easy way to set up a mirror.)

Why does Eunit not require test functions to be exported?

I'm going through the EUnit chapter in Learn You Some Erlang and one thing I am noticing from all the code samples is the test functions are never declared in -export() clauses.
Why is EUnit able to pick these test functions up?
From the documentation:
The simplest way to use EUnit in an Erlang module is to add the following line at the beginning of the module (after the -module declaration, but before any function definitions):
-include_lib("eunit/include/eunit.hrl").
This will have the following effect:
Creates an exported function test() (unless testing is turned off, and the module does not already contain a test() function), that can be used to run all the unit tests defined in the module
Causes all functions whose names match ..._test() or ..._test_() to be automatically exported from the module (unless testing is turned off, or the EUNIT_NOAUTO macro is defined)
Glad I found this question because it gives me a meaningful way to procrastinate and I was wondering how functions get created and exported dynamically.
Started by looking at the latest commit affecting EUnit in the Erlang/OTP Github repo, which is 4273cbd. (The only reason for this was to find a relatively stable anchor instead of git branches.)
0. Include EUnit's header file
According EUnit's User's Guide, the first step is to -include_lib("eunit/include/eunit.hrl"). in the tested module, so I assume this is where the magic happens.
1. otp/lib/eunit/include/eunit.hrl (lines 79 - 91)
%% Parse transforms for automatic exporting/stripping of test functions.
%% (Note that although automatic stripping is convenient, it will make
%% the code dependent on this header file and the eunit_striptests
%% module for compilation, even when testing is switched off! Using
%% -ifdef(EUNIT) around all test code makes the program more portable.)
-ifndef(EUNIT_NOAUTO).
-ifndef(NOTEST).
-compile({parse_transform, eunit_autoexport}).
-else.
-compile({parse_transform, eunit_striptests}).
-endif.
-endif.
1.1 What does -compile({parse_transform, eunit_autoexport}). mean?
From the Erlang Reference Manual's Module chapter (Pre-Defined Module Attributes):
-compile(Options).
Compiler options. Options is a single option or a list of options. This attribute is added to the option list when
compiling the module. See the compile(3) manual page in Compiler.
On to compile(3):
{parse_transform,Module}
Causes the parse transformation function
Module:parse_transform/2 to be applied to the parsed code before the
code is checked for errors.
From the erl_id_trans module:
This module performs an identity parse transformation of Erlang code.
It is included as an example for users who wants to write their own
parse transformers. If option {parse_transform,Module} is passed to
the compiler, a user-written function parse_transform/2 is called by
the compiler before the code is checked for errors.
Basically, if module M includes the {parse_transform, Module} compile option, then all of M's functions and attributes can be iterated through using your implementation of Module:parse_transform/2. Its first argument is Forms, which is M's module declaration described in Erlang's abstract format (described in Erlang Run-Time System Application (ERTS) User's Guide.
2. otp/lib/eunit/src/eunit_autoexport.erl
This module only exports parse_transfrom/2 to satisfy {parse_transform, Module} compile option and its first order of business is to figure out what are the configured suffixes for test case functions and generators. If not set manually, using _test and _test_ respectively (via lib/eunit/src/eunit_internal.hrl).
It then scans all the functions and attributes of your module using eunit_autoexport:form/5, and builds a list of to be exported functions where the suffixes above match (plus the original functions. I may be wrong on this one...).
Finally, eunit_autoexport:rewrite/2 builds a module declaration from the original Forms (given to eunit_autoexport:parse_transform/2 as the first argument) and the list of functions to be exported (that was supplied by form/5 above). On line 82 it injects the test/0 function mentioned in the EUnit documentation.

Why does Erlang have arity in its imports?

I find Erlang's module arity import /n where n is the number of arguments rather bizarre.
In Java and various other languages you can do something like:
import static com.stuff.Blah.myFunction;
Which will import all overloaded Blay.myFunction(..) regardless of parameters.
Besides I guess being explicit why did the language designers decide this was a good idea (I'm not trying to criticize the language... just curious)?
Does it have to do with code swapping?
Or does it have to do with hiding guard methods for recursion? If so why not allow arity on export but no need for arity on import?
Why would I want to be that explicit? That is import the two argument function but not the the three argument of myFunction?
You should be aware of what importing functions in Erlang really does. It is a pure textual transformation. If I do an -import(foo, [bar/1,baz/2]). it means that when I write a call like bar(5) or baz(a, 3) the compiler transforms these to foo:bar(5) and foo:baz(a, 3). That is all it does, nothing else. It doesn't check anything:
It doesn't check if the module foo contains the functions bar/1 or baz/2.
It doesn't even check if the module foo exists.
Really all it does is hide that you are calling a function in another module. That is why the recommendation from experienced Erlangers is "don't use it". It was a mistake. Unfortunately it is much easier to add stupid things than to get rid of them so we were never able to remove it.
"Does it have to do with code swapping?"
Yes, sort of. The unit of all code handling in Erlang is the module. So you compile modules, load modules, purge and delete modules. This means that there are no inter-module dependencies at all in the system and the compiler makes no assumptions about other modules when it is compiling a module. No assumptions are made that the environment in which a module is compiled will be the same in which it is run. That is why it is at runtime the system checks whether the function you are trying to call in another exists, or even if the module itself exists. That is why the import was a purely textual transformation.
Erlang was originally developed in Prolog.
In Prolog, the arity adds additional meaning to what you consider to be the 'arguments, as I understand from a function' in a procedural programming language. But that model does not apply here.
The so-called clauses 'married(X,Y).' and 'married(X,Y,Z).' imply a different kind of relationship 'married', which can be declared as married/2 and married/3.
In procedural programming, 'add(a,b)' or 'add(a,b,c)' are intended to generate the addition of a different number of arguments. That's not immediately the case in Prolog, where it is possible to have the relationship 'a and b, added' or 'a, b and c, added' mean something else. Needless to say, Prolog allows you to declare 'add' as you would expect a function would do. But it allows for more. More available meaning, means more need to control it.
And as in any module system, selecting what you want to expose to external clients makes sense: hence the declaration of arity.
Does it have to do with code swapping?
Kind of. The modules in Erlang are compiled separately (which is part of what allows code swapping), unlike Java classes, so the compiler doesn't know how many versions of the imported function with different arities exist. It could assume that all calls of a function with the given name come from the same module, of course, but the designers likely decided it wasn't particularly useful.
In fact, you rarely want to use imports at all, at least in my experience, just as you rarely use static imports in Java. Just write module:function, like Class.staticMethod.
Or does it have to do with hiding guard methods for recursion?
No, since not importing functions doesn't hide them in any way.

function 'Func/Arity' already imported from 'Module'

I defined both area/1 and perim/1 in modules sqaure and circle.
I want to import and use them in another module. Here is my import statements:
-import(square, [area/1, perim/1]).
-import(circle, [area/1, perim/1]).
I got these error messages.
~/test.erl:4: function area/1 already imported from square
~/test.erl:4: function perim/1 already imported from square
I know erlang does not support namespace. But since we can qualify a function call by specifying the module (i.e. square:area vs circle:area), I fail to see how the lack of namespace is the source of the error here.
So, what exactly caused the above error and how can I fix it?
In Erlang, "importing" a function from another module means being able to call it as if it were a local function, without the module prefix. So with this directive:
-import(square, [area/1, perim/1]).
you could write area(42) and it would mean the same as square:area(42).
However, if you include area and perim functions from two modules, it would be ambiguous which one you'd actually call when writing area(42).
As you correctly note, you can always qualify the function call with the name of the module, i.e. square:area(42) and circle:area(42) - so I would suggest doing so consistently and removing both import directives. This is also recommended by rule 6.6 of the Erlang Programming Rules - "Don't use import".

Resources