Made one for and
and or
, haven’t gotten around to the contract cases yet https://github.com/jackfirth/resyntax/pull/66
I made some changes to the plot package to allow controlling the aspect ratio of the plot area — the main use for this is to make circles look like circles, but it could also have other uses, as it is an additional way to control the plot layout. I prepared a pull request and I welcome comments both on the design and the implementation of the feature. Let me know what you think:
I get a 404/uncaught exception for the pollen website; I think http://pollenpub.com\|pollenpub.com redirects to the same place as https://docs.racket-lang.org/pollen/
The pollen build failed because markdown failed because sexp-diff was broken. The sexp-diff registration has been fixed, but it looks like it needs a checksum bump to trigger updates at clients (probably including pkg-build), so I’ve asked the maintainer to do that.
unfortunately this means that make
is currently broken for me ;(
It’s unfortunate that one broken package can have this much impact
I’m concerned that (or/c (or/c a b) c)
and (or/c a b c)
may be distinguishable by contract-name
, making this not an “obviously correct” transformation.
I think that’s very unlikely to break real code so I’m not too worried about it. There’s lots of ways that refactoring rules can produce things that are technically distinguishable via some sort of metadata extraction, like object-name
or just straight-up reflection on the source code. My position is that if it’s something that a reasonable equal?
implementation wouldn’t distinguish between, it doesn’t break real code, and it doesn’t change side effects like evaluation order, then it’s fine.
For +
though… I’m a lot more hesitant to always suggest rewriting (+ a (+ b c))
to (+ a b c)
. Floating point rounding issues are far from hypothetical.
You may try to email @michael.ballantyne he’s not often on Slack but can probably answer your questions.
I have started making a release specific git branch and that is the one I register on the package site, so then if I break the main branch I commit to it won’t break the published package.
I think you’re right that few transformations on code will be perfectly safe since many realistic Racket projects will make essential use of reflection or replacing one compiler with another. In fact, it’s more than hypothetical: Every developer who uses Resyntax is using at least one tool that splits these hairs. :-p
To me, that makes it obvious that every change Resyntax makes goes against another of your goals for new rules by being at least a little “controversial.” I’m not sure of the purpose of that goal; I disagree with a lot of the rules you already have in there, like using define
instead of let
, but I don’t think you should stop making a tool that’s useful for one person just because someone else would find a different thing useful.
I’m not seeing the distinction you’re making about floating point. If someone wants to draw fine distinctions about what to do with precision, they should probably be using names or imports that convey that intent explicitly so that even their human collaborators know what their intent is. And with explicit distinctions present in the code, any reflection shenanigans they use (including a refactoring tool like this one) can know which instances of addition are associative and which ones aren’t.
> If someone wants to draw fine distinctions about what to do with precision, they should probably be using names or imports that convey that intent explicitly so that even their human collaborators know what their intent is. The distinction is that people don’t do this today. There is plenty of real code that’s sensitive to rounding semantics and purposefully written in certain ways, and it uses the same numerical functions as any other code. Mostly I know this code exists because of my familiarity with the Herbie project, which analyzes numerical code and suggests ways to rewrite it to minimize rounding error.
Creating two versions of the numeric operators, one where resyntax rewrites are allowed and a second set of operators for people who want to specify “this is sensitive to rounding, if you edit this please beware” is certainly an option. But for backwards compatibility the existing racket operators would probably have to be the ones that tools aren’t allowed to touch. So I don’t think it’s worth the effort just for a handful of arithmetic refactoring rules.
As for the “controversial” rule: it’s entirely in the eye of the beholder and is subject to the whims of community consensus (or lack thereof). To me, a controversial fix is a fix that I get a lot of pushback on when I send pull requests to people.
Yeah, the existing operators aren’t necessarily the ones that can be treated as associative. I think there’s a lot of wiggle room without clear answers. The intent information they convey is basically “I might not have decided whether I’m paying attention to floating point precision here or not, and I also might not have decided whether the addition I’m using is associative or not. It’s probably associative-ish since it’s a familiar-looking manipulation of number-ish things. But what I’m doing is also likely to coupled to specifics about Racket’s current representation of numbers (maybe even tied to assumptions that hold in only BC or only CS).”
Anything that conveys a more specific (or differently vague) set of intentions is a different operator.
I was basically responding to the idea of not refactoring +
by saying that at least one refactorable variant of +
can exist. Depending on how much people think of Racket numbers as number-like, maybe it’s even the existing +
.
@rokitna: btw, I’m curious why you prefer not to convert let
to define
. Because you think parendown suffices for reducing rightward drift?
I could definitely see a use for refactoring +
in teaching languages
since if you’re relying on IEEE rounding behavior in a teaching language… what in cthulhu’s name are you doing
I’m not convinced yet in partial expansion as a way of making DSLs. It seems like reflective shenanigans to me; macros that perform partial expansion may get out of sync with each other’s interpretations of various operations. In object-oriented terms, they’re trying to ascribe semantics from outside rather than using the object according to its interface.
I think something like rightward drift is a syntactic concern that arises in all kinds of DSLs and should probably be solved uniformly by whatever part of the system deals with text. Parendown is one option, but I do respect that it isn’t a very comfy one to use in DrRacket. :-p I think another option would be to treat block statements as their own kind of macro DSL like match
patterns and require
forms rather than lumping them together with expressions.
have you seen that recent paper on making DSLs with local expansion?
I haven’t seen it yet, but I do now. “Macros for Domain-Specific Languages,” right? What about it?
It’s a way to ensure that macros which implement DSLs in terms of local expansion over core languages can cooperate with each other without stomping on each other. I’m fuzzy on the details, but my understanding is that today, various DSLs like match
and require
use weird bespoke indirect versions of local expansion, because they need to “fully expand up to a custom core grammar” and then do postprocessing. And the paper provides a way to make that much less ad-hoc, more rigorous, and amenable to more cooperation between separate DSLs.
Yep, happy to answer questions via email () or dm here.
Is the package building server doing OK? Resyntax was updated 17 hours ago, which is on March 8, 9am UTC. I don’t know what timezone the package building server uses, but “The time is now Sunday, March 7th, 2021 12:47:37am” in https://pkg-build.racket-lang.org/server/built/install/resyntax.txt suggests that it haven’t built a new one.
^ @mflatt @samth
I’m sorry, there are a lot of topics here that would he interesting segues, but I’m not sure if any of them are what we’re already talking about.
So I don’t know if I follow what you’re going for.
Oh, just idly wondering if that might address your thoughts about macros using local expansion and getting out of sync with each other.
Looks like pkg-build spent a lot of time on the last round (on the order of a day), maybe some bad effect due to failures, and that makes it wait a relatively long time before trying again. It will try again sometime over night.
Something that would keep code-walkers from getting out of sync is if macros returned encapsulated objects that could only be code-walked according to the ways they were positively designed to be. Breaking encapsulation is sometimes helpful for debugging and such, but it should be easier to distinguish this kind of extra access and control it.
It seems like the encapsulation I want is hard to achieve under Racket’s approach to hygiene, where the expander itself code-walks a macro’s entire output to toggle the presence of the macro-introduction scope. At least not without adding yet more features to Racket’s system, such as some kind of generic interface for “please traverse yourself to flip this scope.”
I wonder if I should file an issue for that idea. Could work well. :)
@cadel.watson has joined the channel
@casparpopova2023 has joined the channel