Roman Levenstein | 31 May 2012 06:56
Picon

Re: Idea: Dynamic implicits and dyanmic scopes

Hi Richard,

On Thursday, May 31, 2012 12:24:01 AM UTC+2, Richard Emberson wrote:


I've been doing something like this for about a year.
In my case, a base object has 7 mixins, Each
mixin has from 3 to 8 variants making a total
of 108864 possible mixins combinations for a base object.
Not only does it make no sense to actually generate
code for each possible combination, having 108864 such
classes, I imagine is a significant overhead - with or
without macro support.

Very good point! I forgot to mention potential explosion of code size in many cases, where static approach covering all potential cases would be used.
 
So, after the most general base object is created, which
variants of each mixin is determine to best optimize
performance/memory/etc. and, using the BIC (Build-In-Compiler),
I generate that particular version and copy the general
object's data into the particularized version.
(Actually, I create a builder for that version which is
stored in a cache so it can be reused if that combination
of mixin variants is required again - which is very
often the case.
Also, Note that a base object lives as long as the application
is running and the application is an enterprise level app
and expected to run for weeks, months or more.)

Richard

Can you make the code or at least the relevant snippets available to others to see how you do it?

-Roman
 
On 05/30/2012 10:15 AM, Luke Vilnis wrote:
> My immediate thought of a use-case for this is dependency injection - DI
> containers are often used to simulate a dynamic environment, and the
> fundamental problem with using implicits for DI is that implicits are
> static. An example is having 2 different containers passed into a
> constructor at the same static call site, chosen depending on some
> runtime state.
>
> On Wed, May 30, 2012 at 1:03 PM, Daniel Sobral <dcsobral <at> gmail.com
> <mailto:dcsobral <at> gmail.com>> wrote:
>
>      > I hope I managed to provide some motivation for the proposed feature.
>
>     Actually, that's the thing I failed to see in the whole text: a use
>     case. You talked about selecting an authentication method, which has
>     absolutely no need for the mechanism you mentioned, since the static
>     implicits are enough:
>
>     def auth(user: String)(implicit authenticator: Authenticator):
>     Boolean = ???
>
>     abstract class Authenticator { def authenticate(user: String): Boolean }
>     object Authenticator {
>       implicit def getAuthenticator: Authenticator = /* check available
>     mechanisms and return one */ ???
>     }
>
>     In fact, I fail to see how dynamic implicits could help you here: if
>     more than one authentication is found, it would simply fail. You'd
>     need some code to check which of the declared ones is actually
>     available, then chose or compose them. None of that is part of
>     implicit resolution.
>
>     Now, I'm not just dismissing the whole notion, but I think it's a
>     solution looking for a problem. I'd rather see more and better
>     examples.
>
>     On Wed, May 30, 2012 at 10:47 AM, Roman Levenstein wrote:
>      > Hi,
>      >
>      > I'm wondering if the following idea makes any sense for you. The
>     idea is
>      > still at its early stage and not very detailed yet, but hopefully it
>      > provides enough information to understand what I have in mind.
>      >
>      > To my understanding, Scala's implicit arguments are currently
>     resolved at
>      > compile-time using the static scope surrounding the place of
>     invocation.
>      > This is very convenient in many cases. But it still requires you to
>      > explicitly define those implicits (Sounds really funny :-)
>      >
>      > Now, what if you don't know in advance which implicits may be
>     required by a
>      > method that is to be invoked? E.g. you only get at run-time the
>     information
>      > which classes/methods are to be used and invoked. Or even if the
>     decision is
>      > taken statically but has a lot of alternatives, you may be don't
>     know for
>      > sure which implicits will be required for real, when a concrete
>     invocation
>      > is done.
>      >
>      > Since you don't know which implicits may be required, you have two
>      > alternatives:
>      >  (1) You declare a lot implicits for all possible cases (if you
>     statically
>      > know all potential methods that may be invoked) and then Scala
>     compiler
>      > would pick the right ones.
>      >        This works only for static cases but may be very annoying
>     as you have
>      > to foresee all possible implicits.
>      >
>      >  (2) A new feature called "Dynamic implicits" could be introduced.
>      >       Dynamic implicits are resolved at run-time. The
>     implementation could
>      > use e.g. reflection mechanisms. When a method needs to be invoked
>     and this
>      > method has implicit parameters, then it would be possible to
>     provide it with
>      > dynamic scope, which should be used to resolve implicits. Each
>     such dynamic
>      > scope may be a set of triples (variable name, class/type information,
>      > value). So, when there is a reflection-based (similar to
>      > java.lang.reflection.Method) Method m and a dynamic scope s, then
>      > m.invoke(s, obj, args) API could be used to perform the
>     invocation. When
>      > this form is used, "invoke" will use the scope s to resolve
>     implicits,
>      > obtain their values and pass them as corresponding arguments.
>      >
>      > Another application of this idea could be somewhat different.
>     Imagine that
>      > you have a system where you have many different implementations
>     of the
>      > semantically same method, i.e. a lot of classes which implement a
>     method
>      > with the same name, but different sets of explicit and implicit
>     parameters.
>      > An example could be, let's say an "authenticate" method. At the
>     high-level
>      > the system needs to authenticate a user - how it is done is a
>     secondary
>      > question. There could be different implementations for different
>      > authentication systems. One such implementation may require username,
>      > password as parameters. Another one may require public keys.
>     Third one may
>      > required Kerberos credentials/tokens and so on. Now, it may
>     happen that you
>      > don't know in advance, which of those implementations has to be used,
>      > because it is based on the user of the system or mode of
>     operation which is
>      > decided only at run-time. More over, it may happen that some of
>     the users
>      > have only username/password credentials, whereas others have only
>     public
>      > keys and Kerberos. How do you implement such a thing? One idea
>     could be to
>      > use dynamic scope and dynamic implicits again. Using them, one
>     could do
>      > roughly the following:
>      >
>      >  - get a user name at run-time
>      >
>      >  - read from a DB or a config file authentication information
>     available for
>      > a given user. It could be username/password credentials, public keys,
>      > Kerberos info, etc. Corresponding typed objects are then created
>     from this
>      > information.
>      >
>      > - such authentication-related objects built using the user
>     information are
>      > put into a dynamic scope s
>      >
>      > - There is a new API ( let's call it resolveAndInvoke(scope:
>     DynamicScope,
>      > candidates: Set[Method]) ) that takes the dynamic scope s and a
>     set of
>      > methods/classes that are potential candidates to be used for
>     authentication
>      > (e.g. the set would consist of authenticateKerberos(implicit
>      > kerberos:KerberosAuthenticationInformation),
>     authUserNamePassword(username:
>      > String, password: String), publicKeyAuthentication(publicKey:
>      > PublicKeyAuthenticationInformation)). The API tries to match
>     candidates
>      > against the dynamic scope s to see if all required explicit and
>     implicit
>      > parameters can be provided by the scope s (and may be current static
>      > scope?). If this is the case, then this candidate is taken and
>     invoked. (In
>      > the future, one could also think about the case, where multiple
>     candidates
>      > match. In such a case, an additional policy or mechanism could be
>     introduced
>      > to pick one of them for invocation) This way, the selection of
>     the method to
>      > be invoked happened at run-time and was decided based on the dynamic
>      > information available through a dynamic scope.
>      >
>      > I hope I managed to provide some motivation for the proposed
>     feature. The
>      > overall wish was to make implicits more usable in dynamic
>     contexts and to
>      > introduce some sort of a very dynamic late binding for method
>     selection and
>      > invocation.
>      >
>      > Questions:
>      > - Are described use-cases and the proposed solution interesting
>     enough to be
>      > discussed? Or do you say that described scenarios are so seldom
>     that it is
>      > not worth it to introduce any new mechanisms to solve them? Or
>     may be they
>      > can be solved in a very elegant way using already existing
>     solutions and
>      > mechanisms?
>      >
>      > - Do you see further use-cases where the proposed features could be
>      > beneficial?
>      >
>      > - Would it be technically possible to implement something like
>     this for
>      > Scala or are there any principal show-stoppers (e.g. limitation
>     due to JVM
>      > internals, etc)?
>      >
>      > Any feedback is very appreciated!
>      >
>      > Thanks,
>      >    Roman
>
>
>
>     --
>     Daniel C. Sobral
>
>     I travel to the future all the time.
>
>

--
Quis custodiet ipsos custodes

Gmane