Re: [racket-users] I wrote my first macro ever!
> https://www.mail-archive.com/racket-users@googlegroups.com/msg40201.html This was effectively the best writing I could read about syntax-parse templates and the quirks of using ~@ and ~?. Thank you so much Alexis for those explanations! You rock. On Tuesday, April 30, 2019 at 10:12:15 PM UTC+2, David Storrs wrote: > > Congratulations on dipping into the macro world! It is an interesting, > terrifying, and often frustrating experience. :> > > I see that you've already read Fear of Macros, which is great. In > addition to FoM, one of the most useful resources I've found for > understanding ... in macros has been Alexis King's module 'struct-update', > the code for which is linked below. In addition, she provides a very good > explanation of ... in this thread: > https://www.mail-archive.com/racket-users@googlegroups.com/msg40196.html > which could supplement what Jérôme Martin said below. > > HTH, > > Dave > > struct-update docs: https://docs.racket-lang.org/struct-update/index.html > struct-update code: > https://github.com/lexi-lambda/struct-update/blob/master/struct-update-lib/struct-update/main.rkt > -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] I wrote my first macro ever!
Congratulations on dipping into the macro world! It is an interesting, terrifying, and often frustrating experience. :> I see that you've already read Fear of Macros, which is great. In addition to FoM, one of the most useful resources I've found for understanding ... in macros has been Alexis King's module 'struct-update', the code for which is linked below. In addition, she provides a very good explanation of ... in this thread: https://www.mail-archive.com/racket-users@googlegroups.com/msg40196.html which could supplement what Jérôme Martin said below. HTH, Dave struct-update docs: https://docs.racket-lang.org/struct-update/index.html struct-update code: https://github.com/lexi-lambda/struct-update/blob/master/struct-update-lib/struct-update/main.rkt On Sun, Apr 28, 2019 at 4:40 PM wanderley.guimar...@gmail.com < wanderley.guimar...@gmail.com> wrote: > I've been following the list since I started to play with Racket (~6 > months), but I've never had the courage to write a macro. It was like > a kind of magic that I wanted to manipulate, but I was afraid to do > that. > > > ## Context. Story time! > > I discovered Racket because a friend asked me to teach him to how to > program. Inspired by the Lego kit for robotic that I saw years ago, I > created a little language (move forward and rotate) and started to ask > him to accomplish some tasks with the language. The day after that, I > searched for "teach kids how to program" (my friend is not a kid > .. but what would be a better way to teach someone?) and I found > "Turtles" which led me to read an article from Papert. The text was > mind blowing. I am Brazilian, and I can't say for all of us, but I > was raised with a black/white (or right/wrong) mindset. This mindset > shaped the way that I've been approaching life. Basically, I always > had one chance to get things right. Yeah! I love programming and it > is a nightmare to try to get things right at first (it is so easy to > be stuck with this mindset). So, even though I loved programming, I > also hated it. But the ideas in Papert's article was liberating, I've > never thought that exploring without fear of failure would be so > natural. I wanted more of it! I kept searching and found "The Little > Lisper", which I consumed it vigor. Then I found some of Matthias' > work in programming education and finally Racket. As I said, I've > been following the list for a while. And man, that is a wonderful > community. OK! My friend and I never really started those classes, > but I am grateful for his first interest on that. > > I've learned that if I want to learn something I have to explore it > without fear! Then, I decided to do the [Advents of Code > 2018](https://adventofcode.com/2018) in > Racket. My goal was use functional programming and immutability as > much as I can. I started with Typed Racket, but I found hard to > freely explore while having to satisfy the compiler. `#lang racket` was > the best option for me. > > What about writing macros? I've been postponing it until April 26th. > I was watching [Inside Racket Seminar 6. Sam Tobin-Hochstadt on > match](https://www.youtube.com/watch?v=IikGK8XP5_Q) > and thinking how these people can write such big programs in an > untyped laguange. I remembered to see something about "bottom-up > programming" in [Racket > pages](https://docs.racket-lang.org/style/Units_of_Code.html) and I > started to search for it. I found > the key idea: building the solution from bottom-up give you chance to > build a language for the problem. It became clear when I saw [Daniel > Friedman & Jason Hemann - Implementing a > microKanren](https://www.youtube.com/watch?v=0FwIwewHC3o) in action > (by the > way, I am a big fan of Friedman) and [Bottom Up vs Top Down Design in > Clojure - Mark Bastian](https://www.youtube.com/watch?v=Tb823aqgX_0). > > I went back to my problem and found that I have a code like > > (define empty-unit #\.) > (define (empty-unit? v) (eq? #\. v)) > (define rock-unit #\.) > (define (rock-unit? v) (eq? #\# v)) > > which I really wanted to express like > > (define-enum unit (empty #\.) (rock #\#)) > > It is time for writing my first macro! > > > ## Macro time! > > My first try was something like this > > (define-syntax (define-unit.wrong stx) > (syntax-case stx () > [(_ name value) > (let ([name? (string->symbol (format "~a?" name))]) >#'(begin >(define name value) >(define (name? other-value) (eq? value other-value])) > > which failed with > > ; /Users/wander/myprojects/aoc/2018/day17.rkt:118:48: name: > pattern variable cannot be used outside of a template > ; in: name > ; [Due to errors, REPL is just module language, requires, and stub > definitions] > > I didn't understand the error message, and had no idea of how to move > forward. I searched the error message and found [Greg Hendershott's > Fear of Macros - Pattern > match
[racket-users] I wrote my first macro ever!
I've been following the list since I started to play with Racket (~6 months), but I've never had the courage to write a macro. It was like a kind of magic that I wanted to manipulate, but I was afraid to do that. ## Context. Story time! I discovered Racket because a friend asked me to teach him to how to program. Inspired by the Lego kit for robotic that I saw years ago, I created a little language (move forward and rotate) and started to ask him to accomplish some tasks with the language. The day after that, I searched for "teach kids how to program" (my friend is not a kid .. but what would be a better way to teach someone?) and I found "Turtles" which led me to read an article from Papert. The text was mind blowing. I am Brazilian, and I can't say for all of us, but I was raised with a black/white (or right/wrong) mindset. This mindset shaped the way that I've been approaching life. Basically, I always had one chance to get things right. Yeah! I love programming and it is a nightmare to try to get things right at first (it is so easy to be stuck with this mindset). So, even though I loved programming, I also hated it. But the ideas in Papert's article was liberating, I've never thought that exploring without fear of failure would be so natural. I wanted more of it! I kept searching and found "The Little Lisper", which I consumed it vigor. Then I found some of Matthias' work in programming education and finally Racket. As I said, I've been following the list for a while. And man, that is a wonderful community. OK! My friend and I never really started those classes, but I am grateful for his first interest on that. I've learned that if I want to learn something I have to explore it without fear! Then, I decided to do the [Advents of Code 2018](https://adventofcode.com/2018) in Racket. My goal was use functional programming and immutability as much as I can. I started with Typed Racket, but I found hard to freely explore while having to satisfy the compiler. `#lang racket` was the best option for me. What about writing macros? I've been postponing it until April 26th. I was watching [Inside Racket Seminar 6. Sam Tobin-Hochstadt on match](https://www.youtube.com/watch?v=IikGK8XP5_Q) and thinking how these people can write such big programs in an untyped laguange. I remembered to see something about "bottom-up programming" in [Racket pages](https://docs.racket-lang.org/style/Units_of_Code.html) and I started to search for it. I found the key idea: building the solution from bottom-up give you chance to build a language for the problem. It became clear when I saw [Daniel Friedman & Jason Hemann - Implementing a microKanren](https://www.youtube.com/watch?v=0FwIwewHC3o) in action (by the way, I am a big fan of Friedman) and [Bottom Up vs Top Down Design in Clojure - Mark Bastian](https://www.youtube.com/watch?v=Tb823aqgX_0). I went back to my problem and found that I have a code like (define empty-unit #\.) (define (empty-unit? v) (eq? #\. v)) (define rock-unit #\.) (define (rock-unit? v) (eq? #\# v)) which I really wanted to express like (define-enum unit (empty #\.) (rock #\#)) It is time for writing my first macro! ## Macro time! My first try was something like this (define-syntax (define-unit.wrong stx) (syntax-case stx () [(_ name value) (let ([name? (string->symbol (format "~a?" name))]) #'(begin (define name value) (define (name? other-value) (eq? value other-value])) which failed with ; /Users/wander/myprojects/aoc/2018/day17.rkt:118:48: name: pattern variable cannot be used outside of a template ; in: name ; [Due to errors, REPL is just module language, requires, and stub definitions] I didn't understand the error message, and had no idea of how to move forward. I searched the error message and found [Greg Hendershott's Fear of Macros - Pattern matching](https://www.greghendershott.com/fear-of-macros/pattern-matching.html) (by the way, I am big fan of Greg). After reading his write-up, became easier to read the Racket documentation. That was my first macro: (require (for-syntax racket/syntax)) (define-syntax (define-unit stx) (syntax-case stx () [(_ name value) (with-syntax ([name? (format-id #'name "~a?" #'name)]) #'(begin (define name value) (define (name? other-value) (eq? value other-value])) (define-unit empty-unit #\.) (define-unit rock-unit #\#) (define-unit dry-unit #\d) (define-unit water-unit #\~) Dude! I was so excited! I did my first macro and it wasn't that scare. I barely could sleep because I did something cool and I also wanted to improve my solution with a "more complex syntax". The next night, I did my second macro: (define-syntax (define-enum stx) (syntax-case stx () [(_ name (e v) ...) #`(begin #,@(for/list ([x (syntax->list #'((e v) ...))]