Newbie: zero parameter functions, bind call-by-name function curiosity

10 views
Skip to first unread message

Strom

unread,
Oct 27, 2009, 2:52:59 AM10/27/09
to Lift
I'm not sure if this is a scala or a lift related question, but when I
try to bind a submit button, I'm having some confusion on using zero
parameter functions as the "() -> Any" parameter in the submit
signature.

The signature for the method in question is
SHtml.submit(value : String, func : () => Any, attrs : (String, String)
*)

1. My first question is about the following method definitions
def processForm () : Unit = {...}
vs
def processForm = {...} //no parentheses after method declaration

Why can I call "processForm" as well as "processForm()" for the first
example, but only "processForm" for the second example. If there is
scala/lift documentation on this simple question?

2. Why do I get a compiler error when I use the following code:
bind( ...
"submit" -> SHtml.submit( "Process Form", processForm() ) /*type
mismatch error*/
)
vs
bind( ...
"submit" -> SHtml.submit( "Process Form", processForm ) /*compiles
successfully*/
)

It's my impression that the above bind calls are equivalent given the
way the scala compiler behaves when I call "processForm" or
"processForm()".

Also, I wasn't even sure the method itself would allow the code to
compile. I thought I'd have to do "() -> processForm" or "() ->
processForm()".


The error I was getting was this:
error type mismatch
found : Unit
required : () -> Any

Can someone please clarify? Thanks so much.

Marius

unread,
Oct 27, 2009, 3:27:42 AM10/27/09
to Lift


On Oct 27, 8:52 am, Strom <strommo...@gmail.com> wrote:
> I'm not sure if this is a scala or a lift related question, but when I
> try to bind a submit button, I'm having some confusion on using zero
> parameter functions as the "() -> Any" parameter in the submit
> signature.
>
> The signature for the method in question is
> SHtml.submit(value : String, func : () => Any, attrs : (String, String)
> *)
>
> 1. My first question is about the following method definitions
> def processForm () : Unit = {...}
> vs
> def processForm = {...}  //no parentheses after method declaration
>
> Why can I call "processForm" as well as "processForm()" for the first
> example, but only "processForm" for the second example. If there is
> scala/lift documentation on this simple question?

Because compiler already knows that processForm is a zero argument
function and accepts processForm call. In the second example you just
can't call a call-by-name using () as it would contradict its very
definition.

>
> 2. Why do I get a compiler error when I use the following code:
> bind( ...
>   "submit" -> SHtml.submit( "Process Form", processForm() )  /*type
> mismatch error*/
> )
> vs
> bind( ...
>   "submit" -> SHtml.submit( "Process Form", processForm ) /*compiles
> successfully*/
> )

processForm() is a value not a function. It is the value returned by
processForm function while processForm is the function itself.

Ross Mellgren

unread,
Oct 27, 2009, 10:19:37 AM10/27/09
to lif...@googlegroups.com
Did you mean () => processForm by chance? () -> processForm is a pair
of () and processForm's result.

-Ross

Strom

unread,
Oct 27, 2009, 2:50:55 PM10/27/09
to Lift
Yes Ross, I did mean () => processForm. Thanks for the clarification.
The one thing in moving from Java to Scala is that there are a lot of
things that look similar that aren't, as you've pointed out. Newbie
error caught ;)

Thanks Marius, I made that assumption, but it still bugs me that the
scala interpreter evaluates both the "value" and the "function" when I
use:

scala> def testFunc() : Int = 3

scala> testFunc
Int = 3

scala>testFunc()
Int = 3


Strom

Marius

unread,
Oct 27, 2009, 3:54:43 PM10/27/09
to Lift


On Oct 27, 8:50 pm, Strom <strommo...@gmail.com> wrote:
> Yes Ross, I did mean () => processForm. Thanks for the clarification.
> The one thing in moving from Java to Scala is that there are a lot of
> things that look similar that aren't, as you've pointed out. Newbie
> error caught ;)
>
> Thanks Marius, I made that assumption, but it still bugs me that the
> scala interpreter evaluates both the "value" and the "function" when I
> use:
>
> scala> def testFunc() : Int = 3
>
> scala> testFunc
> Int = 3
>
> scala>testFunc()
> Int = 3

Right ... and this is correct. Because there is no context the
interpreter (and compiler) assume that you mean a function-
application. But try this:

scala> testFunc _
res5: () => Int = <function>

the _ here means eta expansion. A method is converted into a function.
SLS 6.25.5


But context matters:

scala> def testFunc(): Int = 3
testFunc: ()Int

scala> def other(f: () => Int) = f()
other: (() => Int)Int

scala> other(testFunc)
res0: Int = 3

scala> other(testFunc())
<console>:7: error: type mismatch;
found : Int
required: () => Int
other(testFunc())
^


In the above example textFunc and testFunc() means two different
things
Reply all
Reply to author
Forward
0 new messages