popa.bogdanp
2021-3-23 08:15:01

I suggested DNS resolution might be a problem because I assumed you owned the server (and possibly made changes to DNS entries). That’s probably not what’s going on with GitHub, though :smile:


ryanc
2021-3-23 09:03:03

Beware, char-whitespace? recognizes more characters as whitespace than #px"\\s+".


laurent.orseau
2021-3-23 10:33:47

@greg Then Chrome using a newer version of http has more weight now :slightly_smiling_face: Not user which one Racket uses. HTTP 1.1?


sorawee
2021-3-23 10:52:41

I think this is an interpreter that does what you want

#lang racket (struct closure (x body env)) (define (interp p env dyn-env) (match p [(? number?) p] [`(λ (,x) ,b) (closure x b dyn-env)] [(? symbol?) (cond [(assoc p env) => cdr] [else (error 'unbound-id "~a" p)])] [`(let ([,x ,v]) ,b) (interp `((λ (,x) ,b) ,v) env dyn-env)] [`(println ,x) (println (interp x env dyn-env))] [`(,a ,b) (define a-val (interp a env dyn-env)) (define b-val (interp b env dyn-env)) (match a-val [(closure x body c-env) (define new-binding (cons x b-val)) (interp body (cons new-binding c-env) (cons new-binding env))] [_ (error 'not-a-procedure)])])) (interp `(let ([x 100]) (let ([f (λ (_x) (λ (_y) x))]) (let ([f* (f 0)]) (let ([x 200]) (let ([f** (f 0)]) (let ([_ (println (f* 0))]) (let ([_ (println (f** 0))]) 0))))))) '() '())


greg
2021-3-23 12:05:20

IIUC HTTP3 ~= QUIC ~= “HTTP connections and stream done via UDP instead of TCP”. I think the main motivation for this was data centers like Google can squeeze out another ~ 10% bandwidth. Plus other benefits like you can maintain an HTTP connection while hopping between transports like e.g. your mobile phone’s wifi or cell tower.


greg
2021-3-23 12:06:06

I think it’s probably fine for command-line tools’ defaults to still be HTTP 1.0/1.1 for approximately forever. :slightly_smiling_face:


greg
2021-3-23 12:07:26

I think if you really need a Racket web app to use HTTP3, that can be provided by the same reverse proxy server like ngnix that you’re putting in front of the raw Racket web server, anyway (for speed and for HTTPS and now also for HTTP3)?


greg
2021-3-23 12:08:14

But that’s just my incomplete knowledge, and opinions based on that. People like Jay or @popa.bogdanp or others may easily have better knowledge and opinions. :slightly_smiling_face:


greg
2021-3-23 12:10:37

Anyway. One “theory of the bug” I have is that Chrome is aggressive in expressing its preference for (say) HTTP3, and that causes a different path through GitHub’s CDN that turns out to be “fresher” wrt caching. idk.


badkins
2021-3-23 14:17:07

@ryanc I’m not familiar with the “Unicode "White_Space” property". Are you aware of any characters for which char-whitespace? returns #t that you wouldn’t expect to split on if you were “splitting on whitespace” ?


badkins
2021-3-23 14:18:09

maybe “OGHAM SPACE MARK” I suppose


badkins
2021-3-23 14:19:05

I think I’d still lean toward using char-whitespace?


badkins
2021-3-23 14:22:06

Argh. That does present a problem though given the default would technically change.


mflatt
2021-3-23 14:34:57

I think it makes sense to check for the 5 specific characters recognized by \s instead of using char-whitespace?. Even in the ASCII range, I see that \s omits #\vtab (for whatever reason) compared to char-whitesace?.


badkins
2021-3-23 14:38:54

Ok. I agree it’s a significant advantage to not change the default.


badkins
2021-3-23 15:14:10

@mflatt is it your understanding that #\page corresponds to “formfeed” ? For example: (define (is-whitespace? c) (or (eq? c #\space) (eq? c #\tab) (eq? c #\newline) (eq? c #\return) (eq? c #\page))) ; form feed The Racket regexp docs state \s “Contains space, tab, newline, formfeed, return”


mflatt
2021-3-23 15:18:24

Yes, ASCII 12 is variously know as “page break” and “form feed”.


ryanc
2021-3-23 15:19:53

Right, I meant it would be better to avoid changing the behavior.


