
In this code, why does the ~@
have no effect? I was expecting the 2nd case to behave like the 3rd case, not like the 1st.

IIRC ~@
is for splicing. Like:
(foo {~@ a b} ...)
is going to be:
(foo a b a b a b)
(however long a
and b
is)

I think you want {~@ . args.header}
?

oh, right! Well spotted! Now that makes sense :slightly_smiling_face: Thanks!

Side question: What’s your {...}
convention?

Oh, I just prefer to use {~...}
for stuff from syntax/parse
(~and
, ~?
, etc)

I think I got it from @lexi.lambda’s blog post.


Personally for me, it makes it easier to distinguish meta {template, pattern} from actual {template, pattern}.

Apropos, how do you pronounce ~@ and ~? As “splicing template insertion” and “only insert full template”?

Another syntax-parse question: It appears that attributes don’t ‘propagate’ well. In this example, even though we have access to the attribute the-id
in the syntax class two
, we can’t obtain the attribute hey
from x.the-id
even though it should be of syntax-class one
.
One solution is to explicitly bounce the attributes of syntax-class one
to syntax-class two
, but is there a way to avoid this?

“tilde at” and “tilde question mark” :smile:

I believe I asked the same question before, and the answer IIRC is no. You need to propagate it yourself.

I see, thank you. Probably by now I owe you a beer or two, or whatever beverage you enjoy :smile:

How about: (define-simple-macro (parse-two x:two)
#:with y:one #'x
y.hey)
(parse-two a)

Not automatic, but close.

Interesting. This forces a second parsing though I guess?

True.

(since i’m parsing lists, this can have a cost)

Note that it’s a compile time cost, which is usually not going to be a lot unless your program is 1M lines long.

I decided to use /context
instead, as I find it more specific.

Doubling the parsing cost of a define
form is probably not a benign issue though. I kind of intend to eventually use this form everywhere from now on.

I’m not sure what your mean. You’re always using some custodian. Is the question whether having lots of them is expensive?

@curiouslearn has joined the channel

Hi! First time post here. I am exploring the plot
package in Racket. I am very new to racket in general…started looking at it this week. The plot package looks great. Here is my question.
When I create a plot, the ends of the plot look like they got cut. I was having the same issue when I was playing with the pict
package. But the inset
command in the pict
package solves the problem. Is there something similar for the plot
package? Essentially, I want some margin around the plot, so that it does not like it got cut. I suppose one can output a pict using the plot package and then use inset with that pict before saving to a file. But I was wondering whether there is a setting in the plot package to create than margin/gap around the plot. Thank you. Hoping to use Racket more and more for my work.

Hi Welcome!
I have a hunch. But can you say a little more about where you see the “cut”. Maybe paste a screenshot here?

In that use case, I would worry about performance too.

