[racket] More macros...

From: Danny Yoo (dyoo at hashcollision.org)
Date: Mon May 12 19:16:53 EDT 2014

On Mon, May 12, 2014 at 3:17 PM, Eduardo Costa <edu500ac at gmail.com> wrote:
> Hi, Danny.
>
> I checked your code, and it indeed answer part of my questions. The other
> part refers to the tokenizer.  As you can see, the macro hp does not require
> that the arithmetic operators be separated by space. For instance,
>
>> (hp 3*4+5*6)
>
> works fine.  To achieve this in Racket, I used two tricks. In the case of
> hp, I wrote the expression into a string:
>
> (define-for-syntax (tkn stx) (with-output-to-string (lambda()
>                              (write (cdr (syntax->datum stx))) )))
>
> Then I used separate to break the string in tokens. Since I wanted to
> preserve the possibility of using the minus sign ( - ) in the name of
> variables, I require that the minus operator be surounded by spaces. Thus
>
> (hp 3*4*(4 - 5)*7)
>
> Writing to a string works perfectly well, but I feel that it is not elegant.
> Therefore I tried another trick: I just created a language similar to the
> $-language described in the Racket documentation. However, the $-language
> has a problem: I cannot use it in the read-eval-print loop.
>
> I am enclosed the px language to this email. I hope you can tell me how to
> make it work in the drracket repl and in the racket -il xrepl. I guess that
> the solution has to do with #%top, but I am not sure about it.
>
> In order to install and test the px language, all you need to do is to
> expand the archive px.tar.gz inside
>
> ~/.racket/6.0.1/collects/
>
> This will create a ~/.racket/6.0/collects/px folder, that contains the px
> language. There is an examples.rkt inside the px folder. The examples.rkt
> source file contains many examples and the documentation of the px language.
>
> Please, if you discover how to make the px language work inside the repl, or
> how to improve it in any way, let me know.
>
> By the way, the px language is used to introduce Lisp to students who are
> scared of parentheses. We discovered that after learning the px language,
> the students start accepting the full parenthesized Lisp.
>
>
>
>
>
> 2014-05-05 14:22 GMT-03:00 Danny Yoo <dyoo at hashcollision.org>:
>
>> Hi Eduardo,
>>
>> You might find the following useful or interesting:
>>
>>
>> http://planet.racket-lang.org/package-source/dyoo/infix.plt/1/1/doc.txt
>>
>> In particular, the implementation's in the private subdirectory:
>>
>>
>> http://planet.racket-lang.org/package-source/dyoo/infix.plt/1/1/private/
>>
>> The code is a little stale (I wrote it several years ago), but it
>> might still have some utility for you.
>>
>>
>> Good luck!
>
>



Hi Eduardo,


My apologies; I can not look at this at this promptly due to my day
job.  Can you resend to the racket-users mailing list?

>From a quick and dirty look at your response: it's possible to put an
intermediate stage in the tokenizer so it splits the atoms like "3*4"
into three distinct elements, so that for the most part you avoid
writing the whole program to an intermediate string.

The reason why you want to avoid the conversion to the strong is
because, as soon as you write to string, you lose a lot of location
information that used to be there.  You'd rather want to preserve that
location information as much as possible because otherwise error
messages become less useful.


As another example of this kind of thing, see how ragg does some of
its parsing of grammars in its s-exp branch:

    https://github.com/dyoo/ragg/tree/sexp/ragg/sexp

so as to make things like:

    https://gist.github.com/dyoo/4658351

work.  Part of that process is taking a syntax and breaking it down into tokens:

    https://github.com/dyoo/ragg/blob/sexp/ragg/sexp/stx-to-tokens.rkt#L28

It tries to be very careful about maintaining location information.


You'll see that there's an intermediate phase in the s-exp "tokenizer"
that looks at the individual identifiers and digests them:

    https://github.com/dyoo/ragg/blob/sexp/ragg/sexp/stx-to-tokens.rkt#L111

and I suspect you can do something analogously in your own
implementation.  That is, you can limit the scope of the damage of the
lossy-coercing so that it's done at the point of certain identifiers,
and even then, you'll have the overall location of the identifier in
hand so that the damage isn't too bad.

Posted on the users mailing list.