I have a module defined in a file. This Module1 defines a struct and a function that I'm using in my main script. I include this module within another Parent module with include("module1.jl") so that Parent module can use the struct and function in module1. However, I'm having problems with the namespace. Here's an example in a single file:
#this would be the content of module.jl
module Module1
struct StructMod1
end
export StructMod1
function fit(s::StructMod1)
end
export fit
end
module Parent
#including the module with include("Module1.jl")
module Module1
struct StructMod1
end
export StructMod1
function fit(s::StructMod1)
end
export fit
end
#including the exports from the module
using .Module1
function test(s::StructMod1)
fit(s)
end
export test
end
using .Parent, .Module1
s = StructMod1
test(s)
ERROR: LoadError: MethodError: no method matching test(::Type{StructMod1})
Closest candidates are:
test(::Main.Parent.Module1.StructMod1)
If I remove the mode inclusion in Parent and use Using ..Module1 so that it loads from the enclosing scope, I get this error
ERROR: LoadError: MethodError: no method matching test(::Type{StructMod1})
Closest candidates are:
test(::StructMod1) at ...
In your example, s is a type object not an object of the type StructMod1. In order for s to be the latter, you need to call the constructor for that type. So you should write s = StructMod1() instead of s = StructMod1.
You can read more about types as first class objects here.
Related
Is it possible to call an extension function from another package without importing it?
Given an extension function:
package ext
fun Int.plusOne() = this + 1
Is there any way to call this function without importing the function first?
I can call non-extension functions without an import (ignore that the function does not need to be imported, just note that the syntax is valid):
val el: List<Int> = kotlin.emptyList()
I can instantiate classes without an import:
val str = java.lang.String("yo.")
But I have not yet found the equivalent for extensions (I know some examples are silly):
val i = 42
// All those are not valid syntax...
i.ext.plusOne()
ext.plusOne(i)
i.(ext.plusOne)()
i.(ext.plusOne())
ext.i.plusOne()
val pO = ext.plusOne
i.pO()
Bonus: Same question, but for extension properties.
Edit: To add to the list of invalid examples, even at places where the extension receiver is implicit, FQDNs are not allowed:
// Good:
import ext.plusOne
val four = with(3) { plusOne() }
// Unresolved reference:
val four = with(3) { ext.plusOne() }
No, according to the spec. A call can only be these forms:
A fully-qualified call without receiver: package.foo();
A call with an explicit receiver: a.foo();
An infix function call: a foo b;
An overloaded operator call: a + b;
A call without an explicit receiver: foo().
Notice that the "fully-qualified call" form, which is the only form that allows the use of package names, explicitly says "without receiver". However, your plusOne requires an Int as a receiver. In fact, by definition, all extensions functions/properties require a receiver by definition.
I also tried looking at callable references, in hopes of making a callable reference to plusOne using a fully qualified name, and then calling that callable reference. However, it turns out the syntax for those is even stricter.
Therefore, this cannot be done without modifying the ext package in some way, like adding a "wrapper" function.
After all, there is really no need for such a feature. Importing is not that hard - the IDE does it all for you these days. If you need to import two things with the same name, use an import alias:
import package1.extFunc as pack1ExtFunc
import package2.extFunc as pack2ExtFunc
I'd like to put the definition of a top-level Agda module and a local anonymous module using it in the same file. However, the top-level module has parameters, and I'd like to instantiate it in the second module.
So basically I would like to do something like this:
module MyModule (A : Set) where
foo : A -> A
foo x = x
module _ where
open import Data.Bool
open MyModule Bool
bar = foo true
However, the open MyModule Bool line fails with "The module MyModule is not parameterized, but is being applied to arguments".
Is there a way to do this without:
putting the second module in a separate file
indenting the contents of MyModule, i.e. something like
module _ where
module MyModule (A : Set) where
foo : A -> A
foo x = x
module _ where
open import Data.Bool
open MyModule Bool
bar = foo true
?
The precise thing you're asking for is currently not possible in Agda. The closest thing I can think of is the following:
module MyModule where
module Main (A : Set) where
foo : A -> A
foo x = x
private
module _ where
open import Data.Bool
open Main Bool
bar = foo true
open Main public
This will expose the contents of the main module in their generic form while hiding the private definition bar from other modules. However, when you import the module and want to instantiate the parameter, you cannot write open import MyModule Nat directly, you'd have to instead write
import MyModule using (module Main)
open MyModule.Main Nat
(for importing the generic version, open import MyModule would work just fine).
Given the following module declaration:
module ( myinterface.mymodport mybus, ... );
And assuming that myinterface has parameters, how do I specify them?
The interface instantiation happens only in the testbench, but now I want to synthesize the DUT, so the TB disappears.
This is an oversight in the SystemVerilog LRM. There's no syntax to specify a required set of parameters for an interface in a module header.
You might check your synthesis tool to see if they provide any way of specifying parameter overrides for the top-level synthesis instance.
You specify the parameter when you instantiate the interface; you do not specify it in the port list of the module. Given
interface myinterface #(parameter DATA_SIZE = 0);
...
All you need is
module mymodule (myinterface.mymodport mybus);
...
because somewhere else you have
myinterface #(.DATA_SIZE(64)) i();
interface myinterface #(parameter DATA_SIZE = 0);
logic [DATA_SIZE-1:0] AWID;
logic [31:0] AWADDR;
modport mymodport (input AWID, AWADDR);
endinterface
module mymodule (myinterface.mymodport mybus);
initial
$display("mymodule");
endmodule
module top;
myinterface #(.DATA_SIZE(64)) i();
mymodule m (.mybus(i));
endmodule
https://www.edaplayground.com/x/528x
In the following code;
unit module Fancy::Calculator;
what does 'unit' actually do? I know that the scope for the definition of the module becomes the file its declared in - as opposed to;
module Fancy::Calculator {
# module definition statements here
}
where the scope is obviously defined by the curlies but I can't see anything in the documentation that definitively states that that is all that it does and I'd be a little surprised if that's all that it did. Secondarily, after making such a declaration, can one declare unit class Whatever (class, module, whatever) half way down and call an end to the previous scope definition?
From a commenter (thanks Brad), it appears that is all it does. As for starting a second Module within the same file - you can't use unit module again - that produces;
===SORRY!=== Error while compiling /home/user/Fancy/Calculator.pm6
Too late for unit-scoped module definition;
Please use the block form.
...but as the message says, you can use the block form but whatever you declare is within the unit module namespace - Fancy::Calculator in this case. So these;
unit module Fancy::Calculator;
# The following available to the module user as Fancy::Calculator::Adder
class Adder {
method add { "Hi... I am a method who can add" }
}
# Starting definition of new module but its within Fancy::Calculator namespace
module Minus {
# Following available to the module user as Fancy::Calculator::Minus::Subber
class Subber {
method subtract { "Hi... I am a method who can subtract" }
}
# unless you add "is export" in which case its available by its short name
class Multiplyer is export {
method times { "Hi... I am a method who can multiply" }
}
sub divide() is export { "Hi... I am a sub who can divide" }
}
are accessed like this;
# In main
use Fancy::Calculator;
my $fca = Fancy::Calculator::Adder.new;
say $fca.add; # Hi... I am a method who can add
my $fcms = Fancy::Calculator::Minus::Subber.new;
say $fcms.subtract; # Hi... I am a method who can subtract
my $mul = Multiplyer.new;
say $mul.times; # Hi... I am a sub who can multiply
say divide(); # Hi... I am a sub who can divide
In TypeScript I can define a global/top-level namespace and use it in another file like so:
namespace foo.blah {
export function baz() {
console.log('hello');
}
}
And in another file, this works:
foo.blah.baz();
However, if I then import something from another module:
import Thing from 'boo';
namespace foo.blah {
export function baz() {
console.log('hello');
}
}
Suddenly my whole file is a module, the foo.blah namespace is local, not global, and the foo.blah.baz() call in the other file fails. export namespace ... just causes the namespace to become part of the module's export, not a global.
Is there a way to write a TypeScript file which imports from other modules but also defines global/top-level symbols?
At the moment I'm doing this:
import Thing from 'boo';
import * as $ from 'jquery';
namespace foo.blah {
export function baz() {
console.log('hello');
}
}
$.extend(true, window, {foo});
Which works, but the TypeScript compiler still can't see that foo.blah... exists as a global in other files.
(The file is the entry point for Webpack, and I'm trying to import things from other modules in the Webpack bundle and assign them to globals so they can be used in <script> tags on the page.)
When you add the import, you switch from internal modules to external ones, as the spec says:
In external modules, relationships between files are specified in
terms of imports and exports at the file level. In TypeScript, any
file containing a top-level import or export is considered an external
module.
http://www.typescriptlang.org/Handbook#modules-going-external
The philosophy behind external modules is to avoid global objects, why don't you create a new module with foo.blah (and all the stuff you need) and import it as TypeScript expects it?
The solution is to declare namespace in global.
declare global {
namespace foo.blah {
function baz() {
console.log('hello');
}
}
}
create a global.d.ts and put your type there
reference: cannot use d.ts file to load declaration merging
For me, the problem was to call the google-one-tap library from a module. The library is only available as script, but a types package exists: #types/google-one-tap.
Code snippet from the types package #types/google-one-tap/index.d.ts:
export as namespace google;
export const accounts: accounts;
export interface accounts {
id: {
initialize: (idConfiguration: IdConfiguration) => void;
disableAutoSelect: () => void;
[...]
As you can see in the above declarations file, there is a namespace google that contains objects/interfaces.
My code calling the library from a module:
google.accounts.id.initialize(...)
Without the fix (see below) the above code returns an exception when building: error TS2686: 'google' refers to a UMD global, but the current file is a module. Consider adding an import instead.
To be able to see the types and to get successful compilation, I declared a variable for the namespace google as follows. There is no code generated for declarations.
declare var google: {
accounts: google.accounts
};
// Now this works without errors.
google.accounts.id.initialize(...)
All of this is actually not recommended and red flags per documentation. Moreover it says that:
Multiple files that have the same export namespace Foo { at top-level (don’t think that these are going to combine into one Foo!)
That being said, I also had to preserve namespaced construct when migrating to ES6 modules because some systems don't offer a simple way to suddenly change namespace references like find & replace (MS Power Apps for example) or maybe you are really developing a library and want to preserve the entry point foo
If you had different first part of namespace per file, this would be enought:
(window as any).foo = foo
But having multiple, each file would overwrite previous window.foo
But there are ways what you can do when migrating to modules. With some webpack configuration, namespaces CAN be exposed as a public variables.
/*
Merge foonamespace between multiple files and expose it as a global variable. Otherwise foo namespace stays as module scoped variable.
exports global variable foo (because library.name is foo), and it uses a construct that:
- Copy the return value to a target object if it exists, otherwise create the target object first: Basically copies foo.* to foo object. This turns out to be a merge of namespaces.
- Namespace MUST BE exported.
- export: 'foo' means that instead of having global variable foo.foo.blah I have foo.blah (basically this should be the value whatever namespace starts with)
*/
output: {
...
library: {
name: 'foo', //or [name] if you have namespace same as entry point name
type: 'assign-properties' //or var or window if same namespace doesn't span multiple modules
export: 'foo'
},
}
There are many more ways to expose stuff to global scope (different type values available). Refer to webpack documentation
P.S. A module (having import or export statement) means variables get scoped as a module (rightly so) and that brings these challenges in the first place to preserve namespaced construct. Reference
Modules are executed within their own scope, not in the global scope; this means that variables, functions, classes, etc. declared in a module are not visible outside the module
P.S.2 How does webpack achieve it? The output looks something like:
var __webpack_export_target__ = (foo = typeof foo === "undefined" ? {} : foo);
var __webpack_exports_export__ = __webpack_exports__.foo;
for(var i in __webpack_exports_export__) __webpack_export_target__[i] = __webpack_exports_export__[i];
if(__webpack_exports_export__.__esModule) Object.defineProperty(__webpack_export_target__, "__esModule", { value: true });
Implication is second level namespace must be unique.