Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

erroneous FSC error after using let! binding in CE with overloads: FS0072: Lookup on object of indeterminate type #1310

Closed
smoothdeveloper opened this issue Jul 2, 2016 · 8 comments

Comments

@smoothdeveloper
Copy link
Contributor

smoothdeveloper commented Jul 2, 2016

Repro steps

  1. clone https://github.com/smoothdeveloper/fsharp.playground
  2. checkout commit 1aae8afd63cf0fa048a1074a95290484a26eb877
  3. run build.bat (restores all nugets)
  4. open smoothdev.Utils.sln
  5. build

Expected behavior

Compiles

Actual behavior

This compile error:

module SqlManagement =
  open Microsoft.Azure

  let authenticate settings = 
    job {
      let! adToken = ActiveDirectory.authenticate settings
      return TokenCloudCredentials (settings.SubscriptionId, adToken.AccessToken)
                                                             ^^^^^^^^^^^^^^^^^^^

error FS0072: Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved.

Known workarounds

change code to:

return TokenCloudCredentials (settings.SubscriptionId, (adToken: Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationResult).AccessToken)`

note that I can't specify type on the let! binding

Related information

  • Windows 7 x64
  • VS 2015 Update 1
  • .NET 4.5
@dsyme
Copy link
Contributor

dsyme commented Jul 3, 2016

@smoothdeveloper It feels like this is likely to be by design. At least, could you please synthesize it down to a repro that is fully standalone? i.e. just one code file including the definition of the "job" builder. If the builder uses overloaded Bind or Return methods then this behavior might be observed. (i.e. I'm not yet sure that your expectation that this compiles without an annotation is correct based on the language spec, or is effectively a language request of some kind)

@smoothdeveloper
Copy link
Contributor Author

@dsyme thanks.

I'll try to make a standalone code sample, just wanted to nail down the issue as the tooling gives a different picture than the compiler (type is infered by the tooling), which makes the error message strange.

If this is by design (I've faced another issue with computation expression: #869) what would we ideally do?

My concern is that someone who is not used to the language wouldn't know how to solve it because it is not possible to put the annotation on the binding itself; putting the annotation at usage spot is a technique which I consider non-obvious for people who haven't spent "long enough" writing F# code.

@dsyme
Copy link
Contributor

dsyme commented Jul 4, 2016

@smoothdeveloper Hmmm.. you don't mention IDE tooling above?

We'd need to see the minimal repro to work out what to do

thx

@smoothdeveloper
Copy link
Contributor Author

@dsyme would a repro using the actual packages in the code I have the issue with be OK or you need it to be minimized?

I can easily make a .zip file with all setup to repro this in a script, but authoring my own CE to attempt minimal repro without the libraries is a bit over my head at this point.

@polytypic I wonder if you'd have an idea what makes JobBuilder (from Hopac) special to produce ambiguous behaviour between compiler and IDE?

@polytypic
Copy link

Hopac's JobBuilder currently has overloads for various async mechanisms, including overloads for both Task<'x> and Task, which, unfortunately, seems to mainly cause problems. It has been on my mind to deprecate and remove the Task overloads for some time.

@smoothdeveloper
Copy link
Contributor Author

@polytypic thanks for feedback. Aside, the fact that JobBuilder knows how to take care of Task, Task<'a>, Async<'a> and Hopac own Job<'a> is a great thing, please don't remove that ability!

The inference issue can be worked around at call site, and maybe the compiler can support it better in future release (the tooling seems to support it already).

@dsyme
Copy link
Contributor

dsyme commented Jul 15, 2016

I can easily make a .zip file with all setup to repro this in a script, but authoring my own CE to attempt minimal repro without the libraries is a bit over my head at this point.

If you think it's a bug according to the current language spec, then I'd prefer a single chunk of F# code that reproduces that bug.

If it's a scenario where you think a type annotation shouldn't really be needed, but is because the CE builder is using overloads, then it's probably better to document in a gist and put an issue on http://fslang.uservoice.com (if it's not a bug according to the current language spec then that's what I'd ask you to do next in any case :) )

@smoothdeveloper
Copy link
Contributor Author

@dsyme I tried a quick look at spec, I'm not that good with that, here is what I found

In A.2.3.1 Computation and Range Expressions

comp-or-range-expr :
    comp-expr
    short-comp-expr
    range-expr

comp-expr :
    let! pat = expr in comp-expr
    let pat = expr in comp-expr

In A.2.4 Patterns

rule : pat pattern-guardopt -> expr
pattern-guard : when expr
pat :
    const
    long-ident pat-paramopt patopt
    _
    pat as ident
    pat '|' pat
    pat '&' pat
    pat :: pat
    pat : type // this one

I'd assume pat to accept pat : type even in the case of a let! binding, but I'm probably overlooking some details which might be spelled in the text.

In my case, I'd like to (if the compiler can't infer the same way tooling does infer) write:

let! adToken : AuthenticationResult = ActiveDirectory.authenticate settings

Either the tooling should also give the same perspective as the compiler (adToken shouldn't be inferred if no type annotation is given) or the type should be inferred in the compiler the same way tooling does.

We can close this if this is not a bug, if we want to keep it, I'll make a zip with solution to try it (using the external dependencies).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants