jerome.martin.dev
2019-5-28 08:45:55

Well I’ve never used ClojureScript, but I guess yes, it’s similar to some kind of “transpiling”. Bascially it could look like this: (javascript (function (hello who) (console.log (+ "Hello " who "!"))) (hello "world")) and this would generate: function hello(who) { console.log("Hello " + who + "!"); } hello("world");


jerome.martin.dev
2019-5-28 08:47:33

So that programmers can have the power of Racket macros at hand when writing javascript. Or even generate javascript on-the-fly in a web server.


todo
2019-5-28 09:29:38

Can someone briefly explain how define-syntax, syntax-parse, syntax-rules, syntax-case relate to each other?


sorawee
2019-5-28 09:50:10

https://www.greghendershott.com/fear-of-macros/ should cover all of these, but to give you a summary

Historically, syntax-rules comes before syntax-case, and syntax-case comes before syntax-parse. Regarding expressiveness, syntax-rules is less expressive than syntax-case, and syntax-case is less expressive than syntax-parse.

syntax-rules = traditional hygienic syntax matcher in Scheme syntax-case = an extension of syntax-rules so that you can manipulate syntax object too, allowing you to break hygiene if you want syntax-parse = syntax-case with better error message and with other convenient utilities.


sorawee
2019-5-28 09:53:04

syntax-{rules, case, parse} are pretty much a match working on syntax objects. You can think of it as match/case/if.

define-syntax lifts a regular function that consumes a syntax object and returns a syntax object to macro.


todo
2019-5-28 09:53:08

Yeah, I was reading fear-of-macros, transform! section, but felt I was missing the overall picture.


todo
2019-5-28 09:55:01

summarizing high levels: by invention date (increasing): rules, case, parse by expressive power (increasing): rules, case, parse jump from rules -> case: ‘syntax object’, can break hygiene jump from case -> parse: better error msgs Is that correct?


sorawee
2019-5-28 09:55:23

yes


todo
2019-5-28 09:55:33

Great, thanks for clarifying!


todo
2019-5-28 09:56:18

In https://www.greghendershott.com/fear-of-macros/Transform_.html <— is this rules, case, parse … or manually writing transforms ?


sorawee
2019-5-28 09:56:45

That’s a manual transformer


