liquidev / euwren

High-level Wren wrapper for Nim
MIT License
36 stars 0 forks source link

Inline procs #16

Closed liquidev closed 4 years ago

liquidev commented 4 years ago

Add the ability to create "inline" procs:

wren.foreign("example"):
  [Inline]:
    myProc do (a: int) -> float:
      result = float(a) * 1.5

This would get rewritten to something like this:

# not the actual result, just for illustration purposes
proc myProc(a: int): float =
  result = float(a) * 1.5
wren.foreign("example"):
  [Inline]:
    myProc

but myProc would stay in the scope of the foreign call, and not be visible outside.

The do syntax is used because it allows me to keep the * and ? as prefix operators:

*myProc do (): discard

Otherwise, they must've been used as postfix in the proc declaration:

proc myProc*() = discard

but as you can see, it's confusing. * is Nim's export marker, but in this instance, it would make the proc static. Also, it would make parsing it more difficult, since the proc declaration has to be parsed as a special case .

This can solve the issue of euwren not being able to resolve certain weird cases of overloads, but most notably, it allows one to bind things like variables without using intermediary procs declared outside of foreign(), cluttering up the namespace:

var a = 1
wren.foreign("example"):
  [Vars]:
    a do () -> int: a

A different syntax like a: int might be considered for binding consts and variables in the future.

It's important to note that do: and do (): are different syntax. The first creates a nnkStmtList, and the other creates an nnkDo. Statement lists will be used for multiple overloads in the future, so do: would not be supported in this feature.

liquidev commented 4 years ago

Fixed in 0.13.0.