Discussion:
Need Help Understanding & Correcting "missing parameter type for expanded function"
Randall R Schulz
2009-03-23 14:08:07 UTC
Permalink
Hi,

I'm trying to understand and resolve these errors:

/dar/rho/src/rho/alg/Traversals.scala
Error:Error:line (324)error: missing parameter type for expanded function
((x$12) => ExpressionCursor(expr, next.node.pos.ahead(), x$12, next.node.pol)) _, next.node.pol)))


The code is:

traversal ++ connected.map(TraversalAction(ahead, ExpressionCursor(expr, next.node.pos.ahead(), _, next.node.pol)))


A similar fragment:

traversal ++ next.at.asInstanceOf[FunctionTerm].args.map(ExpressionCursor(expr, next.pos.ahead(), _, next.pol))

Does not prodduce this error.


TraversalAction and ExpressionCursor are a case-class constructors.

I gather the problem has to do with the anonymous function parameter
being nested inside the second constructor the erroneous case, but
don't know how to resolve it.


Randall Schulz
Luc Duponcheel
2009-03-23 14:27:28 UTC
Permalink
I hope that the following explanation helps:

placeholder syntax like: someFunction(someArg, _, otherArg)
is equivalent with: (arg) => someFunction(someArg, arg, otherArg)
if the type inferencer does not have enough context information
to infer the type, say A, of arg, then you have to help it as follows:
(arg: A) => someFunction(someArg, arg, otherArg)

-- sometimes you have to give the inferencer a helping hand

Luc
Post by Randall R Schulz
Hi,
/dar/rho/src/rho/alg/Traversals.scala
Error:Error:line (324)error: missing parameter type for expanded function
((x$12) => ExpressionCursor(expr, next.node.pos.ahead(), x$12,
next.node.pol)) _, next.node.pol)))
traversal ++ connected.map(TraversalAction(ahead, ExpressionCursor(expr,
next.node.pos.ahead(), _, next.node.pol)))
traversal ++
next.at.asInstanceOf[FunctionTerm].args.map(ExpressionCursor(expr,
next.pos.ahead(), _, next.pol))
Does not prodduce this error.
TraversalAction and ExpressionCursor are a case-class constructors.
I gather the problem has to do with the anonymous function parameter
being nested inside the second constructor the erroneous case, but
don't know how to resolve it.
Randall Schulz
--
__~O
-\ <,
(*)/ (*)

reality goes far beyond imagination
Randall R Schulz
2009-03-23 14:27:41 UTC
Permalink
Post by Randall R Schulz
Hi,
/dar/rho/src/rho/alg/Traversals.scala
Error:Error:line (324)error: missing parameter type for expanded function
((x$12) => ExpressionCursor(expr, next.node.pos.ahead(), x$12, next.node.pol)) _, next.node.pol)))
traversal ++ connected.map(TraversalAction(ahead, ExpressionCursor(expr, next.node.pos.ahead(), _, next.node.pol)))
...
TraversalAction and ExpressionCursor are a case-class constructors.
I gather the problem has to do with the anonymous function parameter
being nested inside the second constructor the erroneous case, but
don't know how to resolve it.
On a hunch, I changed the code thusly:

traversal ++ connected.map(arg => TraversalAction(ahead, ExpressionCursor(expr, next.node.pos.ahead(), arg, next.node.pol)))


And it compiled. What did I do?


Randall Schulz
Randall R Schulz
2009-03-23 14:32:45 UTC
Permalink
Post by Randall R Schulz
...
traversal ++ connected.map(arg => TraversalAction(ahead,
ExpressionCursor(expr, next.node.pos.ahead(), arg, next.node.pol)))
And it compiled. What did I do?
What Luc said. Got it.


RRS
Naftoli Gugenheim
2009-03-23 19:00:23 UTC
Permalink
But he said that _ is *already* equivalent to arg => ..., and to help the
inferencer, first use the explicit equivalent, then you can add an explicit
type annotation. So why did step 1 without step 3 help? It's not
contributing any unkowns.
Post by Randall R Schulz
Post by Randall R Schulz
...
traversal ++ connected.map(arg => TraversalAction(ahead,
ExpressionCursor(expr, next.node.pos.ahead(), arg, next.node.pol)))
And it compiled. What did I do?
What Luc said. Got it.
RRS
Arthur Peters
2009-03-23 19:17:01 UTC
Permalink
I think the issue is that:

traversal ++ connected.map(TraversalAction(ahead, ExpressionCursor(expr,
next.node.pos.ahead(), _, next.node.pol)))

Expands to:

traversal ++ connected.map(TraversalAction(ahead, (arg =>
ExpressionCursor(expr, next.node.pos.ahead(), arg, next.node.pol)) ))

Instead of what you seem to have expected:
traversal ++ connected.map(arg => TraversalAction(ahead,
ExpressionCursor(expr, next.node.pos.ahead(), arg, next.node.pol)))

