philip.mcgrath
2019-8-14 10:59:35

It looks like the CS variant of DrRacket 7.4 has a code signing issue on Mac.


soegaard2
2019-8-14 11:11:58

What’s the error?


jarcane
2019-8-14 13:37:57

I’m curious about the ~optional clause in syntax-parse


jarcane
2019-8-14 13:38:09

I’m wondering how it works and didn’t find the docs especially helpful


laurent.orseau
2019-8-14 13:39:05

I use assocs for config and data files pretty often. It’s a breeze to deal with in Racket. I recently had to make a reader/writer for similar files in pure C++, no boost. Did you know that C++ finally introduced a way to (properly) read and write quoted strings in… C++14(!!)?


jarcane
2019-8-14 13:39:23

we use it in a few spots already in Heresy, but @alexknauth wrote all that code so I am not really sure how to work with it, and I have a fairly simple thing that would be much easier to do if I could add optional macro args without having to just add a whole new branching clause for a single thing


soegaard2
2019-8-14 13:43:42

There are a few examples: > (syntax-parse #'(m #:foo 2 a b c) [(_ (~optional (~seq #:foo x) #:defaults ([x #'#f])) y:id ...) (attribute x)]) #<syntax:eval:57:0 2> > (syntax-parse #'(m a b c) [(_ (~optional (~seq #:foo x) #:defaults ([x #'#f])) y:id ...) (attribute x)]) #<syntax:eval:58:0 #f> It looks like the first pattern (~seq #:foo x) is used to match #’(m a b c) if it succeeds fine - otherwise the pattern variables from the #:default list are bound.


jarcane
2019-8-14 13:45:28

Ahh, so I need to give a #:defaults clause or it won’t work?


soegaard2
2019-8-14 13:46:56

Apparently no, since the #:default is optional. But does it do without?


soegaard2
2019-8-14 13:47:27

Okay, that’t the next example: > (syntax-parse #'(m a b c) [(_ (~optional (~seq #:foo x)) y:id ...) (attribute x)]) #f


jarcane
2019-8-14 13:47:29

It does not seem to.


jarcane
2019-8-14 13:47:55

but possibly I’m not using this right at all


soegaard2
2019-8-14 13:48:29

In the first two cases (attribute x) was a syntax object, in the third simply #f.


jarcane
2019-8-14 13:57:41

I think maybe ~optional is not what I even want here then, as it seems to be for head-patterns and I only want an optional single term here


soegaard2
2019-8-14 14:11:54

@jarcane Can you use (~or (~seq x) (~seq)) ?


jarcane
2019-8-14 14:14:03

I think my problem is I need to figure out how to check for its absence in the matching expansion pattern. I get this: name: attribute contains non-syntax value value: #f in: name


jarcane
2019-8-14 14:21:34

@soegaard2 yeah, that method seems to work, but it of course needs to handle if x is not there. ie. it’ll return either syntax or #f, depending on whether it matches or not


ryanc
2019-8-14 15:30:39

@jarcane You might be able to use ~? (see the docs for syntax for an example). If not, you can check whether a pattern variable is absent using attribute: (attribute x) is #f if x is absent (as in soegaard2’s examples above).


ryanc
2019-8-14 15:32:40

Another thing you can do is define a helper maybe-blah splicing syntax class with two cases: either a blah or (~seq). Then you can use #:with or #:attr to define attributes for each case, and just use those attributes in the macro’s template.


ryanc
2019-8-14 15:33:23

@nma.arvydas.silanskas hah, thanks. Slack needs paren matching.


alexknauth
2019-8-14 16:06:13

@jarcane can you give an example? with a concrete example one of us can show how to use either (1. ~optional + #:defaults) or (2. ~optional without defaults + ~?) to solve the problem. In the mean time “Grammar-style” examples might be the best I can do: 1. pattern (~optional pat #:defaults ([attr-id expr])), template temp referring to attr-id 2. pattern (~optional pat), template (~? temp1 temp2) where temp1 refers to attr-id and temp2 is the fallback that doesn’t


jarcane
2019-8-14 16:12:40

@alexknauth The basic gist is that I need to pass the name of described things to them at creation so they can remember it, so I’m trying to add an optional argument to the thing macro to take that name and then pass it. The simplest (broken) clause I have so far is this:

[(thing (~or (~seq name:expr) (~seq)) (field:id value:expr) ...)
   #'(make-thing `([field
                    ,(let ([field
                            (fn (ths)
                              (syntax-parameterize ([Self (make-rename-transformer #'ths)])
                                (def-field-id field ths) ...
                                value))])
                       field)]
                   ...)
                 name)]

jarcane
2019-8-14 16:13:26

This obviously doesn’t work because I’m missing how to handle the result of an ~optional or ~or clause, presumably


sorawee
2019-8-14 16:14:35

So name might not be “bound”, right? What do you want the second argument of make-thing to be in case it’s not bound?


alexknauth
2019-8-14 16:15:54

So if the name is #false when you don’t supply one, that could be:

pattern (~or (~seq name:expr) (~seq)) template (~? name #false)


alexknauth
2019-8-14 16:17:32

or with more context:

pattern (thing (~or (~seq name:expr) (~seq)) stuff ...) template (make-thing `(stuff …) (~? name #false))


jarcane
2019-8-14 16:18:25

It needs a symbol, so probably just 'thing which is the usual default name


alexknauth
2019-8-14 16:18:40

Ok, then (~? name 'thing) I guess


alexknauth
2019-8-14 16:20:17

And there’s also another way which uses ~optional with #:defaults, and not ~?, which looks like:

pattern (~optional name:expr #:defaults ([name #' ' thing])) template name


jarcane
2019-8-14 16:20:45

I did the former and it seems to work, but I do agree the later is probably less messy to read code wise.


jarcane
2019-8-14 16:21:16

I’ll play with both, but thank you so much.


alexknauth
2019-8-14 16:21:47

Oh, another pitfall that I didn’t see until now!


alexknauth
2019-8-14 16:22:38
(thing (field1 value1) (field2 value2) ...)

alexknauth
2019-8-14 16:23:22

In that example, you have to be careful that (field1 value1) isn’t accidentally interpreted as the name expression


jarcane
2019-8-14 16:23:33

oh yup, at least the ~or based solution now breaks


jarcane
2019-8-14 16:24:03

if you don’t give the optional it confuses the first field name for an identifier and tries to evaluate it, presumably because it expanded wrong


alexknauth
2019-8-14 16:24:04

both ones break, because as far as syntax-parse is concerned (field1 value1) looks like a valid :expr


jarcane
2019-8-14 16:24:11

yah.


jarcane
2019-8-14 16:25:09

would it work to make name an :id and then wrap it in quote in the template? Or will it still confuse the list for the single value?


alexknauth
2019-8-14 16:26:43

That would work. It would be less expressive, because a user couldn’t say something like (make-thing (string->symbol (string-append "ahhh" "!")) (field1 value1)) anymore, but if you don’t intend for them to do that then making it an :id in the pattern, and quoting it in the template is great


jarcane
2019-8-14 16:35:55

Yeah, I think it’s best to make clear it’s meant to be an identifier.


alexknauth
2019-8-14 16:37:26

that would make it unambiguous, because the :id and (field value) patterns never overlap


jarcane
2019-8-14 17:01:37

how can I then safely quote the id in a way that I don’t trip over the “undefined: cannot reference an identifier before its definition”


jarcane
2019-8-14 17:08:16

never mind, figured it out, just had some bad code from earlier attempts


jarcane
2019-8-14 17:22:09

And that is the very last new feature I am doing for the next new Heresy version before the Racketfest talk. :wink:


markus.pfeiffer
2019-8-14 19:06:30

I just the other day changed over from yaml to sexpressions


markus.pfeiffer
2019-8-14 19:06:51

those projects are my private fun ones though, noone cares how I store config files there :wink:


khepin
2019-8-14 20:25:17

https://developer.squareup.com/blog/making-openapi-swagger-bearable-with-your-own-dsl/ :point_up: this is “how I tricked my co-workers” into using Racket. If it’s of interest to anyone :wink:


badkins
2019-8-14 22:15:34

I know I’m late to the party, but I’m reading Matthew’s “Composable and Compilable Macros - You Want It When?” paper, and really enjoying it: https://www.cs.utah.edu/plt/publications/macromod.pdf One of my pet peeves is missing dates on articles/papers. Any idea when this was published? I figure at least 2002 given the references.


badkins
2019-8-14 22:17:24

Ah, ICFP 2002 - had to back up to the directory: https://www.cs.utah.edu/plt/publications/


badkins
2019-8-14 22:18:06

17 years - have no other Schemes implemented a similar module & phase system?


soegaard2
2019-8-14 22:39:46

R6RS modules are close, but there are some differences. https://www.cs.indiana.edu/~dyb/pubs/implicit-phasing.pdf


soegaard2
2019-8-14 22:43:01

(There is a comparison on the last page)


plragde
2019-8-14 23:10:11

R6RS modules are close because, I suspect, Matthew Flatt was an editor and deeply involved in the process.


mflatt
2019-8-14 23:14:13

And I viewed the whole process as an experiment in whether agreeing on a module system would make more Scheme portable. (I think it turned out not to be enough, even for a stronger notion of “agreeing” than perhaps applies to R6RS.)


mflatt
2019-8-14 23:15:28

@badkins FWIW, date and venue for ACM papers is bottom of the first page, left side for 2-column format.


badkins
2019-8-14 23:16:03

mea culpa !


willbanders
2019-8-15 00:26:42

If require includes conflicting declarations, it’s specified that this is an error. How would you correct this?


jaz
2019-8-15 00:33:03

prefix-in, rename-in, or the like


notjack
2019-8-15 00:38:44

I use test submodules and contract-out a lot, but module+ bypasses the contacts. So I’ve gotten into the habit of always adding this near the top of my files: (module+ test (require (submod ".."))) …which causes the unit tests to exercise the module’s public contracts. Does anyone else do this?


philip.mcgrath
2019-8-15 06:37:34

I do.