greg
2021-3-23 15:41:51

I realized something. I was expecting the defining/providing module — the one with the contract-out — to be where the wrapper function is defined, once. (And the name isn’t apparent in the fully-expanded code of that defining module, was my confusion.)

But now, it occurred to me that it’s the requiring module where the wrapper function actually gets defined: contract-out provides macros that result in the wrapper function being defined there — in each importing module. Does that sound correct?


robby
2021-3-23 15:42:08

Yes


robby
2021-3-23 15:42:23

We don’t know the negative blame (so cannot build the wrapper) until we get to the use site


robby
2021-3-23 15:43:20

(There is an optimization that’s relevant here where, in some situations the contract system turns an arity-n function into an arity-n+1 function that it defines on the exporting-module side and then it adjusts call sites instead of creating wrappers; not sure if that’s relevant to what you’re thinking about, tho.)


greg
2021-3-23 15:43:25

OK. I’ll marinade myself in that for awhile. But that explains a lot. I had totally the wrong mental model for what was going on.


robby
2021-3-23 15:43:51

(yuuuuum, maaaaaarinating)


greg
2021-3-23 15:44:53

I don’t have a specific practical goal in mind, except curiosity. I don’t expect to grok everything, but it bugged me how confused I was about this. So just absorbing.


robby
2021-3-23 15:45:06

nice


greg
2021-3-23 15:46:15

OK, well, I have one practical question in the near distance. With the check-syntax change (thanks again!) it’s now possible to build a complete db of definitions and uses across multiple files. That by itself has some good utility, I think.


greg
2021-3-23 15:46:27

But I also have this notion it would be nice to support multi-file rename.


greg
2021-3-23 15:46:39

And that’s trickier for a bunch of reasons, even modulo contract-out.


robby
2021-3-23 15:47:07

I have spent a little time over the last quarter starting on code that builds a database of fully expanded code


greg
2021-3-23 15:47:22

So I’m still thinking but it still may pop up again that it could be helpful for contract-out to provide some syntax property or hint. idk yet.


robby
2021-3-23 15:47:26

with the hope of building a layer on top of that that would hold all of the check syntax annotation information in it


robby
2021-3-23 15:47:54

So then we could do this stuff by querying the database (which might trigger real work or not depending on how we design the APIs)


robby
2021-3-23 15:48:09

With the goal of making things like jumping to definitions work a lot better


robby
2021-3-23 15:49:01

We (Christos and I) didn’t get too too far but here’s our current progress on that goal: https://github.com/rfindler/fully-expanded-store


greg
2021-3-23 15:49:02

In Racket Mode I’ve been keeping a “cache” of fully expanded syntax, but. On the one hand, it can grow quite large. On other hand, it seems impossible to serialize to disk, because to do some useful things you need the live namespace in which it was fully expanded? And so I’ve been switching to playing with storing some of the check-syntax results in a db.


greg
2021-3-23 15:49:18

It sounds like we’ve been exploring similar things maybe!


robby
2021-3-23 15:49:25

Yes, the idea here is to be a platform where you’d store things like the check syntax results in a DB


greg
2021-3-23 15:49:53

That gist I shared before is a prototype of that. :slightly_smiling_face:


robby
2021-3-23 15:50:15

But my thinking was that the first layer would be the fully expanded syntax and then others might build other useful things on top besides just check sytnax results


greg
2021-3-23 15:50:17

I’ve moved it into a little repo but not pushed to GitHub. Even if I pushed it, it would be more for “backup” than “hey use this!”.


robby
2021-3-23 15:50:31

The link above is no where near complete


robby
2021-3-23 15:50:42

I think it is the right direction to head but it needs a lot more work


greg
2021-3-23 15:52:49

That link is a 404 for me. Maybe a private repo?


greg
2021-3-23 15:53:17

robby
2021-3-23 15:57:27

oh yeah. I invited you. There’s not much there.


robby
2021-3-23 15:58:04

There’s no, in principle reason to keep it private. Just shy.


robby
2021-3-23 15:58:45

The files in run-example actually use the code


robby
2021-3-23 15:59:11

Most of the time we spent working on it was figuring out the right approach to actually get our hands on the compiled code.


chansey97
2021-3-23 15:59:19

