Accepted answer

According do docs:

exec can also be passed an Expression function.

... which is alias for:

Session => Validation[T]

Also pay attention to this excerpt from the first link:

For those who wonder how the plumbing works and how you can return a Session instead of Validation[Session] in the above examples, that’s thanks to an implicit conversion.

Now, with that info you can see that in the first case you are passing to exec something of type Session => Session (for which there is no implicit conversion to Expression[Session] exists in scope) and you get compile error.

In the second case you're using placeholder/partial application for:

justDoIt("hello world")(_)

... which is equivalent of:

x => justDoIt("hello world")(x)

... which can benefit from implicit conversion of the return value (from Session to Validation[Session]) and, as a result whole expression gets inferred to be conforming Expression[Session] which is just what exec requires.

UPDATE: here is the relevant implicit that does the conversion.

UPDATE 2: to make your original example work you can simply change the return type of justDoIt like this (to benefit from implicit conversion):

def justDoIt(param: String): Session => Validation[Session] = s => s.set("some", param)

Related Query

More Query from same tag