Nim icon indicating copy to clipboard operation
Nim copied to clipboard

Sugar anonymous procedure and procedure type fails on identity function

Open arkanoid87 opened this issue 4 years ago • 8 comments

Identity function fails to compile when using sugar function types. Seem related to how "auto" type works with sugar function types.

Example

import sugar, macros
let identity: int -> int = x => x

By rewriting the => macro, seems that the "auto" type of function argument is not smart enough

This fails to compile

import sugar, macros
let identity: int -> int = proc(x: auto): int = x

This compiles successfully

import sugar, macros
let identity: int -> int = proc(x: int): auto = x

Current Output

Error: A nested proc can have generic parameters only when it is used as an operand to another routine and the types of the generic paramers can be inferred from the expected signature.

Expected Output

compilation successfull

Version

$ nim -v
Nim Compiler Version 1.5.1 [Linux: amd64]
Compiled at 2021-06-01
Copyright (c) 2006-2021 by Andreas Rumpf

git hash: c0e8199acc9f49caa36bae34d103600d112b66f3
active boot switches: -d:release

arkanoid87 avatar Jul 07 '21 17:07 arkanoid87

related: https://github.com/nim-lang/Nim/issues/7435

note that alias PR (https://github.com/nim-lang/Nim/pull/11992) solves all of these problems using true lambdas, eg: x ~> x

timotheecour avatar Jul 07 '21 18:07 timotheecour

Related: "Araq said => and -> were bad ideas for sugar.nim"

Araq avatar Jul 08 '21 10:07 Araq

This goes into the rabbit hole way deeper than my understanding. I will skip shortcuts for my task, but yeah I see there's lot more than just sugar.

arkanoid87 avatar Jul 08 '21 11:07 arkanoid87

This works:

import sugar, macros
let identity = (x: int) -> int => x

Would be good if we could get a nicer error message to suggest doing this.

dom96 avatar Jul 08 '21 20:07 dom96

let identity = (x: int) -> int => x

not very sweet for a syntax sugar; and very limited compared to ~>:

import macros,sugar
proc id0(a: int): int = a          # generics allowed
let id1 = proc(a: int): int = a    # generics not allowed
let id2 = (x: int) -> int => x     # ditto
let id2 = (x: int) => x            # alternative form

# vs alias PR: #11992
alias id4 = (a: int) ~> a          # concrete type possible but not required
alias id5 = (a: auto) ~> a         # generics allowed
alias id6 = a ~> a                 # so are untyped templates
# eg usage: callMe(s, (a,b) ~> a < b, c ~> c * 2)

(and no function pointer indirection either)

timotheecour avatar Jul 08 '21 21:07 timotheecour

@timotheecour fixing the compiler's auto handling would also fix it. Why not do that? :)

dom96 avatar Jul 09 '21 22:07 dom96

@timotheecour fixing the compiler's auto handling would also fix it. Why not do that? :)

Passing a generic (implied by auto) to a proc (or more generally, a template, iterator, macro etc) requires first class symbols, which is exactly what #11992 does.

timotheecour avatar Jul 09 '21 22:07 timotheecour

So with #11992 this bug would be fixed too (i.e. => would now work with auto)?

dom96 avatar Jul 10 '21 13:07 dom96