
AFAIK that’s not possible with structs & generic interfaces, but it’s possible with the class system (https://docs.racket-lang.org/guide/classes.html#%28part._.Interfaces%29)


Ah, it looks like the thing to do is use contracts which check for method availability.

@pmamatsis has joined the channel

With syntax-parse
, is it possible to insert a user-defined keyword, probably from format-symbol
? Say I want to produce (define (foo #:a [a 1] #:b [b 1]) ....)
from (my-define (foo #:? [a 1] #:? [b 1]) ....)
The problem is that format-symbol
produces a symbol and thus this would insert \|#:a\|
instead of #:a

Can you use symbol->keyword
on the desired symbol?

Only string->keyword
exists in racket
, and it generates… a symbol :slightly_smiling_face:

ah, but actually that works (converting the symbol to a string first, then using string->keyword
). Thanks!

That teaches me to check the docs before spouting off an answer, but I’m glad there’s a solution :smile:

Hi All. Instead of reviving my blog, I have written the first, few sections on something that hopefully will become some sort of macro tutorial. I have attached the first sections.
Feedback is needed - both on the contents and on the typography - not to mention on my english grammar.

Two Qs on this video that I would love to know the answers to: • Why #,
(and the splicing counterpart) in the #
templates? Is
,not enough because of the
#?
• Is
(define foo #f)really the best way to handle
#:literals (foo)in
syntax-parse? That seems… odd… at best, to me. An example that shows it is unbound (
(syntax-parse #’(foobar x) #:literals (foobar) [(foobar n:id) ’ok])), but then how to properly bind it without either
(define-for-syntax foobar #f), which the video doesn’t use, or
(define foobar #f)` which seems to pollute the module name-space?

> Why #, (and the splicing counterpart) in the # templates? Is , not enough because of the #?
For one, the template (things inside
#’) could contain
`and
,` already, so using a new notation looks better to me.

define-for-syntax
wouldn’t work because we need a binding to exist at the current phase, but define-for-syntax
operates on a higher phase.

You don’t need (define foo #f)
. (define-syntax foo #f)
also works.

What format of feedback would be most useful to you? Slack comments, notes on the document, a PDF about the document, or something I have not thought of?

Hm. I like (define-syntax foo #f)
slightly better? But it still seems wrong to me. The point of #:literals
seemed to be to treat things, well, literally. Not by looking them up in an environment of bindings

Unfortunately, you do need to pollute the namespace.

You can use #:datum-literals
instead of #:literals
to recognize literals by their symbolic value rather than by binding.

Re: quotes, I see in my syntax matching (vim) there are unquote forms for both #,
and ,#
—are they different?

Definitely different

#,(abc)
translates to (unsyntax (abc))
. ,#(abc)
translates to (unquote #(abc))
.

sighs I really thought I was getting the hang of it. That does make sense, though.

- The forms quasiquote
and unsyntax , are for producing lists:
(foo ,x). The pair quasisyntax #and unsyntax #, belong together. If you want to create a piece of syntax representing
(foo ,x) you don’t want comma to mean unsyntax.

@popa.bogdanp thanks, #:datum-literals
worked w/o having a binding in place!

I think #:literals
is kinda misleading. It doesn’t recognize literally in that sense, but recognize by binding.

Depends on the type / amount :slightly_smiling_face:
If it on the typography (where to add space etc) drawing on the pdf might be the easiest. For typos a slack comment is fine.
My email is if you have longer comments.

Oh - Missed the thread!

From the point of view from the pattern match (which sees everything as a pattern variable) it is a literal :slightly_smiling_face:

#:literals
was definitely confusing to me early on because of that. I prefer using it now over datum literals because you get something concrete to refer to in code and docs, and it lets you provide descriptive error messages when a literal is used incorrectly.

It looks like http://mirror.racket-lang.org\|mirror.racket-lang.org (129.10.116.85) has been down for at least a couple of hours. Requests are timing out.

Failure on GH to download Racket: https://github.com/Bogdanp/racket-wasm/actions/runs/451161748

And a ping from my local machine:
$ ping 129.10.116.85
PING 129.10.116.85 (129.10.116.85): 56 data bytes
Request timeout for icmp_seq 0
Request timeout for icmp_seq 1
Request timeout for icmp_seq 2
Request timeout for icmp_seq 3
Request timeout for icmp_seq 4
Request timeout for icmp_seq 5

I certainly like this approach better than starting with the automagical define-syntax-rule
.
You should increase the text-width and make sure that the two code lines that wrapped it in the textwidth

If you go the tutorial way, you should link to the other tutorials on macros (Greg’s, mflatt’s, the guide, etc.), and say how yours differs (in particular to greg’s)

> Macros can’t be used to change the lexical structure Maybe you could mention in the margin that this can anyway be done in Racket by changing the reader (à la "Can't be done in Racket" can't be done in Racket
)

All noted. Thanks for the feedback.

~Which two lines were too long?~ Ah! I see it now. That’s odd. It looks fine in the browser, but not in the printout. I wonder what caused that.

Did you print from html to pdf, or directly to pdf?

I printed to pdf from Chrome.

Maybe you need to change the page size?

A4 vs US letter stuff?

No. A4 all the way :slightly_smiling_face:

I certainly need to work on the “page media” part of my css. I am somewhat annoyed by some useful features not supported by Chrome.

For example “don’t break the page inside this element” is tricky.

This is the stylesheet. And chrome doesn’t support “avoid”.

I’ll check Safari and see whether it is better or worse.

It’s the same. But I realise now that the main text is narrower in the pdf than in the browser (80ish vs 88ish characters). So I understand why you suggested to use wider lines.

Thanks fr the alert! Various services hosted at NEU appear to be unreachable at the moment.

when generating standalone binaries, will racket cs binaries be smaller than bc?

No,.they’re typically larger

You should use literals-compared-as-identifiers (#:literals
) to match things that might occur in the same position as an expression. For example, cond
treats else
as a literal. If it recognized else
as a datum/symbol, then it would mishandle programs that had a variable named else
(especially if the value of the variable is #f
). Additionally, else
is defined as a transformer that always raises an error, so it is not a valid expression. Since else
does not overlap with the set of valid expressions, allowing the first part of a cond clause to be either else
or an expression doesn’t cause ambiguity. (In modern Racket, it would be more idiomatic to use a keyword there, since keywords are also not valid expressions.)

making a CLI application and is "-p" reserved for something?

":p" definitely is

ahh nevermind

another question, is there a version of map
that passes the index in the lambda?

By, “index” do you mean the position of the current item in the list?

yeppers

What are you using the index for? Generally, map
is used when the number of things in the list doesn’t matter.

using the index to branch operations, e.g i want map to apply to all elements in a list except for indexes 3, 5, 6

Ah, in that case, you may want to use one of the for
forms. It has features that make something like that easy.

Here is a <https://docs.racket-lang.org/reference/for.html?q=for#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._for%29%29|link to the documentation>. There are many variations of for
, depending on what you want to do, but they all work similarly.

(save-image img "temp\test.png")

how would i create a temp folder if it doesnt exist?

looking at the docs, there is create-folder
but that requires the dropbox
sdk…

ahh, make-directory

strangely when i type “directory” into the searchbox , it wasnt showing up

is there a built in function that makes a list of the same element N times? e.g (make-list 1 5) -> '(1 1 1 1 1)

i only see range
but that’s not what i need

make-list
and build-list
?

ohhhh

> (make-list 5 1)
'(1 1 1 1 1)

Keep in mind that all elements are shared

If you don’t want them to be shared, use build-list

You need to hit >>
a couple of times to find it

Cause there are more other relevant search result

Tangential question: why are there constructors for immutable collections where all the elements are the same? I don’t know the use cases.

Being immutable doesn’t meant it can’t be updated. But the updated version is another object.
So you can imagine a dynamic process where you start with '(0 0 0 0)
=> '(0 0 1 0)
=> '(0 0 1 2)
=> '(0 3 1 2)
=> '(10 3 1 2)
or something like that.

Ah, it’s for starting a collection from a “default” state.

Is there a way to attach an exception handler to a top-level form?

For example, wrapping a top-level define
.

I don’t think so, but you can workaround it easily I think

For example, the only exception that can be caused by top-level define
is arity mismatch, I believe

So you can transform (define x e)
to:
(define x (with-handlers ([... ...]) (let ([x* e]) x*)))

@kellysmith12.21 I think you’d need to make your own #lang if you wanted that

More generally, in fully expanded program, you can transform (define-values (x ...) e)
to (define-values (x ...) (with-handlers ([... ...]) (let-values ([(x ...) e]) (values x ...))))

For more context: I’m working on the implementation of my #lang
and, in particular, I’m working on implementing define
and let
. Since my language uses patterns, I could just use simple wrappers around match-define-values
and match-let
, &c. However, I wanted to provide more specific error messages, and that requires catching exceptions thrown by match
, then throwing a new exception that has the information I want to include.

While it’s easy to make my own match-let
, implementing my own version of match-letrec-values
or match-define-values
is tricky and requires me to extract pattern variables, which involves either borrowing a private procedure from racket/match
or rolling my own version, using local expansion.

My first thought is, are you sure you want to put exception handler everywhere? Wouldn’t it be better to install an error display handler instead?

Putting exception handler everywhere seems like going to cause a serious performance issue.

That was something I feared, but the error thrown by match
is unnecessarily vague, when used for binding things. For example, if a binding in match-let
fails, then the entire form is blamed, whereas I’d like to highlight the particular binding that failed.

it sounds like that could be a feature request!

perhaps consider filing an issue against that?

Hm, it looks like the kind of error I was trying to implement is a matter of taste. As a similar example, the snippet (let ([a (values 1 2)])
a)
throws an error, of course, but the entire expression is highlighted, instead of the binding pair [a (values 1 2)]
, which is the real cause of the error.

the entire expression is highlighted because you enable errortrace, right? If you disable errortrace, then probably nothing is highlighted.

Ah. I think I was getting a little too fancy with my errors, using https://docs.racket-lang.org/reference/exns.html?q=prop%3Aexn#%28def._%28%28quote._~23~25kernel%29._prop~3aexn~3asrclocs%29%29\|prop:exn:srclocs to allow DrRacket to highlight specific areas. But that’s probably not a good idea, if it makes the implementation convoluted or slow.

Currently prop:exn:srclocs
is also buggy in Racket CS, welp