todo
2019-5-28 09:56:53
(define-syntax (say-hi stx)
    #'(displayln "hi"))

looks awfully similar to clojure style defmacros


sorawee
2019-5-28 09:57:15

Yup, that’s correct


todo
2019-5-28 09:58:38

Is the following intuition correct: define-syntax = write macros as “sexp -> sexp transforms” rules / case / parse = “dsls” built on top of “define-syntax”


sorawee
2019-5-28 10:00:22

I wouldn’t say “on top of define-syntax”. They are orthogonal


sorawee
2019-5-28 10:00:39

rules / case / parse are just pattern matchers, just like match. However, they work on syntax objects instead.


sorawee
2019-5-28 10:01:29

E.g.,

(syntax-parse #'(hello world)
  [(id1 id2) #'(id2 id1)])

;=&gt; #'(world hello)

The above code roughly compiles to:

(define stx #'(hello world))
(define datum (syntax-&gt;datum stx))
(define new-datum
  (if (= (length datum) 2)
           (list (second datum) (first datum))
           (error 'expect-length-2)))
(datum-&gt;syntax stx new-datum)

todo
2019-5-28 10:02:08

sounds like I need to go write some rules/case/parse to even get the right intuition :slightly_smiling_face:


todo
2019-5-28 10:09:25

If we squint, is syntax-parse basically (1) pattern-match/unification + (2) rewrite rule ?


todo
2019-5-28 10:09:37

(compiled to ifs/conds)


sorawee
2019-5-28 10:09:48

Correct


todo
2019-5-28 10:10:21

Thanks, this is finally starting to make sense, for some reason, syntax-rules/case/parse always seemed like this big pile of black magic.


todo
2019-5-28 10:11:29

I have an unrelated question: do you use dr racket? Coming from an Emacs/IntelliJ-IDEA background, dr racket feels like notepad right now — not because of dr racket is limited, but because I’m not familiar with the key bindings / workflow. Any advice on reaching working proficienty in dr racket?


sorawee
2019-5-28 10:18:01

Let me try this one more time

You can use match on values:

(match (list 1 2)
  [(list a b) (list b a)]) ;=&gt; (list 2 1)

syntax-{rules, case, parse} is like match, but it works only on syntax objects.

(syntax-parse #'(1 2)
  [(a b) #'(b a)]) ;=&gt; #'(2 1)

The above two computations happen at runtime.


We can lift a function that consumes a syntax object and produce a syntax object to compile time as a macro.

(define-syntax (foo stx)
  (match (syntax-&gt;datum stx)
    [(list _ x y) (datum-&gt;syntax stx (list y x))]))

(foo 10 add1) ;=&gt; transform to (add1 10) ;=&gt; 11
(define-syntax (bar stx)
  (syntax-parse stx
    [(_ x y) #'(y x)]))

(bar 10 add1) ;=&gt; transform to (add1 10) ;=&gt; 11

todo
2019-5-28 10:20:17

What is the distinction between “values” and “syntax objects”? I was recently just writing a scheme interpreter, is the following correct:

values = some VM object that exists at run time syntax object = refers to some continuous substring (may be multi line) of some buffer, that also happens to be parseable scheme expr ?


sorawee
2019-5-28 10:20:38

syntax object is a kind of value


todo
2019-5-28 10:22:03

hmm, let me try this again value = set of all objects the VM can create syntax object = needs a buffer-name, starting column, starting row, length Is that correct? If not, I’m missing something fundamental


sorawee
2019-5-28 10:23:31

I’m not familiar with the terminology that you are using, but it sounds correct to me. My point was that syntax object is also a regular value.


sorawee
2019-5-28 10:23:46

But not the other way


todo
2019-5-28 10:25:44

I’m new to racket, so probably using the wrong terminology. Let’s play “pretend to be the compiler” — suppose we want to compile + run main.rkt … is the following approximately correct:

  1. compile main.rkt:
  2. racket fires up a racket VM, goes through main.rkt, finds all define-syntax; for each macro, we add a function to the VM
  3. we run through file again, for each macro, calling corresponding function to expand the sub expressionN
  4. we now have a racket program w/ no macros
  5. we compile the code
  6. now, at runtime:
  7. app fires up a different racket vm
  8. interprets out compiled bytecode point being: a racket vm is fired up during the compile time for the macro processing Is the above approximately correct?

todo
2019-5-28 10:26:57

so macros are racket functions executed on a racket VM — but a VM that exists only at compile time — i.e. not the VM run at runtime of the app


sorawee
2019-5-28 10:27:05

Correct.


todo
2019-5-28 10:28:18

Thanks, and except in cases where we do

(define stx_blah #'(....))

except in the above cases, syntax-objects exist on the compile-time-macro-expansion-VM, and not the runtime-VM (unless we explicitly create one via (syntax ...))


todo
2019-5-28 10:28:38

^ Is that also correct regarding syntax objects?


sorawee
2019-5-28 10:29:04

Syntax object can exist in both runtime and compile time


todo
2019-5-28 10:29:20

Hmm, I phrased that poorly.


todo
2019-5-28 10:29:49

syntax-objects created via macro-expansion exists only on compile-time-VM syntax-objects created via (syntax ... and #'(...) exist at runtime ^— is this correct? :slightly_smiling_face:


sorawee
2019-5-28 10:30:28

Almost, but it doesn’t depend on (syntax ...) or #'(...). Instead, it depends on (define-syntax ...)


sorawee
2019-5-28 10:32:04

#'(a) will be used in macro expansion (compile time) when it’s in (define-syntax ...). And #'(a) will be a runtime value when it’s not in (define-syntax ...)


todo
2019-5-28 10:32:56

I see, so perhaps it should be stated as:

  1. (syntax ...) and #'(...) create syntax objects
  2. they are normal VM objects and created whenever they are executed
  3. (define-syntax ...) creates a function that is executed on compile-time-VM
  4. syntax-objects exist on whatever VM they’re created on [tautology, lol]

sorawee
2019-5-28 10:33:10

Correct!


sorawee
2019-5-28 10:34:35

Yeah, sorry, I communicated very poorly. Glad that you finally figure it out though.


todo
2019-5-28 10:35:25

You communicated great; I didn’t have the right terms / mental models.


todo
2019-5-28 10:35:47

I figured out why I’m so unhappy with Dr Racket — paredit — does Dr Racket have paredit key bindings?


sorawee
2019-5-28 10:36:46

I don’t use DrRacket anymore, tbh. Have been using Racket mode in Emacs



todo
2019-5-28 10:37:32

Well, thanks for all your time/patience in explaining the gist of the macro system ot me.


todo
2019-5-28 10:37:38

I really appreciate it.


todo
2019-5-28 10:38:58

I’m signing off for now, have a nice day!


todo
2019-5-28 10:46:33

is a define-syntax-rule basicalyl a define-syntax/syntax-case that only has one ‘pattern matching line’ ?


sorawee
2019-5-28 11:18:30

There’s also define-simple-macro in syntax/parse/define


sorawee
2019-5-28 11:18:59

But all of these are simply macros themselves. They are not primitives



sorawee
2019-5-28 11:21:08

Honestly, I sometimes wish @greg will rewrite his macro tutorial to avoid syntax-case entirely (since it’s simply syntax-parse without syntax class), and by the same analogy, replace define-syntax-rule with define-simple-macro.


carl.morris.world
2019-5-28 11:27:42

Sounds like a cool idea to me. JavaScript is such a versatile language having a way to tap into its ecosystem would extend Racket’s reach quite a bit.


pocmatos
2019-5-28 12:30:55

@leif you’re listed as a manager of the racket project in openhub. Do you know why commits haven’t been updated since 2017? https://www.openhub.net/p/racket


todo
2019-5-28 14:18:07

Beautiful Racket is great for DSLs. However, are there any examples of DSL -> other language, i.e. a “transpiler” of sorts.


samth
2019-5-28 14:20:28

@todo yes, people have built some for generating c++ of all things


githree
2019-5-28 14:21:42


githree
2019-5-28 14:22:35


githree
2019-5-28 14:32:33

todo
2019-5-28 15:00:05

@samth @githree: nice, thanks!


stoic0
2019-5-28 16:42:55

@stoic0 has joined the channel


leif
2019-5-28 17:27:43

@pocmatos TIL I manage the racket project on openhub…lol.


leif
2019-5-28 17:27:53

(Maybe I signed up for it a few years back?)


leif
2019-5-28 17:28:03

Anyway…


pocmatos
2019-5-28 17:29:06

You show up as one of the managers. The other one is Eli but I haven’t seen him here before.


leif
2019-5-28 17:29:08

Ah, I think I found it.


leif
2019-5-28 17:29:20

Eli used to be very involved. Less so these days.


pocmatos
2019-5-28 17:29:32

I have no permissions so can’t check but it would be great to get the data up to date.


leif
2019-5-28 17:29:53

Yup, it looks like all of the code locations for racket got removed.


leif
2019-5-28 17:30:21

Umm…do you know of a better way to add them (besides going through each repo in http://github.com/racket individually)


leif
2019-5-28 17:31:02

OH wait, you can just tell it to track a github user.


leif
2019-5-28 17:31:05

I’ve added it now.


leif
2019-5-28 17:31:11

So….hopefully it will update?


leif
2019-5-28 17:32:36

Looks like it should update in the next 24 hours or so. Does that work for you @pocmatos?


joelmccracken
2019-5-28 17:35:30

TY i will try it


pocmatos
2019-5-28 17:41:48

Will check, not home at the moment.


leif
2019-5-28 18:26:22

@stamourv Looking at draw-arrow in racket/draw/arrow (which it looks like you added)


leif
2019-5-28 18:26:58

Can you tell me why you added a required dx and dy argument? (Especially given that, say, draw-line doesn’t have it.)


leif
2019-5-28 18:28:11

It also looks like the function draws an arrow from ((startx + dx), (starty + dy)) to ((endx + dx), (endy + dy)). If that’s correct, maybe it would make sense to reflect that in the docs?


stamourv
2019-5-28 18:35:34

Did I add that? I honestly have no memory of that.


leif
2019-5-28 18:36:56

Ah, lol, fair enough.


stamourv
2019-5-28 18:36:57

Ah, looking at the git logs, I moved it from unstable/arrow. I just took what was there.


leif
2019-5-28 18:37:05

AH!!! okay


leif
2019-5-28 18:37:13

(I just ran a git blame, and it blamed you.


leif
2019-5-28 18:37:16

But that makes more sense.


stamourv
2019-5-28 18:37:17

So you may want to see who wrote it in that repo.


leif
2019-5-28 18:37:31

Will do.


leif
2019-5-28 18:37:54

I take it then that you wouldn’t mind if the dx and dy became optional arguments.


leif
2019-5-28 18:38:17

(To bring it more inline with the rest of the racket/draw API, while also not breaking backwards compatibility.)


stamourv
2019-5-28 18:38:38

That sounds reasonable to me, but I’m not the right person to ask.


leif
2019-5-28 18:40:51

Ah, okay. Looks like @samth Is the only other person to have touched it: https://github.com/racket/unstable/blob/master/unstable-lib/arrow.rkt


leif
2019-5-28 18:40:57

Anyway, thanks.



samth
2019-5-28 18:43:57

draw-arrow is very old and I think was created by @robby



soegaard2
2019-5-28 18:49:29

greg
2019-5-28 19:13:45

Well this got out of hand quickly :smile: https://twitter.com/mattmight/status/1132448468994330625


todo
2019-5-28 19:49:20

https://docs.racket-lang.org/reference/file-ports.html#%28def._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._with-output-to-file%29%29 how do I fix: (with-output-to-file "blah.tex" (lambda () (printf "hello world")) [#:exists 'replace])


greg
2019-5-28 20:49:05

@todo Just remove the square brackets.


greg
2019-5-28 20:49:35

In Racket docs, the square brackets indicate optional arguments. You don’t actually supply the square brackets.


greg
2019-5-28 20:51:40

Also, keyword arguments — like #:exists 'replace here — may go anywhere among the positional arguments. So, how you have it above is fine (without the square brackets). Or, for instance, you could also do (with-output-to-file "blah.tex" #:exists 'replace (lambda () (printf "hello world")))


greg
2019-5-28 20:52:21

Or (with-output-to-file "blah.tex" #:exists 'replace (lambda () (printf "hello world")))


robby
2019-5-28 21:03:01

@leif: what was the actual question? That function draws arrows in check syntax and it was refactored out like that so Philippe could use it in MrFlow


robby
2019-5-28 21:03:45

More generally many GUI library functions take dx/d’y arguments because other functions pass them. Like the draw method of a snip or of a canvas.


todo
2019-5-28 21:10:18

@greg: got it working, thanks!


todo
2019-5-28 21:12:56

Is there a way to run a command FROM A PARTICULAR DIRECTORY?

I’m currently using pdf-latex from the slatex package. However, it’s duping all the intermediate files in cwd instead of the directory where the tex file is located.

I am currently looking at https://docs.racket-lang.org/reference/subprocess.html but I don’t see a way to specify the working directory.

In particular, what I want to do is to

run “pdflatex blah.tex” from directory "/home/foobar/tmp/"


sorawee
2019-5-28 21:14:32

Try (parameterize ([current-directory PATH-TO-YOUR-DIRECTORY]) (YOUR-COMMAND-HERE))?


todo
2019-5-28 21:15:39

is “parameterize” like “dynamically scoped vars”, or is it something else?


todo
2019-5-28 21:17:24

okay, it definitely worked


leif
2019-5-28 21:24:14

@robby Eh, while not super important, the original question was to make the dx/dy arguments optional.


leif
2019-5-28 21:24:39

(defaulting to 0), that way it could be more in line with, say, the draw-line method.


robby
2019-5-28 21:24:43

Is there a reason to change the code?


leif
2019-5-28 21:25:04

Not a big one no.


robby
2019-5-28 21:25:14

Maybe best to leave it alone, then.


leif
2019-5-28 21:25:22

SMall one: it got annoying for me to put 0 0 at the end of several function calls. :wink:


leif
2019-5-28 21:25:35

But that’s admittedly small.


leif
2019-5-28 21:25:57

But it might make sense to update the docs to clarify where the line is drawn. :wink:


leif
2019-5-28 21:26:05

I’ll do that later…. (famous last words)


robby
2019-5-28 21:26:18

Docs update would be nice


justin.hu
2019-5-28 21:30:41

On the subject of arrows, I’m trying to use the check-syntax button to draw arrows. These arrows are being used for metadata annotations, associating an element from a tag with some syntax in the function body. I’ve tried to read through the code in drracket/private/syncheck/gui.rkt, and I think that it should be possible to create an arrow from an arbitrary location to another arbitrary location. Is it possible to do that without extending the check-syntax tool? An example would be drawing an arrow between one-of and the open-paren before cond in the following: (@dd-template-rules one-of atomic-distinct atomic-distinct) (define (fn-for-foo f) (cond [(string=? "L" f) (...)] [(string=? "R" f) (...)]))


alexknauth
2019-5-28 21:34:01

Yes. The way I’ve used to draw arrows between arbitrary locations is to generate a fresh identifier, make copies with different source locations, and use 'disappeared-use with one source location and 'disappeared-binding with the other source location


justin.hu
2019-5-28 21:37:20

Thanks.


justin.hu
2019-5-28 21:37:32

I’ll look into this.


justin.hu
2019-5-28 21:42:52

I’m not quite sure how to work that, here’s what I have: (require (for-syntax racket/syntax)) (define-syntax (tag-it stx) (syntax-case stx () [(_ a b) (let ([temp (generate-temporary)]) (begin (syntax-property #'a 'disappeared-use temp) (syntax-property #'b 'disappeared-binding temp)))])) (define a 1) (define b 2) (tag-it a b)


justin.hu
2019-5-28 21:43:12

I expect an arrow from b to a in tag-it, but I’m not getting anything.


alexknauth
2019-5-28 21:50:38

Here’s what I mean below. You still need the 'orig-for-check-syntax property on the source-location identifiers #lang racket (require (for-syntax racket/syntax)) ;; from up here (begin-for-syntax (define (orig stx) (syntax-property stx 'original-for-check-syntax #t)) (define (add-arrow stx from to) (define id (orig (generate-temporary))) (define sym (syntax-e id)) (syntax-property (syntax-property stx 'disappeared-binding (datum-&gt;syntax id sym from id)) 'disappeared-use (datum-&gt;syntax id sym to id)))) (define-syntax (draw-arrow stx) (add-arrow #'(void) (list (syntax-source stx) #f #f 61 7) (list (syntax-source stx) #f #f 609 14))) ;; to over down here (draw-arrow)


todo
2019-5-28 21:59:20

How do I annotate / export this untyped function so I can call it from typed racket?

#lang typed/racket

(require slatex/slatex-wrapper)




(define (write-pdf dir-name file-name content)
    (parameterize ([current-directory dir-name])
    (with-output-to-file file-name
      (lambda ()
        (write-string "\\documentclass{article}\n\\usepackage{fullpage}\\begin{document}\n")
        (write-string "\\begin{displaymath}\n")
        (content)
        (write-string "\\end{displaymath}\n")
        (write-string "\\end{document}")

        )
      #:exists 'replace)
    (pdf-latex file-name)
    ))

(write-pdf "/data/ftp/tmp" "blah.tex"
           (lambda ()
               "x = y + 1"))

justin.hu
2019-5-28 22:00:21

Thanks. This works nicely.


alexknauth
2019-5-28 22:13:59

What type would you give it in the typed world?


todo
2019-5-28 22:14:25

String, String, Function -> ()


alexknauth
2019-5-28 22:14:49

wait so content is a function but what does it return?


todo
2019-5-28 22:15:09

it doesn’t return anything, the key is that the with-output-to-file hijacks stdout


alexknauth
2019-5-28 22:15:20

So when you call it it returns a string?


todo
2019-5-28 22:15:29

oh sorry, I passed a bad content function, 1 sec


alexknauth
2019-5-28 22:15:34

oh okay


todo
2019-5-28 22:15:48
(write-pdf "/data/ftp/tmp" "blah.tex"
           (lambda ()
             (write-string
               "x = y + 1")))

todo
2019-5-28 22:16:04

content doesn’t return anything; it writes to stdout, which is then captured by the with-output-to-file


todo
2019-5-28 22:16:29

(String, String, () -> ()) -> () would be the type sig I want for write-pdf


alexknauth
2019-5-28 22:16:51

So that looks like it would have the type (-&gt; String String (-&gt; Void) Void)


todo
2019-5-28 22:17:40

Sounds right.


todo
2019-5-28 22:18:16

So do I need to create a separate file with #lang racket … or can we, in the middle of a #lang typed/racket file, say:

for this next function, it’s going to be untyped ?


alexknauth
2019-5-28 22:18:33

In the untyped file, provide it normally. In the typed file, use require/typed with the type above


todo
2019-5-28 22:19:22

If this is not too much trouble, can you write the #lang typed/racket file for me? I think it’ll be alot easier to understand how all the pieces fit together from a working example.


todo
2019-5-28 22:25:08

I’m trying #lang typed/racket (require/typed "util.rkt" [write-pdf (-&gt; String String (-&gt; Void))])


todo
2019-5-28 22:25:21

and getting error:

. only-in: identifier `write-pdf' not included in nested require spec in: "util.rkt"

todo
2019-5-28 22:28:40

it all works now; thanks!


todo
2019-5-28 23:11:21

For racket exact-num/big-int, is there a O(1) way to get # of bits used? I’m building a http accessible simple calculator and need to avoid DOS by using large nums to consume all memory.


todo
2019-5-28 23:25:32

integer-length


todo
2019-5-29 00:27:00

I know about https://docs.racket-lang.org/nanopass/index.html

Question: where can I find the actual assignments that goes along with this framework?


todo
2019-5-29 00:39:15

Is it normal in Dr Racket for the following code to take seconds to compile ?


(define-type MathNode (U BigFloat MathNeg))

(struct BigFloat ([base : Number] [exp : Number]))
(struct MathNeg ([base : MathNode]))
(struct MathAdd ([base : (Listof MathNode)]))
(struct MathMul ([base : (Listof MathNode) ]))

I expect typed racket to be slightly slower but not this much slower.


todo
2019-5-29 00:58:26
#lang racket

(require Racket-miniKanren/miniKanren/mk)

(define fail
  (== #t #f))

(define succeed
  (== #t #t))


(current-readtable
 (make-readtable (current-readtable)
                 #\s
                 'dispatch-macro
                 (lambda (a b c d e f) succeed)))

(current-readtable
 (make-readtable (current-readtable)
                 #\u
                 'dispatch-macro
                 (lambda (a b c d e f) fail)))


(run* (q) #s)

This results in an error of:

. . read-syntax: expected `(`, `[`, or `{` after `#s`

how do I fix this?


samdphillips
2019-5-29 01:42:50

You need to make a language that defines your extended readtable and then use that lang


samdphillips
2019-5-29 01:45:22

There is an example at https://docs.racket-lang.org/guide/hash-lang_reader.html you want it to provide a parameterized read and read-syntax


alexknauth
2019-5-29 01:52:17

Parameters like current-readtable set at run time only affect the run-time evaluation of the code, so they don’t affect compile-time things like reading/parsing the program


alexknauth
2019-5-29 01:52:57

However, if you set up a #lang and set the current-readtable at “read time” in the lang’s reader module, then it can do that


todo
2019-5-29 01:54:35

I’m temporarily using ss for #s and ff for #f.


todo
2019-5-29 01:55:25

https://docs.racket-lang.org/syntax-parse-example/index.html <— Does this explain anywhere how repetition, "*" and "…" works? I’m seeing lots of examples but I can’t find an explaination of how these three forms work.


todo
2019-5-29 01:57:39

So I now have a file called ‘reader.rkt’ which contains:

#lang racket

(require (for-syntax racket/base syntax/parse))

(define ff
  (== #t #f))

(define ss
  (== #t #t))

(current-readtable
 (make-readtable (current-readtable)
                 #\s
                 'dispatch-macro
                 (lambda (a b c d e f) ss)))

(current-readtable
 (make-readtable (current-readtable)
                 #\u
                 'dispatch-macro
                 (lambda (a b c d e f) ff)))

todo
2019-5-29 03:48:24

In this code, why can’t I export my macros and how can I fix it:

#lang racket

(provide (for-syntax conj disj)
         ff ss
         )

(require (for-syntax racket/base syntax/parse))

(require Racket-miniKanren/miniKanren/mk)


(define ff
  (== #t #f))

(define ss
  (== #t #t))

(define-syntax (disj stx)
  (syntax-parse stx
    [(_) #'ff]
    [(_ clause) #'clause]
    [(_ clause ...) #'(conde (clause) ...)]
    ))

(define-syntax (conj stx)
  (syntax-parse stx
    [(_) #'ss]
    [(_ clause) #'clause]
    [(_ clause ...) #'(conde (clause ...))]))

nryoung
2019-5-29 03:49:45

@nryoung has joined the channel


michaelmmacleod
2019-5-29 06:41:08

@todo Try using (provide conj disj) instead of (provide (for-syntax conj disj)) See: https://docs.racket-lang.org/reference/syntax-model.html?q=define%2Dsyntax#%28part._transformer-model%29 “In a top-level context or module context, when the expander encounters a define-syntaxes form, the binding that it introduces for the defined identifiers is a transformer binding. The value of the binding exists at expansion time, rather than run time (though the two times can overlap), though the binding itself is introduced with phase level 0 (i.e., in the base environment).”