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

type inference with lambdas doesn't work (requires explicit types) #7435

Open
timotheecour opened this issue Mar 28, 2018 · 5 comments
Open

Comments

@timotheecour
Copy link
Member

timotheecour commented Mar 28, 2018

in D this works:

auto testCallFun(alias fun)() { return fun(0); }
void main(){
  import std.stdio:writeln;
  writeln(testCallFun!(x=>x*2)());
}

in nim apparently this doesn't unless explicit types are provided:

import future
proc testCallFun[T](fun: T): auto = result = fun(0)
proc main() =
  # not ok: Error: invalid type: 'GenericParam' in this context: 'proc (fun: proc (x: GenericParam): untyped){.noSideEffect, gcsafe, locks: <unknown>.}' for proc
  echo testCallFun(x => x * 2)

  #ok with explicit type:
  echo testCallFun((x:int) => x * 2)

This pattern is heavily used and quite useful for generic code.

  • Is there any fundamental reason why this can't work in nim?

  • if not, is that on the roadmap?

potentially related

@Araq
Copy link
Member

Araq commented Mar 29, 2018

Not on the roadmap as I can't figure out how to infer this type myself. Use a template instead, maybe.

This pattern is heavily used and quite useful for generic code.

We managed so far to do without it. Btw "generic" is not a synonym for "bizarre".

@andreaferretti
Copy link
Collaborator

I have problems to figure out the type as well! :-D

For context, Nim's type inference does not perform unification - such as Hindley-Milner languages - but propagates type information forward only.

@Araq
Copy link
Member

Araq commented Mar 29, 2018

For context, Nim's type inference does not perform unification - such as Hindley-Milner languages - but propagates type information forward only.

Unification is forward only.

@andreaferretti
Copy link
Collaborator

Maybe we are talking about different things, but it is not forward only. To give an example, here is a definition of fizzbuzz without any type annotation in Haskell

fizz n | n `mod` 15 == 0  = "FizzBuzz"
       | n `mod` 3  == 0  = "Fizz"
       | n `mod` 5  == 0  = "Buzz"
       | otherwise = show n

If I enter this in GHCi and ask for its type I get

:type fizz
fizz :: (Integral a, Show a) => a -> [Char]   

Notice that it has propagated back the constraint that a is Integral from the fact that I use mod on a variable of type a and that it belongs to the typeclass Show because I call show in it. The type information has propagated from the usage of mod to the definition of fizz, hence backwards

@Araq
Copy link
Member

Araq commented Mar 29, 2018

Yes, Haskell and ML use a more complex scheme which propagates back. But the term "unification" is perfectly fine with forward only. Nim does perform unification.

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

No branches or pull requests

3 participants