How to disable warning in Nim - exception

I'm trying to suppress this warning:
Warning: inherit from a more precise exception type like ValueError, IOError or OSError. If these don't suit, inherit from CatchableError or Defect. [InheritFromException]
And I tried this:
type
ReturnException* = ref object of Exception {.warning[InheritFromException]:off.}
value*: BaseType

Use this:
type
ReturnException* = ref object of CatchableError
or :
type
ReturnException* = ref object of Defect
The difference is that a CatchableException can be caught by try/except, while a Defect always causes the program to exit.

The warning pragma is a switch that turns on and off. So you need to do something like this:
{.warning[InheritFromException]:off.}
type
ReturnException* = ref object of Exception
value*: BaseType
{.warning[InheritFromException]:on.}

Related

F#: how to satisfy IStructuralEquatable requirement when implementing an exception with a signature file?

I get a compiler error like this:
The type definitions for type '<ExceptionType>' in the signature and implementation are not compatible because the signature requires that the type supports the interface System.Collections.IStructuralEquatable but the interface has not been implemented
I narrowed it down to the fact that my exception's record type contains a field of a function type.
In my real code, I can work around this because I don't need this function in the exception, but I'm still curious, why do I get this error only when I have a signature file and how would I have my exception implement IStructuralEquatable?
Here's my signature file, Test.fsi:
module Test
type exception_type
exception TestException of exception_type
val throw_test_exception: unit -> unit
Here's my implementation file, Test.fs:
module Test
type exception_type = { value: unit -> unit }
exception TestException of exception_type
let throw_test_exception (): unit =
let r = { value = (fun () -> ()) }
raise (TestException r)
When there's no signature file, everything compiles just fine.
For your signature to work you need to define the full type of exception_type in your signature:
test.fsi
module Test
type exception_type = { value: unit -> unit }
...
Then the error will go away.
Signature files are typically not created by hand.. You can create them using the --sig option.
I'm not sure why would you want to pass a function in an exception. This does not make sense to me but if you elaborate your case (in another question), maybe I might be able to offer some suggestions.

F# try-with combined with reraise() returns valid type. Why?

