
better summary messages now

This is truly amazing. Fantastic job! There’s still room for nitpicking fortunately :grin:

(like the let*
turned into define
+let
for example)

ah you mean that one case where something like (define (f ...)
(let* ([x ...]
[x (... x ...)])
...))
got turned into (define (f ...)
(define x ...)
(let ([x (... x ...)])
...))

yep

I think it’s… not worse, per se, but yeah it doesn’t seem worth the churn

Personally I prefer the first one

interesting case where this: (let* ([dest-file (if (string? dest-file) (string->path dest-file) dest-file)]
[renderer (new render%
[dest-dir (and dest-file (path-only dest-file))]
[refer-to-existing-files use-existing?]
[css-path 'inline]
[script-path 'inline])]
[ci (send renderer collect (list doc) (list dest-file))]
[_ (send renderer transfer-info ci (resolve-info-ci (xrefs-ri xrefs)))]
[ri (send renderer resolve (list doc) (list dest-file) ci)]
[xs (send renderer render (list doc) (list dest-file) ri)])
was changed to this: (let ([dest-file (if (string? dest-file) (string->path dest-file) dest-file)])
(define renderer
(new render%
[dest-dir (and dest-file (path-only dest-file))]
[refer-to-existing-files use-existing?]
[css-path 'inline]
[script-path 'inline]))
(define ci (send renderer collect (list doc) (list dest-file)))
(define _ (send renderer transfer-info ci (resolve-info-ci (xrefs-ri xrefs))))
(define ri (send renderer resolve (list doc) (list dest-file) ci))
(define xs (send renderer render (list doc) (list dest-file) ri))
(the (define _ …)
form is what’s interesting to me here)

what do you mean?

The _
was in the let binding because there’s no way to interleave plain expressions in let bindings and evaluate them for their side effects. So I think the let-to-define
migration should recognize that case and turn that binding into an expression instead of a definition.


if you’re familiar enough with the refactoring rules DSL, you could attempt writing a rule for that :p

That seems a little risky, but maybe

I want to, but no time right now

anyway: with this new pull request, I seek to banish let
from scribble forever! https://github.com/racket/scribble/pull/294

(actually several uses of let
remain but hyperbole is fun)

(define _ …)
just looks so bizarre. It’s like seeing a fish out of water.

True


Personally, if it doesn’t unindent the body, I’d leave the whole thing alone. Partial conversion is not worth it, IMO.

I concur

Unindenting the right-hand-side expressions seems worthwhile to me, especially in cases where some of the let bindings are to lambda expressions.

yeah, but the single let reads uniformly, whereas now you have both define and let

I agree with @notjack partially. There are cases that are worthwhile

But for some, I really disagree


^ this one should not be converted IMO

Oh yup that one shouldn’t

let*
is an idiom that says, I will keep evolving this variable

can you leave a comment to remind me to fix that one

yep

I don’t know if I’ll implement that special case in the tool since it seems like a lot of work for not much benefit, but I certainly don’t plan on making that fix purposefully

on this point: I kind of like that in the refactored code, whenever I see let forms I can think “oh there’s some sort of shadowing going on here”

I think there’s a simple rule for when partial conversion should be done: when it actually decreases the line width
Compare:
(let ([@expr (if x (litchar/lines (car x)) "")]
(define @expr (if x (litchar/lines (car x)) ""))
So I do think https://github.com/racket/scribble/pull/294/files?diff=split&w=1#diff-6339e804a7deeaf21b376c41eb4afd3a61b61b341b42f9bc748d5c19935f735aR99 should not be converted.
Removing lambda
, on the other hand, is totally worthwhile.

what if there’s a clause that doesn’t decrease the line width, then a clause with a lambda, then an unconvertible clause?

Can you prove that the clauses has no side-effect, and thus clauses can be reordered? :stuck_out_tongue:

not effectively :p

in my own code I don’t use let/let*/letrec at all, so, somewhat biased

I want define*
(https://github.com/racket/rhombus-brainstorming/issues/46) in Racket right now :disappointed:

god, same

redefine
seems like a much better name though..

The best name is let
:slightly_smiling_face:

oh like, (let x expr)
? now that’s an idea

yeah

like ML basically?

yes

it’s kind of weird to have these two forms just be synonyms with nothing to make it clear why they’d be different (besides history)

(assume-under-the-right-circumstances-that x 3)

(without-loss-of-generality-let x 3)

You can go Pyret style here. No need for let
with a body. If you need one, you write:
(block
(let x 1)
body ...)
instead of:
(let ([x 1])
body ...)

(although Pyret does have let
with body)

Yeah I definitely think block
is massively underrated

Well, I didn’t mean block
in Racket

I’m speaking very nonspecifically :p

It’s a hypothetical form that controls scope, but yes, Racket’s block
can work too

@notjack what was broken? The latest commit looks like a wrong direction to me.

No idea. Saw an error in the CI logs that said something was wrong in that file, so I reverted it.

The nice thing about automating these changes is I don’t have to have any particular attachment to them. I can always just rerun the tool and try again later.

Definitely worth investigating the bug, and also check the previous PRs if the same mistake occurs.

I’m guessing I just clicked wrong when I was omitting some of the fixes that dropped comments. Lots of error-prone fiddling in the github desktop UI.

wouldn’t git clone
locally make your life easier? you can also test locally too.

yeah risky… the ordering of the expressions might matter so would need to make sure the _ position stays the same in the order of the expressions and it might look just as weird to have an expression in middle of a list of definitions.

Cool. Thanks for the help :)

Things I like about let
: It’s short. Even then, you don’t have to keep typing let
over and over; one form can do multiple bindings.

Things I like about define
: The “in” (as in "let
bindings in
expresions") is implicit, i.e. “the rest of the ‘block’”, “I don’t want to indent”.

Casual riffing on this: Why choose? Maybe I’d like a let+
form that takes a sequence of identifier and expression pairs, and an optional #in:
expressions tail.

Like idk: (let+ x 1)
(let+ y 2)
(+ x y)
(let+ x 1
y 2)
(+ x y)
(let+ x 1
y 2
#:in
(+ x y))

Yeah that ends up being a little “Clojure-y” by not wrapping each binding in parens, but it’s more just to keep them all consistent. Anyway I feel like those parens are more a crutch for not having syntax-parse
available. :slightly_smiling_face:

So I mean I like define
s lack of indenting, but code where I am typing or reading define
define
define
feels strangely “noisy” for an otherwise not-noisy language.

</opinions>

@greg I would again like to suggest that having racket-mode integrated with the package system would make my life better

you mean Emacs package system?

It’s on melpa, no?


no the racket package system

so that, for example, raco setup
compiles the racket-mode code

ah, I see

I’ve looked at this a few times and not found a great solution, but would be happy to look at it again.

one possibility would be to use raco pkg install
(or even raco link
) to make Racket aware of the Racket code in racket-mode

I bring this up because my typical racket-mode experience is: 1. start emacs on a racket file 2. try to run the buffer 3. nothing happens 4. I remember that I have to run racket-mode-start-faster again

Yes, I could do a raco pkg install --link
and raco pkg setup racket-mode
instead of a raco make
.

Just to make sure I understand your scenario, how would that help you? You’re doing an overall raco setup
(everything) in these situations and so it would do Racket Mode, too?

yes, exactly

I run git pull; make
, that bumps the Racket version number, the zo files for Racket mode are now out of date, Racket mode fails to start

That makes sense.

For me this is particularly problematic because it happens almost daily, because that’s how often the version has been changing recently

Yeah I do work with various Racket versions, but not as frequently as you. Also I don’t ever compile Racket Mode (except as part of testing, then immediately clean it).

Because it starts fast enough, for me.

ah, maybe I’d be happier without doing that

is there a command for removing the zos?

And if you make zos, ever, you’re kind of in that linklet version trap.

Which is the major drawback to that M-x racket-mode-start-faster
command.

racket-mode-start-slower

:slightly_smiling_face:

No, it’s going to be “look under your .emacs/elpa dir for the Racket Mode files, and rm the zos”.

Or package-delete Racket Mode, and package-install it again, should work.

[[ I wish Emacs package-install had a post-install step where I could do a raco pkg install && raco setup
`. But alas no AFAICT. ]]

https://racket.slack.com/archives/C06V96CKX/p1612889269069500?thread_ts=1612886725.064300&cid=C06V96CKX @samth This is the TL;DR I think.

Do that once, then never run racket-mode-start-faster
, again.

yeah that’s my plan

And let me know if you’re still having problems, happy to work on it more.

racket-mode might also be a good use case for https://docs.racket-lang.org/custom-load/index.html

Yes! I starred that a couple years ago and am constantly tempted to try using that.

The times I’ve had bandwidth to try it, I’ve just had bigger fish to fry. I might loop back to that in the near future.

Oops. More like 6 years ago. :eyes: https://github.com/greghendershott/racket-mode/issues/41#issuecomment-88718166

Does anyone know what the error failed to get self (2)
means when running a racket binary in a (non-racket) sandboxed way?


Is the path length longer than 1024 characters?

Thanks! It’s probably line 164 instead, but same thing

That buffer is smaller. 256.

It’s more likely that the executable is prevented from accessing /proc since it’s sandboxed

Right. Makes sense.

So the binary is calling /proc/self/exe to… execute itself?

Just to get the path, I think.

It might be a Chez thing. That would explain, not seeing it before.

right

Anyone knows if there could be a way around this?

Btw - I wasn’t paying enough attention to the code. It actually allocates a larger buffer if needed.

it’s a funny piece of code actually :smile: C never ceases to amaze me

The answer with 36 upvotes is worth a read: https://stackoverflow.com/questions/1023306/finding-current-executables-path-without-proc-self-exe

It seems complicated.

And yes - while (1) {...}
just looks wrong.

@greg some indentation questions: is it possible to configure racket-mode to change the indentation for this code (syntax-parse stx #:datum-literals (->)
[(_ (-> a b (c d)) ...)
#'(values (list (list a b c) ...)
(list (list a b d) ...)
(list (list a b (list c d)) ...))])
to: (syntax-parse stx #:datum-literals (->)
[(_ (-> a b (c d)) ...)
#'(values (list (list a b c) ...)
(list (list a b d) ...)
(list (list a b (list c d)) ...))])

FWIW, if you put #:datum-literals
on a new line, it will indent fine

That’s what I usually do with syntax-parse.

However you could change the indent for syntax-parse to the 'defun
style.

Either globally in your init.el
.

Or locally in a file, e.g. put at the end of the .rkt file: ;; Local Variables:
;; eval: (put 'syntax-parse 'racket-indent-function 'defun)
;; End:

Yes.

[whoops/superfluous/deleted!]

The file-local thing is just the usual Emacs thing for file-local value of a variable. You could think of it like a file-scope parameterize
:wink:

Ah, thank you guys!

That could also go in a project .dir-locals.el
for a project or team style of indent for custom or “standard” forms

@popa.bogdanp has a nice list of such functions/mechanism for adding them here: https://github.com/Bogdanp/.emacs.d/blob/929bff062e745ce750b9b783661c1b8202ff7961/init.el#L947

Oh I hadn’t seen that. Nice!

And the defun
style is pretty much a catch-all for “any number of things on the first thing, then other lines all body-indent”.

Hmm, I wonder if that should even be a default… not sure.

Probably not a new default in Racket Mode, it would change indent for existing things.

Anyway someday the “ideal” way would be for macros to tell tools about their indent. It might entail needing some kind of external database, akin to what scribble needs. And used for other purposes, too, such as finding external references to definitions, etc.

There’s a bit of discussion at https://github.com/racket/rhombus-brainstorming/issues/108

I’ll try to recompile racket after changing main.c to force it to use the generic path method USE_GENERIC_GET_SELF_PATH
, which merely looks at argv[0]

Is the ‘new’ package/collection system still using any feature from planet
somehow?

No, I don’t believe so.

thanks. My embedded executable appears to be trying to setup some things in planet/config, and I was wondering if that was needed at all

(trying and failing due to being sandboxed)

planet is still built in, if that’s what you’re asking

i believe that code probably only looks at some environment variables

I think it’s running collects/planet/config.rkt, which contains a call to find-system-path
, which fails

ah, it appears I can set PLTPLANETDIR
to something non-empty to avoid the call

so I guess if it’s not used it should be safe to give it some fake value

Quick question - I’ve been reading through Racket2/Rhombus - is feedback from industrial programmers useful at all?

I’m not entirely certain about the goals of the project; so I don’t know if my opinions on any of the issues are useful in any way.

I’m pretty sure all opinions are welcome. It can be helpful to provide some context about yourself and how you use Racket, but the core team is very open minded about making it work for everyone, so I don’t see why your feedback would not be useful :slightly_smiling_face:

Definitely. I’m a bit more industry-focused than most racketeers and it gets lonely :p

I had a student using the Beginning Student language report an error of “define-struct: struct name must start with a lower case letter”. I could not replicate it. They provided a screenshot, and I noticed they were running a snapshot build from January 3. They said that was advised for Mac M1 owners. I have asked them to reinstall in the hopes that the glitch was fixed in the intervening month. But now I’m wondering how many students are running on suspect builds from the start of term. Will 8.0 support the new Macs?

Yes, 8.0 includes an M1-native build.

At first, the 7.9 Intel build did not run on M1 Macs, but then Apple improved Rosetta2. The 8.0 Intel builds also run on M1 Macs, just in case that’s ever relevant.

Meanwhile, it looks like the define-struct
issue has not changed in the snapshot builds, so going back to v7.9 is probably the right option for your student — and we should take down the snapshot recommendation on the download page.

Thanks, Matthew, I will advise this.

Confusion about the goals seems common. I need to reread https://github.com/racket/rhombus-brainstorming/blob/master/README.md\|https://github.com/racket/rhombus-brainstorming/blob/master/README.md and the linked resources as I’m not sure.
My understanding of the broad project goals, and I’m not part of the racket team (I’m an outsider), is; 1. Rhombus will be implemented in Racket (Rracket isn’t going away, and will continue to evolve) 1.Rhombus will be a default alternative syntax. (I think this means you open DrRhombus the first time you get #lang rhombus 2. Rhombus will a friendly syntax version of Racket. not a lisp. and infix binary operators. 3. Rhombus intended to have the full power of racket (macros, gradual types, full interoperability with racket, native code compilation, all libs/packages and toolchain) 4. Rhombus should have the capability to freely mix racket and rhombus modules, as well as other languages in the racket ecosystem
<<I welcome correction>>
All the above is my opinion. If I have misunderstood or misinterpreted it is my fault.
My understanding is the perspective of professionals is most welcome. (I’m not a developer, but I work for a small ISV.)

I realized that the Rhombus README doesn’t really say whether or not participation from “ordinary Racket users” is “welcomed”, so I opened a pull request https://github.com/racket/rhombus-brainstorming/pull/155

I have a student who is running 7.9 [bc] and find-exe
says “can’t find Racket executable for variant 3m”. Any ideas what might cause this?

They had a homebrew installed 7.4 and installer installed 7.9 at some point which may have been causing problems

OK, resolved. Seems like the brew install got in some bad partially uninstalled state, but after removing that and going with an installer, things are better.

When defining a control flow abstraction, e.g. call-with-my-exception-thrower
, should a fresh continuation prompt be made for each invocation of the abstraction, or is it sufficient to define a single my-exception-prompt-tag
?
