Lets say I have an exception defined as below:
exception MyException of string
I raise it in a function (this function returns string) as follows:
fun foo ... = raise DomenaInterpretacije ("Error ...")
| foo ... ...
Then I call that functon in a way, that produces the exception:
fun testExc () =
(foo ...)
handle MyException msg => msg
But these yields:
Error: non-constructor applied to argument in pattern: MyException
Error: unbound variable or constructor: msg
What am I doing wrong here?
Apparently, what you are doing wrong has little to do with the code you have pasted.
A working example of your code is provided below:
exception MyException of string
fun foo () = raise MyException "I wonder what happened."
fun testFoo () =
foo ()
handle MyException msg => msg
The exception was actually defined inside a module, so I had to call it like MyModule.MyException msg.
Related
I have an object with two functions, foo and bar. bar calls foo.
Normally, this works fine when bar uses this.foo(). However, when destructuring the object, this doesn't refer to the object anymore. In the code snippet below, it is undefined. When I run this in chrome, it refers to the window object.
Expected output
func1()
foo
objectValue
foo
bar
func2()
foo
objectValue
foo
bar
Actual output
func1()
foo
objectValue
foo
bar
func2()
foo
globalValue (or Uncaught TypeError, in the case of the code snippet, which breaks here)
Uncaught TypeError: this.foo is not a function (in the case of chrome, which breaks here)
*note : to reproduce in chrome, change let val = 'globalValue' to val = 'globalValue'
let val = 'globalValue'
let functions = {
val : 'objectValue',
foo : function(){
console.log('foo')
},
bar : function(){
console.log('this.val: ' + this.val)
this.foo()
console.log('bar')
}
}
class Class {
func1(functions){
console.log('func1()')
functions.foo()
functions.bar()
}
func2({foo, bar}){
console.log('func2()')
foo()
bar()
}
}
let instance = new Class()
instance.func1(functions)
console.log('\n')
instance.func2(functions)
Destructuring is the same as assigning a property to a local variable. I.e. in your case it would be the same as
var foo = functions.foo;
var bar = functions.bar;
Functions are not bound to their "parent" object. What this refers to depends on how a function is called. foo() and functions.foo() are two different ways of calling a function, hence this has a different value in each case.
This nothing new to ES6 or destructuring, JavaScript has always worked like that.
See How does the "this" keyword work? .
Given the following constructs for defining a function in Scala, can you explain what the difference is, and what the implications will be?
def foo = {}
vs.
def foo() = {}
Update
Thanks for the quick responses. These are great. The only question that remains for me is:
If I omit the parenthesis, is there still a way to pass the function around? This is what I get in the repl:
scala> def foo = {}
foo: Unit
scala> def baz() = {}
baz: ()Unit
scala> def test(arg: () => Unit) = { arg }
test: (arg: () => Unit)() => Unit
scala> test(foo)
<console>:10: error: type mismatch;
found : Unit
required: () => Unit
test(foo)
^
scala> test(baz)
res1: () => Unit = <function0>
Update 2012-09-14
Here are some similar questions I noticed:
Difference between function with parentheses and without
Scala methods with no arguments
If you include the parentheses in the definition you can optionally omit them when you call the method. If you omit them in the definition you can't use them when you call the method.
scala> def foo() {}
foo: ()Unit
scala> def bar {}
bar: Unit
scala> foo
scala> bar()
<console>:12: error: Unit does not take parameters
bar()
^
Additionally, you can do something similar with your higher order functions:
scala> def baz(f: () => Unit) {}
baz: (f: () => Unit)Unit
scala> def bat(f: => Unit) {}
bat: (f: => Unit)Unit
scala> baz(foo)
scala> baz(bar)
<console>:13: error: type mismatch;
found : Unit
required: () => Unit
baz(bar)
^
scala> bat(foo)
scala> bat(bar) // both ok
Here baz will only take foo() and not bar. What use this is, I don't know. But it does show that the types are distinct.
Let me copy my answer I posted on a duplicated question:
A Scala 2.x method of 0-arity can be defined with or without parentheses (). This is used to signal the user that the method has some kind of side-effect (like printing out to std out or destroying data), as opposed to the one without, which can later be implemented as val.
See Programming in Scala:
Such parameterless methods are quite common in Scala. By contrast, methods defined with empty parentheses, such as def height(): Int, are called empty-paren methods. The recommended convention is to use a parameterless method whenever there are no parameters and the method accesses mutable state only by reading fields of the containing object (in particular, it does not change mutable state).
This convention supports the uniform access principle [...]
To summarize, it is encouraged style in Scala to define methods that take no parameters and have no side effects as parameterless methods, i.e., leaving off the empty parentheses. On the other hand, you should never define a method that has side-effects without parentheses, because then invocations of that method would look like a field selection.
Terminology
There are some confusing terminology around 0-arity methods, so I'll create a table here:
Programming in Scala
scala/scala jargon
def foo: Int
parameterless methods
nullary method
def foo(): Int
empty-paren methods
nilary method
I sounds cool to say "nullary method", but often people say it wrong and the readers will also be confused, so I suggest sticking with parameterless vs empty-paren methods, unless you're on a pull request where people are already using the jargons.
() is no longer optional in Scala 2.13 or 3.0
In The great () insert, Martin Odersky made change to Scala 3 to require () to call a method defined with (). This is documented in Scala 3 Migration Guide as:
Auto-application is the syntax of calling a nullary method without passing an empty argument list.
Note: Migration document gets the term wrong. It should read as:
Auto-application is the syntax of calling a empty-paren (or "nilary") method without passing an empty argument list.
Scala 2.13, followed Scala 3.x and deprecated the auto application of empty-paren methods in Eta-expand 0-arity method if expected type is Function0. A notable exception to this rule is Java-defined methods. We can continue to call Java methods such as toString without ().
To answer your second question, just add an _:
scala> def foo = println("foo!")
foo: Unit
scala> def test(arg: () => Unit) = { arg }
test: (arg: () => Unit)() => Unit
scala> test(foo _)
res10: () => Unit = <function0>
scala> test(foo _)()
foo!
scala>
I would recommend always start definition with a function like:
def bar {}
and only in cases, when you are forced, to change it to:
def bar() {}
Reason: Let's consider these 2 functions from a point of possible usage. How they can be infoked AND where they can be passed.
I would not call this a function at all:
def bar {}
It can be invoked as:
bar
but not as a function:
bar()
We can use this bar when we define a higher-order function with a call-by-name parameter:
def bat(f: => Unit) {
f //you must not use (), it will fail f()
}
We should remember, that => Unit - is not even a function. You absolutely cannot work with a thunk as if it's a function insofar as you cannot choose to treat it as Function value to be stored or passed around. You can only trigger evaluations of the actual argument expression (any number of them).
Scala: passing function as block of code between curly braces
A function, defined with () has a bigger scope for usage. It can be used exactly, in the same context, as bar:
def foo() = {}
//invokation:
foo
//or as a function:
foo()
It can be passed into a function with a call-by-name parameter:
bat(foo)
Additionally, if we define a higher-order function, that accepts not a call-by-name pamameter, but a real function:
def baz(f: () => Unit) {}
We can also pass foo to the baz:
baz(foo)
As we can see standard functions like foo have a bigger scope for usage. But using a functions defined without () plus defining higher-order functions, that accept call-by-name parameter, let us use more clear syntax.
If you do not try to archive a better, more readable code, or if you need ability to pass your piece of code both to function defined with a call-by-name parameter and to a function defined with a real function, then define your function as standard one:
def foo() {}
If you prefer to write more clear and readable code, AND your function has no side-effects, define a function as:
def bar {}
PLUS try to define your higher-order function to accept a call-by-name parameter, but not a function.
Only when you are forced, only in this case use the previous option.
I'm writing unit tests in F# using MSTest, and I'd like to write tests that assert that an exception is raised. The two methods that I can find for doing this are either (1) write the tests in C# or (2) don't use MSTest, or add another test package, like xunit, on top of it. Neither of these is an option for me. The only thing I can find on this is in the MSDN docs, but that omits F# examples.
Using F# and MSTest, how do I assert that a particular call raises a particular exception?
MSTest has an ExpectedExceptionAttribute that can be used, but it is a less than ideal way to test an exception has been thrown because it doesn't let you assert the specific call that should throw. If any method in the test method throws the expected exception type, then the test passes. This can be bad with commonly used exception types like InvalidOperationException. I use MSTest a lot and we have a Throws helper method for this in our own AssertHelper class (in C#). F# will let you put it into an Assert module so that it appears with all the other Assert methods in intellisense, which is pretty cool:
namespace FSharpTestSpike
open System
open Microsoft.VisualStudio.TestTools.UnitTesting
module Assert =
let Throws<'a> f =
let mutable wasThrown = false
try
f()
with
| ex -> Assert.AreEqual(ex.GetType(), typedefof<'a>, (sprintf "Actual Exception: %A" ex)); wasThrown <- true
Assert.IsTrue(wasThrown, "No exception thrown")
[<TestClass>]
type MyTestClass() =
[<TestMethod>]
member this.``Expects an exception and thrown``() =
Assert.Throws<InvalidOperationException> (fun () -> InvalidOperationException() |> raise)
[<TestMethod>]
member this.``Expects an exception and not thrown``() =
Assert.Throws<InvalidOperationException> (fun () -> ())
[<TestMethod>]
member this.``Expects an InvalidOperationException and a different one is thrown``() =
Assert.Throws<InvalidOperationException> (fun () -> Exception("BOOM!") |> raise)
Like this?
namespace Tests
open Microsoft.VisualStudio.TestTools.UnitTesting
open System
[<TestClass>]
type SomeTests () =
[<TestMethod; ExpectedException (typeof<InvalidOperationException>)>]
member this.``Test that expects InvalidOperationException`` () =
InvalidOperationException () |> raise |> ignore
I'm using util.control.Exception.catching to convert internal exceptions into an exception type specific to my library:
import util.control.Exception._
abstract class MyException extends Exception
case class ErrorOccurredDuringFoo(e : Exception) extends MyException
def foo : Foo = {
catching(classOf[Exception]) either { fooInternals } match {
case Left(e) => throw ErrorOccurredDuringFoo(e)
case Right(v) => v
}
}
Unfortunately, this doesn't work. Applying the Catch returned by either doesn't return Either[Exception,Foo], it returns Either[Throwable,Foo]. But I've already told catching I want it to catch only subtypes of Exception, not all Throwables, and internally it's already matched an Exception.
Am I using this correctly? Is there no way I can convince catching to return the exception it catches as an instance of the class of exceptions I asked it to catch? Is my best bet to just add a redundant asInstanceOf[Exception]? I'd rather not if I can avoid it, as the catching instance could logically be created elsewhere, and I'd like to get a compile error if I one day change it to catching[Throwable] without changing ErrorOccurredDuringFoo, not a runtime error when the cast to Exception fails.
Catch isn't parameterised on Throwable, only on the result type. The only way to downcast the Throwable type is with the mkCatcher method:
val c = catching[Foo](
mkCatcher(
(t: Throwable) => t.getClass == classOf[MyException],
(e: MyException) => throw new ErrorOccurredDuringFoo(e)))
c(fooInternals)
But, Catch takes a Catcher[T] – which is really just an alias for a PartialFunction[Throwable, T].
As a case statement is a PartialFunction we can use pattern matching:
val c: Catcher[Foo] = {
case e: MyException => throw new ErrorOccurredDuringFoo(e)
}
catching(c)(fooInternals)
You could write it like this:
def foo : Foo = {
catching(classOf[Exception]) either { fooInternals } match {
case Left(e: Exception) => throw ErrorOccurredDuringFoo(e)
case Right(v) => v
}
}
It is interesting that it doesn't complain about missing cases.
Apologies for the confusing title, didn't know how to express it better. This is a follow-up from Overloading in Scala when type parameters are being used
Here's the faulty code:
def parser[T](identifier: String, default: T, modifier: String => T): T = {
val l = args.filter(_.toLowerCase.startsWith(identifier.toLowerCase))
println("l:")
println(l.isEmpty)
if(l.isEmpty) default
else modifier(l(0).drop(identifier.length).trim)
}
val installation: String = parser("-installation", {throw new Error("Installation not specified")}, identity)
This code is in the main function, so args is the usual list of arguments. If I do pass in a -installation asdf argument what happens is that the error gets thrown before the program can even step into the parser method (This happens becase no "l: false" is printed in the console, so that code is never reached.) I believe the exception is thrown when the
{throw new Error("Installation not specified")}
block is evaluated. I guess Scala evaluates that block in order to know what value to pass to the method. Is there a way of deferring evaluation until it actually hits that bit of the code inside parser?
I've tried using a lazy value, something like:
lazy val error = {throw new Error("Installation not specified")}
val installation: String = parser("-installation", error , identity)
but this doesn't work either.
You need to pass default by-name, with => T, if you want it to be evaluated only if need be
def parser[T](identifier: String, default : => T; modified: String => T): T = ...
Otherwise, the arg of a function are evaluated when the function is called (call by value). Your lazy val simply causes error to be evaluated when you call parser passing it as argument.
On the other hand, you can use lazy val inside a method, when you do not want a call by name argument to be evaluated each time it is referenced.
def f(x: => T) {
lazy val y = x
// use y
}
In your case, it is not needed, as default is called at most once in parse.