Re: [racket-users] I wrote my first macro ever!

2019-05-03 Thread Jérôme Martin

> 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!

2019-04-30 Thread David Storrs
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!

2019-04-28 Thread wanderley.guimar...@gmail.com
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) ...))]