alias declarations
wizzardx opened this issue · 15 comments
More or less what you have in C, with the 'define' preprocessor directive, but in a type-safe manner.
This may be possible in eg a macro or template that could be added to stdlib.
Basically what D describes over here:
https://dlang.org/spec/declaration.html#alias
Meaning that eg, code like this (from Platformer tut):
proc handleInput(game: Game) =
var event = defaultEvent
while pollEvent(event):
case event.kind
of QuitEvent:
game.inputs[Input.quit] = true
of KeyDown:
game.inputs[event.key.keysym.scancode.toInput] = true
of KeyUp:
game.inputs[event.key.keysym.scancode.toInput] = false
else:
discard
Can be expressed as something like this, for instance:
proc handleInput(game: Game) =
alias inputs = game.inputs[event.key.keysym.scancode.toInput]
var event = defaultEvent
while pollEvent(event):
case event.kind
of QuitEvent:
game.inputs[Input.quit] = true
of KeyDown:
inputs = true
of KeyUp:
inputs = false
else:
discard
It's possible currently to get a lot of these kinds of effects by making use of some combination of const or template, or inlined function, but it's a bit untidy or verbose.
Here's one basic example of it from the Nim forum:
https://forum.nim-lang.org/t/1515
It's also something that Ada lets you do with its "rename" syntax, eg:
http://www.adaic.org/resources/add_content/docs/95style/html/sec_5/5-7-2.html
https://en.wikibooks.org/wiki/Ada_Programming/Basic#"Hello,_world!"_with_renames
This is possible with a template already, no?
template inputs = game.inputs[event.key.keysym.scancode.toInput]
Ah, thanks!
I've struggled with this in the past, too.
So in the linked forum thread, this solution would also work?
template bar = foo
It probably will
Doesn't look like it...
This works, as per forum thread:
proc foo(x: int) = echo x
const bar = foo
bar 10
This doesn't:
proc foo(x: int) = echo x
template bar = foo
bar 10
It gets this error:
test.nim(3, 5) Error: type mismatch: got (int literal(10))
but expected one of:
template bar()
However, it looks like this does work, which is pretty nice:
proc foo(x: int) = echo x
template bar(x) = echo x
bar 10
However, this one sadly doesn't (it seems close to your original template example):
var a = 200
template b = a
b = 300
echo a
It gives this error:
test.nim(3, 1) Error: expression 'a' is of type 'int' and has to be discarded
This one does however:
var a = 200
let b = addr a
b[] = 300
echo a
However I think that syntax is a bit unsafe, ideally shouldn't be used.
I've edited that forum thread with this updated info.
You need to declare the return value. The error is saying that a
returns an int
, but it wasn't expecting any return value.
var a = 200
template b: untyped = a
b = 300
echo a
Ah, thanks, that helps a lot!
There's a section in the Nim manual which talks about untyped:
https://nim-lang.org/docs/manual.html#overloading-resolution-lazy-type-resolution-for-untyped
But it's not immediately obvious from that, that you can use template to swap in the left hand side of an assignment.
However, looks like I can't say eg, substitute a proc directly:
proc foo(x, y, z: int) =
echo x + y + z
template bar: untyped = foo
bar(1,2,3)
Or eg rename modules, eg like this:
import os
echo os.fileExists("/tmp/")
template my_os: untyped = os
echo my_os.fileExists("/tmp/a.txt")
I think I'm asking for something pretty close to a source code string substitution macro, eg something like this, where "aliasing" is the macro, and "alias" is a special identifier recognized by the macro, like this:
(kind of, operating a lot like how C's "define" preprocessor directive works):
aliasing:
# os is a module
alias(my_os, "os")
echo my_os.fileExists("/") # Same as: echo os.fileExists("/")
# bar is a function
alias(foo, "bar")
foo(1, 2, 3, 4, "abcd") # Same as: bar(1, 2, 3, 4, "abcd")
# a is a variable
alias(b, "a")
var a: int
b = 123 # Same as: a = 123
# x.a.b is a structure, where b is a seq.
alias(s, "x.a.b[idx]")
var idx = 999
s = 123 # Same as: x.a.b[idx] = 123
The proc example can be done too. Note that specifying a return type (which can also be untyped) is only necessary if it returns a value.
proc foo(x, y, z: int): int =
x + y + z
proc foo2(x, y, z: int) =
echo foo(x, y, z)
template bar(v: varargs[untyped]): untyped = foo(v)
template bar2(v: varargs[untyped]) = foo2(v)
echo bar(1,2,3)
bar2(1,2,3)
I don't think there is a solution for the module alias at the moment.
Ah, yes, and that even works in addition to other import names.
import os
import os as my_os
echo os.dirExists("/tmp")
echo my_os.dirExists("/tmp")
Workarounds have been sorted out. Closing.
the workarounds don't work in many cases; this issue is properly fixed here: #11822
@timotheecour I'm going to repeat my request again, please stop cross-referencing your PRs across every single related issue. You can see that GitHub shows that you've referenced this issue above. Writing a comment here is just noise in our notifications.
sure, will do. my reasoning was that issues may be referenced in a PR, but the PR is not intending to fix or close the issue referenced (eg workaround or just part of PR description). But fine.