I'm trying to check a mapping I've made to see if there are any values that match the word I'm sending. But it should return zero when there are no instances found. Instead, it's throwing Exception: Not_found. and exiting.
Is there any way I can catch this error? I thought Some and None were supposed to do the trick.
let word_count word =
match DictMap.find word word_mapping with
| None -> 0
| Some count -> count;;
I assume that DictMap is some result of applying the Map functor. Use try-with (rather than the option type) since find raises an exception rather than returning None when the key is not found.
let word_count word = try DictMap.find word word_mapping with Not_found -> 0;;
Related
Can anyone give me some examples of Failed Predicate exception in ANTLR.
and some examples that will clearly explain :- input mismatch VS failed predicate VS no viable alt exceptions in ANTLR. thanks in advance.
The names of the exceptions pretty much explain when they can appear. Only the failed predicate exception is a bit special.
NoViableAlt:
Thrown when you try to match block with several alternatives and none matches. Example:
r: 'a' | 'b';
Input: 'c'.
InputMismatch:
Thrown when you have input that partially matches. Example:
r: 'a' 'b' 'c' EOF;
Input: 'a' 'b' or 'a' 'c' EOF.
FailedPredicateException:
Thrown in certain situations where a path is guarded by a predicate and this path is the only possible match (or a required match), but the predicate prevents matching it. For example:
... | a ({condition}? b)
However if the block with the predicate is optional (so it's not required) then no predicate exception is thrown, like with:
... | a ({condition}? b)?
For more advanced use of these exceptions for generating better error messages see this error listener.
It seems that ? and catch have been accepted into Rust, but I am not able to use it properly:
let x = catch {
1
}
I think this should give me Ok(1). Instead, I get the error:
error: expected identifier, found `1`
--> src/main.rs:15:9
|
15 | 1
| ^
Is this syntax not yet supported in Rust, or is there a problem with my code?
This is going to sound very dumb, because it kind of is. You need to have
#![feature(catch_expr)]
fn main() {
let x = do catch {
1
};
}
Basically, catch, like default and union, cannot be made a keyword without breaking backwards compatibility. Since Rust has tried to guarantee that any code on 1.x will still work on 1.y, introducing default, union and now catch into the grammar has been all about figuring out the conflicts. For union and default, there are none - identifiers are never expected in those positions.
For catch, catch { 1 } can also be interpreted as a struct literal. Unless you require do (a reserved keyword) occur before catch - then there is no ambiguity. Yes, this is ugly, and everyone knows it.
Hopefully these nightmares go away when 2.0 comes around and we can break backwards compatibility. Quoted from the rust-internals discussion around the grammar woes of catch:
There's a growing list of other syntax we would ultimately like to repurpose in this way, but we generally avoid breaking the ability to run code that worked on 1.x on 1.y where y > x except in cases where the code was exploiting a compiler bug or was just a terrifically rare construction. Our stability guarantees demand we wait until 2.0 for most of these.
TL;DR: The RFC is accepted, but your syntax is slightly off (unfortunately) and the feature is still gated.
See Alec's excellent answer on how to actually use catch.
I encourage you to read the full error log:
error: expected identifier, found `1`
--> <anon>:2:21
|
2 | let x = catch { 1 };
| ^
error[E0422]: cannot find struct, variant or union type `catch` in this scope
--> <anon>:2:13
|
2 | let x = catch { 1 };
| ^^^^^ not found in this scope
error: aborting due to 2 previous errors
The clue is in the second error message:
cannot find struct, variant or union type catch in this scope
which really lets us know that catch is not recognized as a keyword by the compiler.
Since catch looks like any regular word, what happens is that the compiler attempts to parse this as building a struct or enum. Indeed, the syntax for building a struct or enum is:
struct X { name: i32 }
let x = X { name: 1 };
Therefore, the compiler sees <identifier> { and expects it to be followed by a list of <identifier>: <expression>. It reads 1, which is not an identifier, and reports the error that 1 is not an identifier.
Per The Definition of Standard ML (Revised):
The idea is that dynamic evaluation of a non-expansive expression will neither generate an exception nor extend the domain of the memory, while the evaluation of an expansive expression might.
[§4.7, p19; emphasis mine]
I've found a lot of information online about the ref-cell part, but almost none about the exception part. (A few sources point out that it's still possible for a polymorphic binding to raise Bind, and that this inconsistency can have type-theoretic and/or implementation consequences, but I'm not sure whether that's related.)
I've been able to come up with one exception-related unsoundness that, if I'm not mistaken, is prevented only by the value restriction; but that unsoundness does not depend on raising an exception:
local
val (wrapAnyValueInExn, unwrapExnToAnyType) =
let exception EXN of 'a
in (EXN, fn EXN value => value)
end
in
val castAnyValueToAnyType = fn value => unwrapExnToAnyType (wrapAnyValueInExn value)
end
So, can anyone tell me what the Definition is getting at, and why it mentions exceptions?
(Is it possible that "generate an exception" means generating an exception name, rather than generating an exception packet?)
I'm not a type theorist or formal semanticist, but I think I understand what the definition is trying to get at from an operational point of view.
ML exceptions being generative means that, whenever the control of flow reaches the same exception declaration twice, two different exceptions are created. Not only are these distinct objects in memory, but these objects are also extensionally unequal: we can distinguish these objects by pattern-matching against exceptions constructors.
[Incidentally, this shows an important difference between ML exceptions and exceptions in most other languages. In ML, new exception classes can be created at runtime.]
On the other hand, if your program builds the same list of integers twice, you may have two different objects in memory, but your program has no way to distinguish between them. They are extensionally equal.
As an example of why generative exceptions are useful, consider MLton's sample implementation of a universal type:
signature UNIV =
sig
type univ
val embed : unit -> { inject : 'a -> univ
, project : univ -> 'a option
}
end
structure Univ :> UNIV =
struct
type univ = exn
fun 'a embed () =
let
exception E of 'a
in
{ inject = E
, project = fn (E x) => SOME x | _ => NONE
}
end
end
This code would cause a huge type safety hole if ML had no value restriction:
val { inject = inj1, project = proj1 } = Univ.embed ()
val { inject = inj2, project = proj2 } = Univ.embed ()
(* `inj1` and `proj1` share the same internal exception. This is
* why `proj1` can project values injected with `inj1`.
*
* `inj2` and `proj2` similarly share the same internal exception.
* But this exception is different from the one used by `inj1` and
* `proj1`.
*
* Furthermore, the value restriction makes all of these functions
* monomorphic. However, at this point, we don't know yet what these
* monomorphic types might be.
*)
val univ1 = inj1 "hello"
val univ2 = inj2 5
(* Now we do know:
*
* inj1 : string -> Univ.univ
* proj1 : Univ.univ -> string option
* inj2 : int -> Univ.univ
* proj2 : Univ.univ -> int option
*)
val NONE = proj1 univ2
val NONE = proj2 univ1
(* Which confirms that exceptions are generative. *)
val SOME str = proj1 univ1
val SOME int = proj2 univ2
(* Without the value restriction, `str` and `int` would both
* have type `'a`, which is obviously unsound. Thanks to the
* value restriction, they have types `string` and `int`,
* respectively.
*)
[Hat-tip to Eduardo León's answer for stating that the Definition is indeed referring to this, and for bringing in the phrase "generative exceptions". I've upvoted his answer, but am posting this separately, because I felt that his answer came at the question from the wrong direction, somewhat: most of that answer is an exposition of things that are already presupposed by the question.]
Is it possible that "generate an exception" means generating an exception name, rather than generating an exception packet?
Yes, I think so. Although the Definition doesn't usually use the word "exception" alone, other sources do commonly refer to exception names as simply "exceptions" — including in the specific context of generating them. For example, from http://mlton.org/GenerativeException:
In Standard ML, exception declarations are said to be generative, because each time an exception declaration is evaluated, it yields a new exception.
(And as you can see there, that page consistently refers to exception names as "exceptions".)
The Standard ML Basis Library, likewise, uses "exception" in this way. For example, from page 29:
At one extreme, a programmer could employ the standard exception General.Fail everywhere, letting it carry a string describing the particular failure. […] For example, one technique is to have a function sampleFn in a structure Sample raise the exception Fail "Sample.sampleFn".
As you can see, this paragraph uses the term "exception" twice, once in reference to an exception name, and once in reference to an exception value, relying on context to make the meaning clear.
So it's quite reasonable for the Definition to use the phrase "generate an exception" to refer to generating an exception name (though even so, it is probably a small mistake; the Definition is usually more precise and formal than this, and usually indicates when it intends to rely on context for disambiguation).
I'm writing a REST service in Erlang and need to verify the received data before passing it to other internal functions for further processing; in order to do that, I'm currently using nested case expressions like this:
case all_args_defined(Args) of
true ->
ActionSuccess = action(Args),
case ActionSuccess of
{ok, _} -> ...;
{fail, reason} -> {fail, reason}
end,
_ ->
{fail, "args not defined"}
end,
...
I realize this is kind of ugly, but this way I can provide detailed error messages. Additionally, I don't think the usual make it crash philosophy is applicable here - I don't want my REST service to crash and be restarted every time somebody throws invalid arguments at it.
However, I'm considering abandoning all those cases in favor of an umbrella try/catch block catching any badmatch errors - would this work?
fun() ->
true = all_args_defined(Args),
{ok, _} = action(Args).
%% somewhere else
catch fun().
Since what you want to achieve is error reporting, you should structure the thing around the execution of actions and reporting of the result. Perhaps something like this:
execute(Action, Args) ->
try
check_args(Args),
Result = action(Action, Args),
send_result(Result)
catch
throw:{fail, Reason} ->
report_error(Reason);
ExceptionClass:Term ->
%% catch-all for all other unexpected exceptions
Trace = erlang:get_stacktrace(),
report_error({crash, ExceptionClass, Term, Trace})
end.
%% all of these throw {fail, Reason} if they detect something fishy
%% and otherwise they return some value as result (or just crash)
action(foo, [X1, X2]) -> ...;
action(foo, Args) -> throw({fail, {bad_arity, foo, 2, Args}});
action(...) -> ...
%% this handles the formatting of all possible errors
report_error({bad_arity, Action, Arity, Args}) ->
send_error(io_lib:format("wrong number of arguments for ~w: "
"expected ~w, but got ~w",
[Action, Arity, length(Args)]));
report_error(...) -> ...;
report_error({crash, Class, Term, Trace}) ->
send_error(io_lib:format("internal error: "
"~w:~w~nstacktrace:~n~p~n",
[Class, Term, Trace])).
I've had this problem while developing an application that create users.
I first come with a solution like this:
insert() ->
try
check_1(), % the check functions throw an exception on error.
check_2(),
check_3(),
do_insert()
catch
throw:Error1 ->
handle_error_1();
throw:Error2 ->
handle_error_2();
_:Error ->
internal_error()
end.
The problem with this solution is that you lose the stack trace with the try...catch block.
Instead of this, a better solution is:
insert() ->
case catch execute() of
ok -> all_ok;
{FuncName, Error} ->
handle_error(FuncName, Error);
{'EXIT', Error} ->
internal_error(Error)
end.
execute() ->
check_1(), % the check functions throw an exception on error.
check_2(),
check_3(),
do_insert().
This way you have the full error stack on Error.
I have faced exactly the same question when writing my own REST services.
Let's start with the philosophy:
I like to think of my applications like a box. On the inside of the box are all of the parts I built and have direct control over. If something breaks here, it's my fault, it should crash, and I should read about it in an error log. On the edge of the box are all of the connection points to the outside world - these are not to be trusted. I avoid exception handling in the inside parts and use it as needed for the outer edge.
On similar projects I have worked on:
I usually have about a dozen checks on the user input. If something looks bad, I log it and return an error to the user. Having a stack trace isn't particularly meaningful to me - if the user forgot a parameter there is nothing in my code to hunt down and fix. I'd rather see a text log that says something like: “at 17:35, user X accessed path Y but was missing parameter Z”.
I organize my checks into functions that return ok or {error, string()}. The main function just iterates over the checks and returns ok if they all pass, otherwise it returns the first error, which is then logged. Inside of my check functions I use exception handling as needed because I can't possibly consider all of the ways users can screw up.
As suggested by my colleagues, you can alternatively have each check throw an exception instead of using a tuple.
As for your implementation, I think your idea of using a single exception handler is a good one if you only have the single check. If you end up needing more checks you may want to implement something like I described so that you can have more specific logging.
Does anyone know the real difference between the two ways of type casting in Flex 3?
var myObject1:MyObject = variable as MyObject;
var myObject2:MyObject = MyObject(variable);
I prefer to use the second method because it will throw an Error when type cast fails, whereas the first method will just return null. But are there any other differences? Perhaps any advantages to using the first method?
The second type of casting has different behaviour for top level(http://livedocs.adobe.com/flex/2/langref/) types, e.g. Array(obj) does not cast in the straightforward way you describe; it creates a new Array if possible from obj, even if obj is an Array.
I'm sure the times this would cause unexpected behaviour would be rare but I always use "as" for this reason. It means if I do
int(str)
I know it's a cast in the "attempt to convert" sense of the word not in the "I promise it is" sense.
ref: got some confirmation on this from http://raghuonflex.wordpress.com/2007/07/27/casting-vs-the-as-operator/
The as method returns null if cast fails.
The () method throws and error if the cast fails.
If the value of variable is not compatible with MyObject, myObject1 will contain null and you will be surprised by a null pointer error (1009 : cannot access a property or method of a null object reference.) somewhere later in the program when you try to access it. Where as if you are casting using the MyObject(variable) syntax, you will get a type coercion error (1034 : Type Coercion failed: cannot convert _ to _) at the same line itself - which is more helpful than getting a 1009 somewhere later and wondering what went wrong.
I think I read somewhere on this site that as is slighty faster than (), but I can't find the question again.
Beside that this question have been asked many times, you will find an more in-depth answer here.
I recently discovered the very useful [] tag when searching on StackOverflow, it allows to only search in questions tagged with the specified tag(s). So you could do a search like [actionscript-3] as vs cast. There are more search tips here: https://stackoverflow.com/search.
And no; the irony in that I can not find the question about performance and write about how to search is not lost on me ;)
I think as returns back the base class and not null when the casting fails and () throws an error.