aowens5189
2018-8-10 15:42:24

@aowens5189 has joined the channel


pocmatos
2018-8-10 16:02:07

Hi guys, I am thinking of writing a macro that wraps around contract-out to selectively disable contracts at compile-time (I know this might be seen as bad, but it doubles the speed of my program). Is there already anything out there that does this?



pocmatos
2018-8-10 16:09:45

@samth exactly what I needed, thanks.


redwynskaja
2018-8-10 18:50:25

Hello. I am trying to return several (define ...) expressions(?) with a macro. I managed to produce: '((define par-h (Parameter "h" "handling time" 123 kg)) (define par-a (Parameter "a" "attack rate" 321 kg)))


samth
2018-8-10 18:51:09

@redwynskaja you probably want (begin (define ...) (define ...))


redwynskaja
2018-8-10 18:51:11

My problem is the error define: not allowed in an expression context … I have to get rid of the outermost pair of parentheses, i think


soegaard2
2018-8-10 18:52:33

Try (let () (define ...) ...)


shu--hung
2018-8-10 18:55:12

I think begin may be closer, since begin would let the defines be available outside but let` won’t


redwynskaja
2018-8-10 19:01:04

I tried begin: (1) ?: literal data is not allowed; no #%datum syntax transformer is bound in: "h" (2) However, if i copy the resulting expression to the REPL, it works (w/o the quote): '(begin (define par-h (Parameter "h" "handling time" 123 kilogram)) (define par-a (Parameter "a" "attack rate" 321 kilogram)))


shu--hung
2018-8-10 19:03:13

The problem is probably somewhere else. What is the code for this macro? Is it returning a quoted s-expression?


redwynskaja
2018-8-10 19:03:48

it is returning the code from (2) (above)


redwynskaja
2018-8-10 19:03:57

evaluating it in the repl works


redwynskaja
2018-8-10 19:04:20

(struct Parameter ([p-id : String] [p-desc : String] ;[p-val : Measure] [p-num : Number] [p-unit : Unit])


shu--hung
2018-8-10 19:04:42

And how is it defined? Using syntax-rules or some other forms?


redwynskaja
2018-8-10 19:04:53

syntax-parse


redwynskaja
2018-8-10 19:05:10

(define-syntax (def-par stx) (syntax-parse stx [(_ [~seq name:id descr:string val:number punit:expr] ...) #:fail-when (check-duplicate-identifier (syntax->list #'(name ...))) "duplicate identifier" #:with [name-str ...] (map (compose symbol->string syntax-e) (syntax->list #'[name ...])) #:with [ids ...] (map (λ (s) (string->symbol (string-append "par-" ((compose symbol->string syntax-e) s)))) (syntax->list #'[name ...])) #''(begin (define ids (Parameter name-str descr val punit)) ...)]))


redwynskaja
2018-8-10 19:06:45

This is how it would be used (def-par h "handling time" 123 kilogram a "attack rate" 321 kilogram)


shu--hung
2018-8-10 19:07:25

Try this: #'(begin (define ids (Parameter name-str descr val punit)) ...)


redwynskaja
2018-8-10 19:08:06

i did. that leads to (1) (see above).


redwynskaja
2018-8-10 19:08:10

or am i missing something?


redwynskaja
2018-8-10 19:09:05

(1) -> “iteral data not allowed” error


soegaard2
2018-8-10 19:13:56
?: literal data is not allowed;
 no #%datum syntax

Just checking: Do you have an (require (for-syntax racket/base)) ?


shu--hung
2018-8-10 19:14:31

@redwynskaja here: #'(begin (define ids (Parameter 'name-str descr val punit)) ...)


shu--hung
2018-8-10 19:14:54

I think the way name-str is introduced give it no lexical information


shu--hung
2018-8-10 19:15:23

therefore the expander failed to find the #%datum for name-str


shu--hung
2018-8-10 19:17:12

another point: the new ids needs to be given the right scope in order to be visible outside: #:with [ids ...] (map (λ (s) (syntax-local-introduce ;; <- here (datum->syntax #f (string->symbol (string-append "par-" ((compose symbol->string syntax-e) s)))))) (syntax->list #'[name ...]))


shu--hung
2018-8-10 19:17:35

otherwise those ids will only be visible to this macro


redwynskaja
2018-8-10 19:23:00

@shu—hung wow… with your last two tips it now works!


shu--hung
2018-8-10 19:24:45

a few helpers: format-id from racket/syntax combines what you need for ids, including introducing the right lexical context and format identifiers https://gist.github.com/shhyou/4e0090b8f9c33f2c02cf3b1a2290cd93


shu--hung
2018-8-10 19:25:45

and to include the current lexical context in name-strs, quasi-syntax + escape could help


shu--hung
2018-8-10 19:26:47

or similarly (datum->syntax #'here (symbol->string ...))


redwynskaja
2018-8-10 19:27:46

Thank you a lot!


notjack
2018-8-10 22:30:43

in addition to the TR code sam linked, you might be interested in Option Contracts (https://docs.racket-lang.org/option-contract/index.html). They’re more oriented towards runtime decision making about whether to use contracts or not as opposed to compile-time, and I find the API confusing, but they’re designed for exactly the use case you describe