Closed porky11 closed 6 years ago
Fixing this would be important for writing macros. (I wrote a macro this way, and don't know another way to implement it) I don't know, where this bug could be. Maybe in definition of qq (and bqq), but it would make more sence, if there were multiple representations of a sexpression, and only get-varargs-list, returns the correct representation. (It seems that list-nodes containing a non-list-node as first argument is the same as a non-list-node with a next-node)
On Fri, Sep 30, 2016 at 04:36:02PM -0700, Fabio Krapohl wrote:
Fixing this would be important for writing macros. (I wrote a macro this way, and don't know another way to implement it)
The problem is that 'uql' is not unquoting the unwrapped list node of the node, but the list node itself, as per your example. The only difference between 'uq' and 'uql' is that 'uq' does not include the next-nodes of the unquoted node, whereas 'uql' does. I think this made some things simpler during earlier development, but it's unintuitive, and should be changed such that 'uql' unquotes the unwrapped list node, and that both forms (and the '-nc' variants) always include the next-nodes. In the interim, the following will work:
(import macros)
(using-namespace std.macros
(def x (macro intern (a)
(let ((a2 \ (@:@ a list-node))
(x \ (qq x (uql a2))))
(print x)
(printf "\n")
a))))
(def main (fn extern-c int (void)
(x (a b c))
0))
I don't think, this can be "fixed", I just didn't understand the structure of the DNode lists.
if (uql (qq a))
would be the same as (uql (@:@ (qq a) list-node))
then (uql (@:@ (qq (a)) list-node))
would also be the same, and (uql (@:@ (qq (a) (b)) list-node)
would mean something different, even if similar syntax
(qq (uql list) rest)
returns (list0 list1 …)
instead of (list0 list1 … rest)
I think the problem shown by the above has been fixed indirectly at some point along the way:
$ cat test.dt
(import stdlib)
(using-namespace std.macros
(def test-macro (macro intern (rest)
(let ((rest-list \ (link-nodes-array (arg-count mc) rest)))
(qq (uql rest-list) "test1" "test2"))))
(def main (fn extern-c int (void)
(test-macro printf "%s %s\n")
0)))
$ dalec test.dt && ./a.out
test1 test2
Though the general unintuitiveness of the above is still not very appealing.
example program:
but uql works like uq here and prints
(x (a b c))