宏内映射没有额外的括号?

时间:2017-07-27 08:20:33

标签: macros scheme racket

说我有这样的宏:

java.lang.AssertionError: assertion failed: Ran out of messages before reaching ending offset 9 for topic lms_uuid_test partition 0 start 5. This should not happen, and indicates that messages may have been lost
    at scala.Predef$.assert(Predef.scala:179)
    at org.apache.spark.streaming.kafka.KafkaRDD$KafkaRDDIterator.getNext(KafkaRDD.scala:211)
    at org.apache.spark.util.NextIterator.hasNext(NextIterator.scala:73)
    at scala.collection.Iterator$class.isEmpty(Iterator.scala:256)
    at org.apache.spark.util.NextIterator.isEmpty(NextIterator.scala:21)
    at com.scb.BulkUpload.PortalConsumeOffset$$anonfun$createStreamingContext$1$$anonfun$apply$1.apply(PortalConsumeOffset.scala:94)
    at com.scb.BulkUpload.PortalConsumeOffset$$anonfun$createStreamingContext$1$$anonfun$apply$1.apply(PortalConsumeOffset.scala:93)
    at org.apache.spark.rdd.RDD$$anonfun$foreachPartition$1$$anonfun$apply$35.apply(RDD.scala:927)
    at org.apache.spark.rdd.RDD$$anonfun$foreachPartition$1$$anonfun$apply$35.apply(RDD.scala:927)
    at org.apache.spark.SparkContext$$anonfun$runJob$5.apply(SparkContext.scala:1881)
    at org.apache.spark.SparkContext$$anonfun$runJob$5.apply(SparkContext.scala:1881)
    at org.apache.spark.scheduler.ResultTask.runTask(ResultTask.scala:66)
    at org.apache.spark.scheduler.Task.run(Task.scala:89)
    at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:214)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

如果我在这样的事情上使用它(可能有更多选项):

"send.buffer.bytes"->"5000000", "max.partition.fetch.bytes" -> "5000000", "consumer.fetchsizebytes" -> "5000000"

它将其转换为

(define-syntax (choose stx)
  (define data (syntax->datum stx))
  (define args (cadr data))
  (define body (cddr data))
  (define output
    `(apply (case (car ,args)
              ,(map (lambda (choice)
                           `((,(car choice)) ,(cadr choice)))
                         body)
              (else (displayln "error")))
            (cdr ,args)))
  (println output)
  #'(void))

哪个不是有效的代码,因为地图给了它额外的括号。相反,我希望它能给我这个:

(choose args
        ("run" runsomething)
        ("del" delsomethingelse))

我怎么能这样做?

1 个答案:

答案 0 :(得分:2)

使用unquote-splicing(又名,@)删除map周围的列表。

示例:

(define xs '(a b c))
`(1 2 ,xs  3 4)    ; => '(1 2 (a b c) 3 4)
`(1 2 ,@xs 3 4)    ; => '(1 2 a b c 3 4)

但是我注意到您在输入syntax->datum上使用了stx 语法变换器。这删除了词汇信息 最终可能导致问题。它建议使用syntax-casesyntax-parse,它使用模式匹配来挑选元素 用于生成输出的输入语法和模板。

(define-syntax (choose stx)
  (syntax-case stx ()
    [(_choose args
              (datum fun-expr)
              ...)
     #'(apply (case (car args)
                [(datum) fun-expr]
                ...)
              (cdr args))]))

(define (run-it . xs) (list 'ran-it  xs))
(define (del-it . xs) (list 'delt-it xs))

(choose (list "run" 1 2 3)
        ("run" run-it)
        ("del" del-it))

Output: '(ran-it (1 2 3))