I have the following code
class clazz
{
constructor {:axiom} () requires true
method su(x: int, y:int) returns (r: int)
{
r := x + y;
}
}
method {:main} Main() {
var c := new clazz();
var s := c.su(2,3);
print(s);
}
How can one make use of the clazz class? This is the specific error:
error CS1061: Type `__default.ClassRoomExample' does not contain a definition for `__ctor'and no extension method `__ctor' of type `__default.ClassRoomExample' could be found. Are you missing an assembly reference?
I've just figured out the problem. missing a { } in the constructor. Dumb.
Normally, the Dafny compiler would complain that you have declared something without a body, in this case a constructor without a body. But you have marked your constructor with {:axiom}, which tells the compiler that you left out of the body intentionally. That's why the error you're seeing comes from the C# compiler, not the Dafny compiler.
The {:axiom} attribute, which is uncommon, was designed for body-less lemmas. If you really want to omit the code for a constructor or method, you probably want to use the :extern attribute instead, which lets you implement the method in another .NET language.
Related
I try to use SharpPcap in F#, but I was blocked by this compiler error for two days.
I find the most releate answer is What is the error "A type instantiation involves a byref type." and what is a workaround in F#, but do not fit my context well.
Please help me work around it, Thank you!
open System
open SharpPcap
open SharpPcap.LibPcap
let device = new CaptureFileReaderDevice("test.pcap")
// try workaround 1
let new_package (sender: Object) (e: PacketCapture) = ()
let handler = new PacketArrivalEventHandler(new_package)
device.OnPacketArrival.AddHandler(handler)
// error: A type instantiation involves a byref type. This is not permitted by the rules of Common IL.
// try workaround 2
let new_package (e: PacketCapture) = ()
device.OnPacketArrival.Add(new_package)
// error: A type instantiation involves a byref type. This is not permitted by the rules of Common IL.
I think the error is because:
public event PacketArrivalEventHandler OnPacketArrival;
public delegate void PacketArrivalEventHandler(object sender, PacketCapture e);
public readonly ref struct PacketCapture
{...}
The delegate PacketArrivalEventHandler use PacketCapture as param type, but this is a readonly ref struct which can not use to define F# function to add to Event OnPacketArrival.
Pls help me workaround it, Thank you!
I want make this line pass the F# compiler:
device.OnPacketArrival.Add(new_package)
In c# it used in this way:
device.OnPacketArrival += new_package
[FS0412] A type instantiation involves a byref type. This is not permitted by the rules of Common IL.
You can't do this by using the F# IEvent first-class listening points, because in this case the type of device.OnPacketArrival ends up being IEvent<PacketArrivalEventHandler, ref<PacketCapture>>, whose second type parameter ref<PacketCapture> is not allowed. This is what the error message tells you.
But you can use the underlying .NET add_ and remove_ methods, which are analogs of property get_ and set_ methods, but for events. F# allows you to call these "hidden" methods explicitly, even though they're not listed in IDE completion lists.
device.add_OnPacketArrival handler
It works, because it's directly calling a method on the device object, rather than creating a wrapping value of type IEvent<...> and then calling .Add or .AddHandler on it.
What is the expected way to extend a class imported from a Javacript library while at the same being capable to call parent's members?
I tried several alternatives, using abstract classes apparently worked without errors but the child cannot call parent's abstract method, with interfaces there were no errors either but I cannot call to parent's class as there is no reference.
The best method I found is the following one overriding the mezhods, and althought the yielt code works, the compiler still emits an error:
error FSHARP: No abstract or interface member was found that corresponds to this override (code 855)
My current code:
[<Import("DataManager", from="library/data")>]
type DataManager<'Model> (conf:obj) =
class
member this.insert(_:'Model):Promise<obj> = jsNative
member this.update (_:'Model):Promise<obj> = jsNative
end
type MyAdaptor<'Model> (conf, inst)=
inherit DataManager<'Model> (conf)
let DB:obj = inst
do
printf "I've been created"
override this.insert(o:'Model):Promise<obj> =
printf "insert method comes with object:"
console.log o
base.insert o
//Constructors.Promise.Create o
override this.update(o:'Model): Promise<obj> =
printf "Update method comes with object:"
console.log o
base.update o
//Constructors.Promise.Create o
Previously I also tried to use just members and still call base's method but althought it compiled without issue, when calling instance's methods only parent's code was executed. I am afraid it might be a bug.
I also had several tries callint the inheritance manually in a self-made constructor but it usually fails to compile because the imported JS was either not recognize as a valid constructor or then I couldn't include the method definitions (I care about type safety).
It turns out that in F# people cannot override a method which has not been declared previously as abstract.
For that the solution was to declare the methods as abstract and provide a default implementation before override.
[<Import("DataManager", from="library/data")>]
type DataManager<'Model> (conf:obj) =
class
abstract member insert: 'Model -> Promise<obj>
default this.insert(_:'Model):Promise<obj> = jsNative
abstract member update:'Model -> Promise<obj>
default this.update (_:'Model):Promise<obj> = jsNative
end
After that it is possible to override the child class without issues.
Coming back to C++ after a hiatus in Java. Attempting to create an immutable object and after working in Java, a public const variable seems the most sensible (like Java final).
public:
const int A;
All well and good, but if I want to defensive check this value, how might I go about it. The code below seems strange to me, but unlike Java final members, I can't seem to set A in the constructor after defensive checks (compiler error).
MyObj::MyObj(int a) : A(a) {
if (a < 0)
throw invalid_argument("must be positive");
}
A public const variable for A seems like a clearer, cleaner solution than a getter only with a non const int behind it, but open to that or other ideas if this is bad practice.
Your example as it stands should work fine:
class MyObj {
public:
const int var;
MyObj(int var) : var(var) {
if (var < 0)
throw std::invalid_argument("must be positive");
}
};
(Live example, or with out-of-line constructor)
If you intend that MyObj will always be immutable, then a const member is
probably fine. If you want the variable to be immutable in general, but still have the possibility to overwrite the entire object with an assignment, then better to have a private variable with a getter:
class MyObj {
int var;
public:
MyObj(int var) : var(var) {
if (var < 0)
throw std::invalid_argument("must be positive");
}
int getVar() const { return var; }
};
// now allows
MyObj a(5);
MyObj b(10);
a = b;
Edit
Apparently, what you want to do is something like
MyObj(int var) {
if (var < 0)
throw std::invalid_argument("must be positive");
this->var = var;
}
This is not possible; once a const variable has a value it cannot be changed. Once the body ({} bit) of the constructor starts, const variables already have a value, though in this case the value is "undefined" since you're not setting it (and the compiler is throwing an error because of it).
Moreover, there's actually no point to this. There is no efficiency difference in setting the variable after the checks or before them, and it's not like any external observers will be able to see the difference regardless since the throw statement will unroll the stack, deconstructing the object straight away.
Generally the answer by N. Shead is the regular practice - but you can also consider:
Create domain-specific types and use them instead of general primitives. E.g., if your field is a telephone number, have a type TelephoneNumber which, in its constructor (or factory), taking a string, does all the telephone number validation you'd like (and throws on invalid). Then you write something like:
class Contact {
const TelephoneNumber phone_;
public:
Contact(string phone) : phone_(phone) { ... }
...
When you do this the constructor for TelephoneNumber taking a string argument will be called when initializing the field phone_ and the validation will happen.
Using domain-specific types this way is discussed on the web under the name "primitive obsession" as a "code smell".
(The problem with this approach IMO is that you pretty much have to use it everywhere, and from the start of your project, otherwise you start having to have explicit (or implicit) casting all over the place and your code looks like crap and you can never be sure if the value you have has been validated or not. If you're working with an existing codebase it is nearly impossible to retrofit it completely though you might just start using it for particularly important/ubiquitous types.)
Create validation methods that take and return some value, and which perform the validation necessary - throwing when invalid otherwise returning its argument. Here's an example validator:
string ValidatePhoneNumber(string v) {
<some kind of validation throwing on invalid...>
return v;
}
And use it as follows:
class Contact {
const string phone_;
public:
Contact(string phone) : phone_(ValidatePhoneNumber(phone)) { ... }
I've seen this used when an application or library is doing so much validation of domain-specific types that a small library of these domain-specific validator methods has been built up and code readers are used to them. I wouldn't really consider it idiomatic, but it does have the advantage that the validation is right out there in the open where you can see it.
I am trying to get this example translated from C# to F#
public class MyModule : NancyModule
{
private IMyDependency _dependency;
public MyModule(IMyDependency dependency)
{
_dependency = dependency;
Get["/"] = x =>
{
};
// Register other routes
}
}
(source 1)
However adding a parameter to constructor
type HelloModule(dependency) as self =
inherit NancyModule()
do
self.Get.["/"] <- fun _ -> "Hello" :> obj
(source 2)
results in a run-time exception: System.InvalidOperationException: 'Something went wrong when trying to satisfy one of the dependencies during composition ...
How can I correctly add a dependency like a data-source to the code? Or, generally, how do I pass something from outside of HelloModule to the inside?
I'm guessing this might be caused by not specifying the type of the dependency parameter of the constructor in your F# code. This would result in the F# compiler assigning that parameter a generic type, and then Nancy's dependency injection framework doesn't know what to inject.
Try the following and see if it fixes your problem:
type HelloModule(dependency : IMyDependency) as self =
inherit NancyModule()
do
self.Get.["/"] <- fun _ -> "Hello" :> obj
P.S. Naturally, for this to work, you'll also need to have some type that implements the IMyDependency interface, and have told the Nancy framework about that type. From this part of the Nancy documentation that you linked to, it looks like merely declaring the type is enough, but if that's not actually enough then you'll have to register the type manually. I'm not familiar enough with Nancy to give you specific advice there beyond what the documentation says.
These 4 lines compile but do not make sense to me :
open System
type mclas (y) =
member x.m = x.m
let z = mclas (1:>obj)
Question : In what case would we need to code in such way ? Am I activating subtle class features I am not aware of ?
Edit : If there is no use case, what is the status of this piece of code regarding compiler warning/error and is it eligible for some Issue raising on github ?
Note : At runtime, the debugger cannot evaluate variable z saying "Function evaluation timed out".
The member m actually compiles to something like this in IL:
.property instance object m {
.get instance object Program/mclas::get_m()
}
So m is a property of type object which has a getter that recurses endless. The C# equivalent of this would be:
public class mclas
{
public mclas(object y) { }
public object x {
get {
return x;
}
}
}
Because the recursion never ends, taking too long and/or there is a StackOverflowException happening when the Debugger tries to evaluate m, it cancels and spits out that the evaluation timed out.
And for your actual question: I don't think that you ever need this kind of self-reference in F#, at least I can't think of any possible use.
I think that this behaviour of the compiler makes sense, because a member without paramters will always compile to a get-only property, and then this would be the most obvious way of defining an infinite recursing property (just because this has no use doesn't mean that you can't do it).