Thank you @soegaard2. Here is the picture. Please look at –1 at the bottom and 4 at the top. They have been rendered fully. I am also copying and pasting the code.
#lang racket
(require plot/no-gui)
(plot-x-axis? #f)
(plot-y-axis? #f)
(plot-x-far-axis? #f)
(plot-y-far-axis? #f)
;;(plot (function sin (- pi) pi))
(define sqrplt (plot-file (list (y-axis 0 #:labels? #t)
(x-axis 0 #:labels? #t)
(function sqr -2 2)
(lines (list '(-2 1) '(1 2) '(3 1)))
(point-label '(0 1) "Plot" #:size 24 #:color "steelblue"))
"sqplot.svg"
#:y-min -1))

I see the same thing when plotting directly inside DrRacket: #lang racket
(require plot)
(plot-x-axis? #f)
(plot-y-axis? #f)
(plot-x-far-axis? #f)
(plot-y-far-axis? #f)
;;(plot (function sin (- pi) pi))
(plot (list (y-axis 0 #:labels? #t)
(x-axis 0 #:labels? #t)
(function sqr -2 2)
(lines (list '(-2 1) '(1 2) '(3 1)))
(point-label '(0 1) "Plot" #:size 24 #:color "steelblue"))
;"sqplot.svg"
#:y-min -1)
Definitely a bug. You should file an issue here: https://github.com/racket/plot/issues

The immediate fix is to plot a little more: #lang racket
(require plot/no-gui)
(plot-x-axis? #f)
(plot-y-axis? #f)
(plot-x-far-axis? #f)
(plot-y-far-axis? #f)
;;(plot (function sin (- pi) pi))
(define sqrplt (plot-file (list (y-axis 0 #:labels? #t)
(x-axis 0 #:labels? #t)
(function sqr -2.1 2.1)
(lines (list '(-2 1) '(1 2) '(3 1)))
(point-label '(0 1) "Plot" #:size 24 #:color "steelblue")
)
"sqplot.png"
#:y-min -1.2
#:y-max 4.1))

Note that the automatic label computation wants to label –2, 0, 2, 4. So the label at –1 disappears abouve.

Thank you @laurent.orseau. Yes, I saw it in DrRacket too. Maybe the issue in case of pict
package is also a bug. Will file a bug.

If you need the label at –1 you will need to make one explicitly.

Thank you @soegaard2. I will try that workaround for now.

The options available for the decorators are seen here. But … I must be missing something - what do if I want to draw a “point label” with no point. Errrr. I mean if I just want to draw the label?

I have not tried it. But will making #:point-size 0
do the job?

That would work.

There’s also ’none in point-sym: https://docs.racket-lang.org/plot/contracts.html?q=point-sym%2Fc#%28def._%28%28lib._plot%2Futils..rkt%29._point-sym%2Fc%29%29

During make both
, I get this error:
/Library/Developer/CommandLineTools/usr/bin/make sysinfer3m
./racket3m -cqu ../../bc/mksystem.rkt system.rktd "gcc -E -I. -I../../bc/include -I../../bc/src -I../../bc/../version -g -O2 -DOS_X -D_DARWIN_UNLIMITED_SELECT -fno-common -DUSE_SENORA_GC -Wno-nullability-completeness ../../bc/src/systype.c" "bc" machine "./racket3m" "./racket3m"
make[13]: *** [sysinfer3m] Killed: 9

Rerunning doesn’t fix the issue. Does anyone (@mflatt?) know what could have caused it, and how to fix it?

What architecture?

Mac M1

Does deleting racket3m manually solve the problem?

That doesn’t solve the problem, but discarding the whole bc
directory does (well, it’s still not finished building, but it gets past that step).

Thank you!

Another “koan,” this time with continuations. I thought I understood things, but I had to twist myself around to get this to work: #lang racket
;; 3. Prompts, aborts and continuations
;; Exceptions are powered by an underlying mechanism of prompts, aborts and
;; continuations. If we take a simplified analogy with Algol family languages,
;; 'prompts' in use are a generalization of 'try..catch', 'aborts' are a
;; generalization of 'throw', and continuations are a generalization of some
;; WIP state of computation. These three concepts power the ability to divide
;; up Racket's work, then jump to the dividing lines at the author's
;; discretion.
;;
;; For helpful visual aids, see <https://stackoverflow.com/a/29838823/394397>
;; Complete and then capture this foldl computation such
;; that you may apply it using only a list.
(define *captured-fold*
(lambda (l) (fail "Redefine *captured-fold* to pass the test.")))
This was the template I had to fill in: ; (call/cc
; (lambda (k)
; (foldl (lambda (a b) "?") "?" '())
; (void)))
Here was my eventual solution (call-with-continuation-prompt
(λ ()
(foldl
+
0
(call-with-composable-continuation
(λ (k)
(set! *captured-fold* k)
'())))))
(check-eqv? (*captured-fold* '(1 2 3)) 6)
But I tried using call/cc
and nested call/cc
or call-with-composable-continuation
and kept getting continuations that looked like they returned void (no print at repl) or multiple values (like 0 0 at repl or 0 6 at repl). Further, the check-eqv?
stayed silent, even if I changed it to (check-eqv? … 7)
on all of my attempts except the one shown… color me very confused

Is this the same as the foldk
here: https://sidburn.github.io/blog/2016/05/07/cps-fold Note the comment about implementing foldk
in Scheme with call/cc.

@soegaard2 so the continuation-prompt seems necessary? Otherwise, calling *captured-fold*
would jump out of check-eqv?
, right? Hm, maybe I need two call/cc
s to get this right.

I like your solution. It seems call/cc
often captures “too much”.

Especially if tested in the repl.

Yeah, two cc’s didn’t make sense. I think you’re correct re: “too much”—the guide says A more traditional continuation operator in Racket (or Scheme) is call-with-current-continuation, which is usually abbreviated call/cc. It is like call-with-composable-continuation, but applying the captured continuation first aborts (to the current prompt) before restoring the saved continuation. And each REPL interaction implicitly has a prompt. But I still wonder at having to compose the prompt and the composable continuation to avoid ignoring check-eqv?
…

Good point. I mean creating and freeing many of them a lot. Like a lot of possibly short lived custodians.

Hmm, when I wrote my initial question I didn’t have a real intuition of the costs of custodian start up and shutdown. Now I’m thinking that startup is fairly fixed (allocation + registration in the parent custodian) and shutdown is (roughly) proportional to the number of resources managed by the custodian, but the clean up happens asynchronously to the user threads?

I believe that’s the case.

Racket users video meetup - Jan 9, 2021 at 8pm CET, via Gather Town. https://gather.town/app/wH1EDG3McffLjrs0/racket-users\|https://gather.town/app/wH1EDG3McffLjrs0/racket-users There’ll be (optionally) lightning talks and the paper for discussion (optional pre-reading) is the featured paper: Macros for Domain-Specific Languages. https://drive.google.com/file/d/14XMPoRJgrmAJ934qDZSCQ8p8_rvNEe0b/view?usp=sharing\|https://drive.google.com/file/d/14XMPoRJgrmAJ934qDZSCQ8p8_rvNEe0b/view?usp=sharing

Is Mac OS 64-bit Apple Silicon build cs or bc ?

Interesting. Seem like a bug I should report?


CS

All snapshot builds are CS unless labeled “BC”.

A couple of weeks ago, I complained about syntax-parse
parsing literal ids as identifiers or expressions. Although this can, sometimes, be prevented by carefully ordering alternatives, it’s not a general solution. I came up with a simple solution that prevents this behavior in all cases. {begin-for-syntax
(struct syntax-literal ()
#:property prop:set!-transformer (λ (self stx)
(raise-syntax-error #f "not allowed as an expression" stx)))
(define-syntax-class safe-id
#:description "non-literal id"
#:attributes ()
[pattern {~and _:id
{~not {~var _ (static syntax-literal? #f)}}}])
(define-syntax-class safe-expr
#:description "expr that is not a literal"
#:attributes ()
[pattern {~and _:expr
{~not {~var _ (static syntax-literal? #f)}}}])
}

thanks everyone :+1: the Forge developers say they learned many things … I hope that means they’re successful now :white_check_mark:

@mflatt Does this look like a bug to you?

This only works if the literal isn’t going to be bound to something else.

In general this behavior is just ordered pattern matching and I recommend not trying to work around it

If you really need literals that aren’t expressions keywords might be a better solution

The only reason that I’m not using keywords is that they don‘t look great, in my particular use case, because the keywords would be #::
, #:=
, #:⇒
, #:...
&c.

I’m sorry, I should‘ve specified that I was only talking about literals that are used exclusively as a token, like ...
.

We ought to write this advice down in the racket docs somewhere

Oh, a really useful approach I forgot to mention: if they want something interactive to show up in the drracket REPL, they can implement a snip%

anyone else seeing “invalid memory reference” errors? I don’t think I’ve ever seen those before, but some are popping up when I run tests. I’m on 7.9 CS. (I can give more details, or make a ticket, but I thought I’d first check whether others are seeing this kind of thing.)

it’s an error message leaking out from Chez Scheme into Racket. So there are many possibilities (https://github.com/racket/racket/issues?q=is%3Aissue+invalid+memory+reference) and is worth figuring out.