The point is that when you use _ placeholder the anonymous function is
created using the closest surrounding function call, so you cannot use _ to
create a anonymous function that composes multiple functions like you were
(ExpressionCursor and TraversalAction). Your other example works because
there is no composition being attempted (there is only one function).

Hope that helps.

-Arthur
Post by Naftoli Gugenheim
But he said that _ is *already* equivalent to arg => ..., and to help the
inferencer, first use the explicit equivalent, then you can add an explicit
type annotation. So why did step 1 without step 3 help? It's not
contributing any unkowns.
Post by Randall R Schulz
Post by Randall R Schulz
...
traversal ++ connected.map(arg => TraversalAction(ahead,
ExpressionCursor(expr, next.node.pos.ahead(), arg, next.node.pol)))
And it compiled. What did I do?
What Luc said. Got it.
RRS
Andreas Hofstadler
2009-03-24 19:54:48 UTC
Permalink
Can I find this in the language spec?
I cannot find this in the spec. Just get dizzy by all that types :)
I never found out, why the placeholder works sometimes and sometimes not.
Well... your explanation makes some things clear for me.
Post by Randall R Schulz
traversal ++ connected.map(TraversalAction(ahead,
ExpressionCursor(expr, next.node.pos.ahead(), _, next.node.pol)))
traversal ++ connected.map(TraversalAction(ahead, (arg =>
ExpressionCursor(expr, next.node.pos.ahead(), arg, next.node.pol)) ))
traversal ++ connected.map(arg => TraversalAction(ahead,
ExpressionCursor(expr, next.node.pos.ahead(), arg, next.node.pol)))
The point is that when you use _ placeholder the anonymous function is
created using the closest surrounding function call, so you cannot use
_ to create a anonymous function that composes multiple functions like
you were (ExpressionCursor and TraversalAction). Your other example
works because there is no composition being attempted (there is only
one function).
Hope that helps.
-Arthur
On Mon, Mar 23, 2009 at 3:00 PM, Naftoli Gugenheim
But he said that _ is /already/ equivalent to arg => ..., and to
help the inferencer, first use the explicit equivalent, then you
can add an explicit type annotation. So why did step 1 without
step 3 help? It's not contributing any unkowns.
On Mon, Mar 23, 2009 at 10:32 AM, Randall R Schulz
Post by Randall R Schulz
...
traversal ++ connected.map(arg => TraversalAction(ahead,
ExpressionCursor(expr, next.node.pos.ahead(), arg,
next.node.pol)))
Post by Randall R Schulz
And it compiled. What did I do?
What Luc said. Got it.
RRS
Arthur Peters
2009-03-24 20:14:16 UTC
Permalink
It is in the spec. Section 6.23 on page 88.

Also to give a simplified example that may make more sense:

f(i, _)
Expands to:
arg => f(i,arg)

g(j, f(i,_))
Expands to:
g(j, arg => f(i,arg))

Note that the "f(i,_)" becomes an anonymous function that is passed to g,
and g is called normally (no expansion). If you want the whole expression
"g(j, f(i,_))" to return an anonymous function you have to do it by hand:
"arg => g(j, f(i, arg))"

-Arthur


On Tue, Mar 24, 2009 at 3:54 PM, Andreas Hofstadler
Post by Andreas Hofstadler
Can I find this in the language spec?
I cannot find this in the spec. Just get dizzy by all that types :)
I never found out, why the placeholder works sometimes and sometimes not.
Well... your explanation makes some things clear for me.
Post by Randall R Schulz
traversal ++ connected.map(TraversalAction(ahead, ExpressionCursor(expr,
next.node.pos.ahead(), _, next.node.pol)))
traversal ++ connected.map(TraversalAction(ahead, (arg =>
ExpressionCursor(expr, next.node.pos.ahead(), arg, next.node.pol)) ))
traversal ++ connected.map(arg => TraversalAction(ahead,
ExpressionCursor(expr, next.node.pos.ahead(), arg, next.node.pol)))
The point is that when you use _ placeholder the anonymous function is
created using the closest surrounding function call, so you cannot use _ to
create a anonymous function that composes multiple functions like you were
(ExpressionCursor and TraversalAction). Your other example works because
there is no composition being attempted (there is only one function).
Hope that helps.
-Arthur
But he said that _ is /already/ equivalent to arg => ..., and to
help the inferencer, first use the explicit equivalent, then you
can add an explicit type annotation. So why did step 1 without
step 3 help? It's not contributing any unkowns.
On Mon, Mar 23, 2009 at 10:32 AM, Randall R Schulz
Post by Randall R Schulz
...
traversal ++ connected.map(arg => TraversalAction(ahead,
ExpressionCursor(expr, next.node.pos.ahead(), arg,
next.node.pol)))
Post by Randall R Schulz
And it compiled. What did I do?
What Luc said. Got it.
RRS
Loading...