I am trying to figure out the try-with in F#. And as i understood it, then the the return type of try must be identical to the return type of with.
But why is it then that when i do something like this:
let safeIndexTry (anArray : array<'a>) (i : int) =
try
Array. item i anArray
with
| :? System.IndexOutOfRangeException as ex -> printfn "%s" ex.Message
reraise()
then as i can figure it. then reraise() turns the return value to a valid type. in this case an int. But why is that? and is that for all types reraise will do that?
In general i find it a bit problematic that the two must have the same return type. I mean usualy you want to calculate some value and if it is unable to then catch an exception throwing a string message. Can some give me any guidance?
reraise is defined like this:
reraise : unit -> 'T
That means its result type fits the type of the encompassing function from which it is returned. Its return value is more or less meaningless because of the exception being thrown. In languages like Haskell it can be thought of as bottom.
Since the function has to have the same result type, a more idiomatic value to return would be the Option type. You can then return None if an exception is caught, and a Some goodValue when the operation is successful. This idiom is much preferred over using exceptions to handle control flow because all callers must explicitly handle both the None and Some cases, rather than having to wrap all calling code with exception handling wrappers.
Here is what your function would look like if converted to use Option:
let safeIndexTry (anArray : array<'a>) (i : int) : 'a option =
try
Some <| Array. item i anArray
with
| :? System.IndexOutOfRangeException as ex -> None

Actionscript check custom object defined type (not actual type)

Suppose I have a custom object variable that is set as null and I want to check it's type definition. How do I do it?
var a:MyObject = null;
// how do I check if a is MyObject?
//
// a is MyObject == false
// a instanceof MyObject == false
// getQualifiedClassName(a) <-- Exception
// typeof(a) == "object"
// describeType(a) <-- Exception
// a.constructor <-- Exception
// a.prototype <-- Exception
I think you're misunderstanding the way all of those examples in your question work.
They don't check the type that is associated with a variable - they check the type of the instance assigned to that variable. Here is a good example of why your examples don't make sense:
var prop:DisplayObject = new MovieClip();
trace(prop is MovieClip); // true
If this worked the way you thought it does, you would actually get false here.
All you're doing when you create a variable and give it a type is telling the compiler what type of instances it expects to see assigned to that property, and to throw an error if something that is not an instance of the expected type is assigned to it.
I don't think there is a way to determine what type a variable expects. Moreover, I think if you see a need to be checking what type a variable is expecting at runtime, then you're doing something terribly wrong.

Compare two interfaces using "is"

I am not sure if I am missing something here. I would like to compare two classes that uses the same interface. Is this possible? I understand that the is operator compares classes, but is there any similar function when you use interfaces?
// works
var effect1 : CrazyEffect = new CrazyEffect();
var effect2 : SaneEffect = new SaneEffect();
trace(effect1 is effect2) // false
// does not work
var effect1 : ISoundEffect = new CrazyEffect();
var effect2 : ISoundEffect = new SaneEffect();
trace(effect1 is effect2)
1067: Implicit coercion of a value of type ISoundEffect to an unrelated type Class.
Note the differences between concepts of a class and of an object. The former is a data type whereas the latter is a runtime instance of it, a variable. is operator can not compare one variable to another.
According to language reference
is Operator
Evaluates whether an object is compatible with a specific data type,
class, or interface. Use the is operator instead of the instanceof
operator for type comparisons. You can also use the is operator to
check whether an object implements an interface.
In other words, compiler expects the first operand to be a variable whereas the second operand should be a type identifier.
var sample:String = "Object is an instance of a class.";
^^^ ^^^
variable type identifier
However effect2 is not a type identifier but a variable. Hence the error message.
Unfortunately there is no generic operator to test for interface commonality. The only alternative is:
trace((s is ISoundEffect) && (t is ISoundEffect));
Update
Checking whether objects are instances of a same class can be done by comparing class names:
if (getQualifiedClassName(effect1) == getQualifiedClassName(effect2)) {
// true
}
For in depth discussion see Get the class used to create an object instance in AS3
Even though it will work with getQualifiedClassName, there's a better method to check whether two objects are instances of the same class:
a['constructor'] === b['constructor']
getQualifiedClassName is very slow and CPU intensive. Since the above code just compares property values it is lightning fast. And yes, constructor IS a property of every object, however FB will complain if you try to access it using dot-notation, that's why I use dynamic property access.

Type mismatch while using allCatch opt

In order to avoid Java exceptions I'm using Scala's exception handling class.
However, when compiling the following snippet:
import scala.util.control.Exception._
val cls = classManifest[T].erasure
// Invoke special constructor if it's available. Otherwise use default constructor.
allCatch opt cls.getConstructor(classOf[Project]) match {
case Some(con) =>
con.newInstance(project) // use constructor with one Project param
case None =>
cls.newInstance // just use default constructor
};
I receive the following error:
error: type mismatch;
[scalac] found : java.lang.reflect.Constructor[_]
[scalac] required: java.lang.reflect.Constructor[_$1(in method init)] where
type _$1(in method init)
[scalac] allCatch opt cls.getConstructor(classOf[Project]) match {
[scalac] ^
[scalac] one error found
What's going on here and how can I fix it?
I have no explanation, but a much shorter example which I hope pinpoint where the problem occurs. I think it is not related at all to exceptions, nor to reflection. Whether this behavior is an arcane but correct consequence of the specification or a bug, I have no idea.
val untypedList : List[_] = List("a", "b")
val typedList : List[String] = List("a", "b")
def uselessByName[A](a: => A) = a
def uselessByValue[A](a: A) = a
uselessByName(untypedList) fails with the same error as your code. The other combinations do not. So combination of a method with a generic call-by-name argument, called with a parameter of a generic with an existential type.
uselessByName[List[_]](untypedList) works, so I guess if you call explicitly opt[Constructor[_]] it might work too.
The type inference scheme has gotten confused by the types available--specifically, by the type of cls. If we write generic code:
def clser[A](cls: Class[A]) = allCatch opt cls.getConstructor(classOf[Project])
then it works perfectly okay. But you're probably doing something else--I can't tell what because you didn't provide the code--and this results in a mismatch between the expected and actual types.
My currently solution is to cast the constructor explicitly.
cls.getConstructor(classOf[Project]) becomes cls.getConstructor(classOf[Project]).asInstanceOf[Constructor[Project]].
I'm still wondering about the actual error and if there are better ways to resolve it -- so I'm going to leave this open.