最简洁的方法来制作"派生"标识?

时间:2017-12-25 02:50:57

标签: syntax macros scheme chez-scheme

使用Scheme宏来制作"派生"这是非常常见的。标识符,如定义记录类型foo(使用R6RS语法记录API)将默认定义一个名为make-foo的构造函数。我想在我自己的宏中做类似的事情,但我在标准库中找不到任何干净的方法。我最后写了这个:

(define (identifier-add-prefix identifier prefix)
  (datum->syntax identifier
                 (string->symbol (string-append prefix
                                                (symbol->string (syntax->datum identifier)))))

我将语法对象(假设为标识符)转换为数据,将该符号转换为字符串,创建前缀为前缀的新字符串,将该字符串转换为符号,最后将该符号转换为标识符与identifier在同一句法环境中。

这有效,但似乎迂回曲折。是否有更清洁或更惯用的方式来做到这一点?

1 个答案:

答案 0 :(得分:1)

虽然它可能不是一个卫生的宏,但我想你可以使用这样的define-syntax(在鸡计划中)。 对于鸡计划,宏的文档是here。同样this SO question揭示了鸡计划宏。最后,我不知道这是否是解决问题的惯用方法。

A = [
    1   0    0.7
    1   1    0.1
    1   2   -0.5
    1   3   -1.6
    3   0    0.3
    3   1    0.2
    3   2    0.0
    3   3   -0.2
    4   0    0.7
    4   1   -0.1
    4   2   -0.3
    4   3    0.2
    5   0   -0.5
    5   1   -0.4
    5   2   -0.9
    5   3   -0.4
    8   0    0.5
    8   1    1.0
    8   2    0.3
    8   3    0.4
 ];

A_min = min(A(:,1));
A_max = max(A(:,1));
A_seq = A_min:A_max;
A_seq_cnt = numel(A_seq) * 4;

B_idx1 = repmat(A_seq,4,1);
B = [B_idx1(:) repmat((ones(A_seq_cnt,1) * -999),1,2)];

for n = unique(A(:,1)).'
    B((B(:,1) == n),2:3) = A((A(:,1) == n),2:3);
end

上面的单个定义可以更改为定义getter / setter或其他与记录交互方式的(begin ...)。