Proposal To Revise Implicit Parameters

#144

I like the recent changes concerned with contextual abstractions. I think what you are saying is right, on the other hand though, when the ease of understanding of the concept of implicits is considered together with also having to understand the patterns it is used in, the proposed changes work better. The “expressing intent vs expressing mechanism” argument works for me.

It might turn off slightly more people in the earliest stages of learning than implicits. But to me it seems like a large subset of those would end up not liking scala with implicits either, and I’m yet to see a single person from that group to change their mind. Often the issue is that scala is just not in the part of the typesystem/PL landscape that they are prepared to leave anyway.

The proposed changes might serve better than implicits those newcomers who were more likely to stay with the language just a little bit longer in the first place, and it is this latter group that has the potential to impact adoption.

1 Like
#145

If given is an infix operator then why can’t we turn it into a dotted notation? We as Scala programmers know that generally object operator argument can be rewritten as object.operator(argument). If that applies to given as well then normalization could look like this:

f("abc")
f.given(global)("abc")
f("abc").given(ctx)
f.given(global)("abc").given(ctx)

Which looks much saner to me and has the very desirable (IMO) property that there’s less distance between opening and closing parentheses, e.g. f.given(global)("abc") as opposed to (f given global)("abc").

7 Likes
#146

My first reaction: I like .given. That reads even better than as an infix operator.

9 Likes
#147

Sorry, only just saw this. Apart from the “it works better” reasons for liking the implied given for syntax (modulo I’d wish to change implied to instance or deriving in the declarations) is that it feels like a much cleaner and distinct model for describing derivable values, and how to construct them from one-another. The implied def/object/val constructs in scala 2.* always felt to me as if derived values were being simulated using a source-level DSL within scala. That we were writing the plumbing of an implementation of this machinery. Using implied given for, there is a single, first-class syntax for this, which only does this, and does all of this. It is far, far clearer to see at a glance what code is introducing and manipulating supplied values, and what code is introducing and manipulation derived values. I find it a much lower cognitive overhead writing even quite complex stacks of derived instances using the new syntax, that I’ve never been able to do in practice with the old syntax.

2 Likes
#148

That would be lovely!

(I think it would be great if match could be also; but I’ll take every dottable operator-or-method-like thing I can get. I always appreciate the regularity-of-flexibility in invocation.)

1 Like
#149

Too bad I missed most of the discussion (since it happened on Passover).

I think one thing that hasn’t really been expressed is that there’s a huge risk involved. We don’t know what effect it will have on people open to begin using Scala or to stop using Scala. Maybe it will make more people learn Scala. Maybe it won’t. Maybe it will cause people that were on the fence to stop using Scala. Maybe it won’t. We don’t know.

Personally, my reaction to the new syntax is that perhaps it could be justified, but it’s not Scala. It feels like after a decade of using Scala, to continue using it I have to learn a new language now. :frowning:

Because of the above I feel very strongly that we should take this slowly. There is already a huge amount of changes in Scala 3.0. There is no reason that this has to be in the same release. It can wait. (Personally, I would make the release that includes this Scala 4.0, even if it were released only a week after 3.0.)

Meanwhile, all of the proposed improvements to implicits that don’t break code or involve paradigm shifts, should go into 3.0. Or 2.14. Those have the least risk for the greatest gain. Then we can decide whether it’s worth the bolder move.

1 Like
#150

IMO given doesn’t make Scala much more different. Overall it seems that what given changes is giving implicit arguments less priority than regular arguments. It won’t substantially change the shape of Scala programs if method notation for given arguments (i.e. f.given(a)(b).given(c)) will be used.

OTOH removing assignment operator from typeclasses instances definition could require tedious restructuring. instance abc of Type given xyz { ...class members... } is greatly limited compared to implicit abc: Type given xyz = anything.
Update: I missed aliases in implied instances proposal. Well, it changes the situation then.

#151

I love the simplicity and targeted nature of your proposal.

What do you think of just enforcing that passing implicit arguments must be by-name instead of positional? Instead of:

Just doing:

maximum(xs)(ord = descending)

Do you think that would solve the same problem and be even less radical of a change?

#152

The problem with your proposal is that it could also be a normal argument list, and you cannot see it from here.

It also goes against two of the principles as discussed in the other thread (leaving out of scope whether or not you agree with them):

  • It doesn’t mirror call and use sites.
  • It doesn’t distance implicit parameters from normal parameters anymore than is done now, which is one of the reasons the change it.
1 Like
#153

I like idea with given as function call f.given(a)(b).given(c) but it moves back to first implementation that was proposed few years ago f.implicitly(a)(b).implicitly(c). Why original proposition was abandoned?

This volatile also first rule:

Maybe we should also accept same syntax on definition site then?

def f(x: Double).given(ctx: Context):Double = { ... } 
1 Like
#154

If I want to respond directly to a point made, how can I do that? Can I split off a separate thread by replying to a post here?

#155

+1 to infer and inferred over implied

#156

I don’t remember implicitly keyword being suggested, but anyway implicitly is already present in Scala’s stdlib as a function and it’s frequently used. You would first need to deprecate that method in Scala Next and only in Scala Next+1 you would have a chance to reintroduce implicitly as a keyword. To avoid that lengthy process you need to choose another keyword.

#157

It’s not a keyword, it would be a method, much like apply

#158

I don’t want to hijack this thread (and started a new one on Scala governance to take any further discussion there), but I feel this statement needs a reply:

I think you’re over-interpreting this. I mean, Martin does not
have the final say here, the SIP committee does. Yes, he’s extremely influential in the process, but we’ve long since moved on from “everything Martin says is final”.

I don’t think that is entirely correct. The SIP submission process details:

For a SIP to be accepted, the following three requirements must be met:

  • At least 50% of the committee members vote in favor.
  • There are at least two-thirds “in favor” versus “against” votes.
  • Martin Odersky does not veto it.
#159

AFAIK, he can only veto against a proposal, but not in favor.

#160

I agree with @lihaoyi, even if we use the given syntax, we should instead choose another keyword that is more familiar to mainstream language developers.

The alternative keywords to given that I can imagine include:

  • autowire
  • inject
  • import
1 Like
#161
#162

I propose changing

delegate for

to

delegate as

eg

s/delegate (.*) for/delegate $1 as/

Old Post:
I propose changing

implied for

to

implied as

eg

s/implied (.*) for/implied $1 as/
#163

implied was recently changed to delegate see https://github.com/lampepfl/dotty/pull/6649
It’s already the syntax in dotty 0.16.0-RC3