pocmatos
2018-5-18 08:59:39

Sometimes macro errors drive me bonkers… Can someone with better eyes than me understand why: #lang racket (require (for-syntax racket/syntax)) (define-syntax (define-feature-statistics stx) (syntax-case stx () [(_ feature (event-types ...)) (with-syntax ([stats-name (format-id stx "~a-statistics" #'feature)]) #`(begin #,@(for/list ([x (in-list (syntax->list #'(event-types ...)))]) (syntax-case x (:timed) [event0 (with-syntax ([register-name (format-id "register-event/~a" #'event0)]) #`(define-syntax (register-name stx) (syntax-case stx [(_) (record-event (make-event event0 (current-inexact-milliseconds) (void)) feature-statistics)])))]))))])) (define-feature-statistics simulator (sim-symbolic)) complains about an error in : regexp-match?: contract violation expected: (or/c string? bytes? path? input-port?) given: #<syntax:22:3 sim-symbolic> argument position: 2nd other arguments...:


pocmatos
2018-5-18 09:00:41

I know I should be using syntax-parse by now but I haven’t gotten around to look into it…


pocmatos
2018-5-18 09:00:59

also, not sure syntax-parse would help in this situation.


pocmatos
2018-5-18 09:02:29

I am sure the error is obvious to those living in macro-land, but for those knocking on the gate trying to come in this is a very rude way to welcome you. :slightly_smiling_face:


dedbox
2018-5-18 09:15:56

looks like you’re missing an argument at (with-syntax ([register-name (format-id


dedbox
2018-5-18 09:16:24

(format-id stx…?


pocmatos
2018-5-18 09:20:51

@dedbox ah, great. Thanks. I am indeed. But why is regexp-match? being pointed to as the culprit instead of format-id?


pocmatos
2018-5-18 09:20:59

maybe @mflatt?



dedbox
2018-5-18 09:24:24

the definition of restricted-format-string below uses a regexp to validate the format string.


pocmatos
2018-5-18 09:25:41

@dedbox understood but the error message still leaks internal details I shouldn’t need to worry about.


dedbox
2018-5-18 09:39:26

Well, that’s a run-time error. I don’t see any contracts in the module.


dedbox
2018-5-18 09:44:55

I should separate those two comments. I meant to say, Racket is just crashing and reporting the point of error. A contract on format-id could catch bad calls and report the call site instead.


dedbox
2018-5-18 09:48:08

I wonder if it’s absent for a reason. The signature looks pretty straight forward in the docs.


greg
2018-5-18 11:45:45

Quick glance, maybe suffice to change restricted-format-string? from (regexp-match? #rx"^(?:[^~]\|~[aAn~%])*$" fmt) to (and (string? fmt) (regexp-match? #rx"^(?:[^~]\|~[aAn~%])*$" fmt)). format-id is already using raise-arguments-error instead of contract. (Might be unable to require racket/contract because reasons like circular dependency.)


pocmatos
2018-5-18 13:03:52

So, I fixed my macro above, thanks @dedbox. The thing create something like a struct with a few extra functions. I now need to provide to the user something like a struct-out. I looked at the struct-out implementation and OMG: https://github.com/racket/racket/blob/54989bddec0f854a290b427d7cc49b0105dc56a2/racket/collects/racket/private/reqprov.rkt#L978


pocmatos
2018-5-18 13:04:03

Is there an easier way to achieve something like it?


pocmatos
2018-5-18 13:05:22

I don’t want to re-export the struct-out under a different name, but instead export a set of functions that are generated by the main macro.


pocmatos
2018-5-18 16:17:52

Using ->i i am trying to define a contract that ensures that two lists received as arguments have the same length. This seems to be the wrong way to do it since I cannot have an argument as its own dependent.


pocmatos
2018-5-18 16:19:11

So when I do (->i ([lst1 list?] [lst2 (lst1 lst2) (and/c list? (= (length lst1) (length lst2)))] ... it fails with ->i: lst2's contract depends on lst2's value


lexi.lambda
2018-5-18 16:20:25

Try this: (->i ([a list?] [b (a) (and/c list? (λ (b) (= (length a) (length b))))]) any)


lexi.lambda
2018-5-18 16:22:10

Remember that the arguments to and/c must be contracts. (and/c list? #t) is a contract that expects its argument to be a list? and be eq? to #t, which will never be satisfied.


pocmatos
2018-5-18 16:22:11

it seems I need to name the range. but [out any/c] will do even if it’s redundant.


pocmatos
2018-5-18 16:22:12

thanks.


pocmatos
2018-5-18 16:22:36

yes, that seems to work. Now it makes sense!


dedbox
2018-5-18 18:02:16

It looks like the struct-out source is mostly argument processing. I wonder if it could be rewritten in a more transparent style.


samth
2018-5-18 19:32:07

@dedbox you could write it using syntax-parse more clearly, but as mentioned earlier, syntax-parse uses structs


dustin
2018-5-18 21:50:48

I didn’t realize Rust’s type system designers were using PLT Redex.


dedbox
2018-5-19 04:11:58

As an exercise, I rewrote struct-out in a more self-descriptive style. Here’s the diff: https://github.com/dedbox/racket/commit/1eb85d2fc44b7b0a442410c109d7e2d3519c3429


dedbox
2018-5-19 04:12:13

I required “define.rkt” for syntax and then used it to move and rename chunks of code. Not sure how safe that is, but the unit tests in racket-test-core are all passing.


dedbox
2018-5-19 04:15:30

Creating this was very informative. It helped me understand Racket a little better and gave me a reason to learn how to work with the Racket source.


dedbox
2018-5-19 04:23:19

@samth this is what I meant earlier