Great! This interpreter uses two environments, a static environment and a dynamic environment, which reflects @greg’s comment: > I think of this as overloading let to mean both lexical scope and dynamic scope, but in Racket we’d normally use let for the former and parameterize for the latter. Thanks!


chansey97
2021-3-23 16:00:34

Also this reflects why @greg’s let + Parameter code can simulate it.


greg
2021-3-23 16:05:27

Thanks for the invite. I use Firefox containers and I think I’d opened it one that doesn’t know about my GitHub account. Got it now!


greg
2021-3-23 16:18:24

samdphillips
2021-3-23 18:09:43

What is the status of “Shallow Typed” Racket?


greg
2021-3-23 18:13:10

I wanted to double-check on one point. You’d said: > But my thinking was that the first layer would be the fully expanded syntax and then others might build other useful things on top besides just check sytnax result But I mentioned above something, I’m not sure you noticed? In my experience, the fully-expanded syntax seems impossible to serialize in a fully useful way. The gotchas there seem to be:


greg
2021-3-23 18:13:16

(a) You can’t just write the syntax object. Well, you can, but it can’t be read later. If you (write (syntax->datum exp-stx-object)) you can read that back, but you’ve lost all the interesting things like stx props, srcloc, etc.


robby
2021-3-23 18:13:38

Compile can do it


robby
2021-3-23 18:13:48

The code has it in there.


greg
2021-3-23 18:13:56

Oh cool.


greg
2021-3-23 18:14:22

I was about to type: (b) Even if you solve (a), to do some things you seem to need not just the stx object, but the live namespace in which it was expanded. e.g. If you want to use identifier-binding.


greg
2021-3-23 18:14:34

But maybe I’m wrong about, too?! :slightly_smiling_face:


robby
2021-3-23 18:15:00

I’m not sure about that.


robby
2021-3-23 18:15:10

I do think you lose something in the serialization process but I don’t know what exactly


robby
2021-3-23 18:15:14

the trick with compile:


robby
2021-3-23 18:15:27

you compile a program with a syntax-object literal (constant) in it so serialize


robby
2021-3-23 18:15:38

then you eval the compiled code to unserialize


greg
2021-3-23 18:16:06

OK. Interesting.


greg
2021-3-23 18:16:53

I imagine you lose syntax properties that aren’t marked as “preserved”? But maybe I’m confusing “compiling” with “bytecode marshaling”.


greg
2021-3-23 18:25:43

Anyway I do want it to be possible to save the result of full expansion to disk, in a rich enough way to be able to reuse it w/o needing to re-expand. (I was sharing what I thought might be speed bumps — not trying to shoot down the idea. I love the idea.)


greg
2021-3-23 18:30:50

Hmm oh actually: > then you eval the compiled code to unserialize Maybe doing so updates the namespace sufficiently to recover the things from the original namespace in which it was originally expanded. I can try some experiments.


greg
2021-3-23 18:32:17

What can I say. I like to sit down and have a good think, first. But sometimes, for me, “forensics precedes understanding” is my motto. :slightly_smiling_face:


robby
2021-3-23 18:32:29

absolutely!


robby
2021-3-23 18:32:39

(the smile was because I’m glad you’re putting energy into this!)


greg
2021-3-23 18:33:39

Oh I have already put a lot of energy into many of these topics. I am well into “sunk cost fallacy” territory by now, there is no turning back. :wink:


robby
2021-3-23 18:33:50

:slightly_smiling_face:


ben
2021-3-23 19:17:22

@samdphillips same as it was 6 months ago. Things keep piling up; I’ll have to pick a weekly hour or two to get it rolling again


greg
2021-3-23 21:03:53

I’ll double-check in case I made a mistake, but it seems like the 'module-body-context syntax property — https://docs.racket-lang.org/reference/Expanding_Top-Level_Forms.html#%28part._modinfo%29 — doesn’t survive the round-trip (writing ((current-compile)(,#’quote-syntax ,exp-stx) #f)to a file,read-ing it back in andeval-ing it in a freshmake-base-namespace`.) :(


greg
2021-3-23 21:12:02

Something else to consider for dynamic binding is concurrency. Racket parameters have distinct values per thread. A new thread inherits the parameter values of the thread that created it, as initial values, but they’re separate and can diverge thereafter. (Although I think that’s a sane general behavior I guess it’s possible to imagine a dynamic binding model where you intentionally don’t want that.)