nim-lang / Nim

Nim is a statically typed compiled systems programming language. It combines successful concepts from mature languages like Python, Ada and Modula. Its design focuses on efficiency, expressiveness, and elegance (in that order of priority).
https://nim-lang.org
Other
16.57k stars 1.47k forks source link

Macro quote function forgets the names on named tuples #23239

Open ggb-sw opened 9 months ago

ggb-sw commented 9 months ago

Description

#!/usr/bin/env -S nim r
#
# File: test1.nim

import macros

type
  tt1 = tuple[f1: int, f2: string]

macro test1() : untyped =
  let ret : tt1 = (f1:10, f2:"abc")
  result = quote do:
    tt1(`ret`)

macro test2() : untyped =
  let ret : tt1 = (f1:10, f2:"abc")
  # quote seems to forget that ret is a named tuple
  result = quote do:
    `ret`

echo "test1 => ", $test1()
echo "test2 => ", $test2()

Nim Version

Nim Compiler Version 2.0.0 [Linux: amd64]
Compiled at 2023-08-01
Copyright (c) 2006-2023 by Andreas Rumpf

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

Current Output

Hint: used config file '/home/ggb/.choosenim/toolchains/nim-2.0.0/config/nim.cfg' [Conf]
Hint: used config file '/home/ggb/.choosenim/toolchains/nim-2.0.0/config/config.nims' [Conf]
........................................................................
CC: test1.nim
Hint:  [Link]
Hint: mm: orc; threads: on; opt: none (DEBUG BUILD, `-d:release` generates faster code)
29471 lines; 0.200s; 37.496MiB peakmem; proj: /home/ggb/Temp/nim/tests/test1.nim; out: /home/ggb/.cache/nim/test1_d/test1_52413FA68D44329642ECBE936C908E623E15A59F [SuccessX]
Hint: /home/ggb/.cache/nim/test1_d/test1_52413FA68D44329642ECBE936C908E623E15A59F [Exec]
test1 => (f1: 10, f2: "abc")
test2 => (10, "abc")

Expected Output

Hint: used config file '/home/ggb/.choosenim/toolchains/nim-2.0.0/config/nim.cfg' [Conf]
Hint: used config file '/home/ggb/.choosenim/toolchains/nim-2.0.0/config/config.nims' [Conf]
........................................................................
CC: test1.nim
Hint:  [Link]
Hint: mm: orc; threads: on; opt: none (DEBUG BUILD, `-d:release` generates faster code)
29471 lines; 0.200s; 37.496MiB peakmem; proj: /home/ggb/Temp/nim/tests/test1.nim; out: /home/ggb/.cache/nim/test1_d/test1_52413FA68D44329642ECBE936C908E623E15A59F [SuccessX]
Hint: /home/ggb/.cache/nim/test1_d/test1_52413FA68D44329642ECBE936C908E623E15A59F [Exec]
test1 => (f1: 10, f2: "abc")
test2 => (f1: 10, f2: "abc")

Possible Solution

No response

Additional Information

No response

metagn commented 9 months ago

Using newLit on ret before passing it to quote works

ggb-sw commented 9 months ago

@metagn my issue was not about how to mitigate the issue (I have other mitigations I have used) but whether it is designed behaviour that the macro should convert a named tuple to an unnamed tuple, and if so under what other circumstances would one expect a macro to change the type of value it is using?

metagn commented 9 months ago

In the first place I don't think you are supposed to embed values that aren't NimNode in quote blocks. The macro isn't removing the names from the named tuple, the NimNode serialization in the VM for values like ret does, which is what quote happens to use here, which gets exposed when it treats ret like an untyped NimNode

ggb-sw commented 9 months ago

@metagn I take your point that it probably is not the quote itself, because if it were the quote then macro test1 would also have the same outcome.

The question then is why is the VM stripping the names from the named tuple without giving me any warning that I am doing anything wrong?

metagn commented 9 months ago

It probably should warn when quoting non-NimNode symbols.