deactivateduser60718
2020-3-9 14:01:30

Hi folks, I am still stumped on yesterday’s problem but found a different way to present it. Please see this video


deactivateduser60718
2020-3-9 14:05:03

Summary: If I use #lang to configure the reader, I can’t get a require to find a module I declared within a document. But if I bypass the #lang and use the read procedure directly, the require works fine. I don’t understand what changed since to me it just looks like two ways to run the same process.


laurent.orseau
2020-3-9 14:06:52

I don’t know what the solution is, but more generally since “the top-level is hopeless” have you tried the same commands from within an actual racket module instead?


deactivateduser60718
2020-3-9 14:08:30

I’m not sure what exactly you’re asking me to try. Do you mean I should try the working case within a normal racket/base module instead of the REPL?


laurent.orseau
2020-3-9 14:09:03

yes


laurent.orseau
2020-3-9 14:09:15

weird things happen in the REPL


deactivateduser60718
2020-3-9 14:09:58

checking now, stand by


deactivateduser60718
2020-3-9 14:10:49

Ran this using the racket launcher. It works fine. #lang racket/base (require "./lang.rkt") (define in (open-input-file "./mkup.rkt")) (void (read-line in)) (markup-read in) (close-input-port in)


deactivateduser60718
2020-3-9 14:11:37

And (require "./mkup.rkt") reproduces the error


laurent.orseau
2020-3-9 14:12:50

try dynamic-requiremaybe?


deactivateduser60718
2020-3-9 14:14:32

I assume you meant in the markup, but I used dynamic-require in both the markup and the racket/base module. My situation remains the same.


deactivateduser60718
2020-3-9 14:14:52

Specifically, the markup read:

#lang polyglot @mod['what]{ #lang racket/base (define out (+ 1 1)) (provide out) } @dynamic-require[''what 'out]


laurent.orseau
2020-3-9 14:14:59

Then I can’t help you much more, sorry :slightly_smiling_face:


deactivateduser60718
2020-3-9 14:15:08

That’s okay. Thanks for looking.


laurent.orseau
2020-3-9 14:15:28

But I meant instead of (require "./mkup.rkt")


deactivateduser60718
2020-3-9 14:15:38

Yeah, I changed that too. Nothing different.


laurent.orseau
2020-3-9 14:16:10

good luck then!


soegaard2
2020-3-9 16:10:51

I haven’t got a solution: just wanted to say a video was nice way of presenting the problem.


deactivateduser60718
2020-3-9 16:51:22

I’m pressed enough to start dumping the values of parameters and whatever the module resolver can tell me. I really don’t know how else to get a lead at this point.


ryanc
2020-3-9 16:51:31

Try wrapping (parameterize ((current-module-declare-name #f)) _) around the body of run-markup, maybe at the same time as you parameterize the current namespace.


deactivateduser60718
2020-3-9 16:53:21

That… seemed to do it! So the difference was that the declaring module changed?


deactivateduser60718
2020-3-9 16:54:34

It looks like this was the solution. Thank you @ryanc!


ryanc
2020-3-9 16:56:25

Here’s what I think happened: The module name resolver sets current-module-declare-name when it tries to load a module declaration. Since you’re evaluating module declarations at read-time, you accidentally inherit the parameter setting, so when your code tries to eval a declaration for module what, it gets adjusted to a declaration for whatever the name of the enclosing module is supposed to be.


ryanc
2020-3-9 17:07:45

Do you specifically want all evaluation to happen at read-time? An alternative would be to preserve all of the body forms and eval them at run time when the module is evaluated. See the implementation of the racket/load language for example.


deactivateduser60718
2020-3-9 17:09:16

That makes sense to me. I’ll do that.


badkins
2020-3-9 17:45:21

I’m considering various mechanisms for returning a small number of values. In the special case of two values it appears that the following are in order of efficiency: (values v1 v2), (cons v1 v2), (list v1 v2) - does that match your intuition? I’m inclined to use (values v1 v2)


laurent.orseau
2020-3-9 17:49:20

It matches my intuition in the following sense: • values merely moves the values around • cons uses 1 additional cons cell • list uses 2 cons cells Missing from your comparison, a (struct pair (first second)) , which I think might be on par with list, but I may be wrong.


deactivateduser60718
2020-3-9 17:50:51

I ran this for some timings. #lang racket (for ([p (in-list (list list cons values))]) (displayln (object-name p)) (time (for ([i (in-range #e1e8)]) (p 1 2))))


deactivateduser60718
2020-3-9 17:51:06

Results for me: overhead.rkt> list cpu time: 505 real time: 507 gc time: 51 cons cpu time: 320 real time: 321 gc time: 6 values cpu time: 232 real time: 233 gc time: 0


laurent.orseau
2020-3-9 17:51:29

add (collect-garbage) before the loop


badkins
2020-3-9 17:51:58

Use a higher loop count to get gc involved more


badkins
2020-3-9 17:52:06

I was testing with 100M iterations


deactivateduser60718
2020-3-9 17:52:46

Like so? (for ([p (in-list (list list cons values))]) (displayln (object-name p)) (collect-garbage) (time (for ([i (in-range #e100e6)]) (p 1 2))))


laurent.orseau
2020-3-9 17:52:59

yes, better


badkins
2020-3-9 17:53:05

why hex values for the loop max? :slightly_smiling_face:


deactivateduser60718
2020-3-9 17:53:19

You want free help or not? :smile:


deactivateduser60718
2020-3-9 17:53:46

But seriously, I just like consice notation.


badkins
2020-3-9 17:54:31

oh, I misread the constant as a hex value, not e notation


deactivateduser60718
2020-3-9 17:54:50

No worries.


badkins
2020-3-9 17:55:34

The Racket built-in libraries sometimes use values and sometimes use a cons pair, etc. - not sure if that just reflects different styles of authors, or if there is some other rationale.


deactivateduser60718
2020-3-9 17:57:04

IME I find myself switching it up based on how much I want to (re)write for consumers of values. Switching from list to values, for example, has a small re-write burden since you have to write matching define-values


deactivateduser60718
2020-3-9 17:57:49

Lists and pairs have the benefit of being readily useable for channels, etc.


deactivateduser60718
2020-3-9 17:59:05

I’d only speculate that the former motivation would have a bigger impact on style choices.


laurent.orseau
2020-3-9 18:00:45

@deactivateduser60718 Are your tests with the bigger values still running?


deactivateduser60718
2020-3-9 18:03:39

Nope, here’s 1 billion.

list cpu time: 4627 real time: 4642 gc time: 96 cons cpu time: 3536 real time: 3547 gc time: 56 values cpu time: 2411 real time: 2414 gc time: 3 overhead.rkt>


deactivateduser60718
2020-3-9 18:03:53

collect-garbage still being outside time’s body.


badkins
2020-3-9 18:04:06

@deactivateduser60718 geez - what computer are you running that on?


deactivateduser60718
2020-3-9 18:04:18

HP Omen 15, why?


badkins
2020-3-9 18:04:32

much faster than my 16" Macbook Pro


badkins
2020-3-9 18:04:51

although I ran in DrRacket


deactivateduser60718
2020-3-9 18:05:10

I wonder what’s so different. My hardware is a bit dated.


deactivateduser60718
2020-3-9 18:05:20

Lemme try DrRacket


laurent.orseau
2020-3-9 18:06:09

As a rule of thumb, don’t benchmark in DrRacket, as it can do a lot more things under the hood


deactivateduser60718
2020-3-9 18:07:09

Yep. But just for grins, #e1e9 + DrRacket yields: list cpu time: 5990 real time: 6015 gc time: 298 cons cpu time: 4315 real time: 4337 gc time: 167 values cpu time: 2421 real time: 2431 gc time: 2 >


deactivateduser60718
2020-3-9 18:07:38

(7.6 CS too, btw. Should have mentioned that)


badkins
2020-3-9 18:08:06

Odd, when running from the command line, I get: list cpu time: 1970 real time: 1982 gc time: 21 cons cpu time: 607 real time: 612 gc time: 11 values cpu time: 1557 real time: 1558 gc time: 0 badkins@create Desktop % racket bench.rkt list cpu time: 1980 real time: 1993 gc time: 17 cons cpu time: 608 real time: 613 gc time: 7 values cpu time: 1562 real time: 1564 gc time: 0


badkins
2020-3-9 18:08:15

not sure why values is higher


badkins
2020-3-9 18:08:42

In my test, I also extracted the values out into two variables since both the return and destructuring are necessary.


laurent.orseau
2020-3-9 18:09:27

Racket 7.6 CS, linux: list cpu time: 532 real time: 532 gc time: 8 cons cpu time: 357 real time: 357 gc time: 5 values cpu time: 339 real time: 340 gc time: 0


laurent.orseau
2020-3-9 18:10:29

(Sage’s code with #e100e6)


deactivateduser60718
2020-3-9 18:10:41

A colorful max :wink:


laurent.orseau
2020-3-9 18:10:50

haha


deactivateduser60718
2020-3-9 18:12:19

@badkins I’m guessing running raco make wouldn’t make much difference since the code would be compiled by the launcher anyway, but does that affect anything?


laurent.orseau
2020-3-9 18:14:21

With 1e9, and a struct mypair: list cpu time: 5426 real time: 5427 gc time: 83 cons cpu time: 3709 real time: 3710 gc time: 44 values cpu time: 3323 real time: 3324 gc time: 0 mypair cpu time: 5479 real time: 5481 gc time: 82


deactivateduser60718
2020-3-9 18:15:18

This is pretty neat. There’s a lot to extrapolate from that


badkins
2020-3-9 18:18:25

#lang racket (define count #e1e9) (define str-value "qwertyasdf") (define num-value 7.85) (define (return-values) (values str-value num-value)) (define (return-cons) (cons str-value num-value)) (define (return-list) (list str-value num-value)) (time (for ([ i (in-range count) ]) (let-values ([( str num ) (return-values) ]) (void)))) (time (for ([ i (in-range count) ]) (match-let ([(cons str num ) (return-cons) ]) (void)))) (time (for ([ i (in-range count) ]) (match-let ([(list str num ) (return-list) ]) (void)))) cpu time: 1146 real time: 1149 gc time: 0 cpu time: 1195 real time: 1198 gc time: 0 cpu time: 7029 real time: 7164 gc time: 331


badkins
2020-3-9 18:19:04

surprised at how close values and cons are here


laurent.orseau
2020-3-9 18:19:11

With 10 values, 1e9 iterations: list cpu time: 18831 real time: 18834 gc time: 469 values cpu time: 3763 real time: 3763 gc time: 0 mypair cpu time: 14752 real time: 14754 gc time: 310 (cons excluded, obviously)


laurent.orseau
2020-3-9 18:23:32

So for a larger number of values, a struct seems a little better than a list, but values is way faster anyway


laurent.orseau
2020-3-9 18:26:59

@badkins My guess is that match-let might be optimized for cons but not for list?


badkins
2020-3-9 18:27:53

You’re right! I think it could tell the result wasn’t used.


badkins
2020-3-9 18:28:36

Here’s a more valid one: #lang racket (define count #e15e7) (define (return-values) (values "qwertyasdf" 7.85)) (define (return-cons) (cons "qwertyasdf" 7.85)) (define (return-list) (list "qwertyasdf" 7.85)) (time (for ([ i (in-range count) ]) (let-values ([( str num ) (return-values) ]) (when (not (and (string=? "qwertyasdf" str) (eqv? 7.85 num))) (error "bad values"))))) (time (for ([ i (in-range count) ]) (match-let ([(cons str num ) (return-cons) ]) (when (not (and (string=? "qwertyasdf" str) (eqv? 7.85 num))) (error "bad values"))))) (time (for ([ i (in-range count) ]) (match-let ([(list str num ) (return-list) ]) (when (not (and (string=? "qwertyasdf" str) (eqv? 7.85 num))) (error "bad values"))))) cpu time: 171 real time: 172 gc time: 0 cpu time: 900 real time: 913 gc time: 25 cpu time: 1320 real time: 1344 gc time: 33


popa.bogdanp
2020-3-9 18:37:16

@greg I’ve noticed that racket-expand-last-sexp no longer works on this branch. The expansion window opens and when I hit RET to expand it doesn’t do anything and it writes this

string::2: match-let: unbound identifier; also, no #%app syntax transformer is bound at: match-let in: (match-let (((list str num) (return-list))) (void)) to the minibuffer. Let me know if you want me to open up an issue with more details about it.


greg
2020-3-9 19:12:00

@popa.bogdanp Thanks for reporting. We must be on the same psychic wavelength, because I also just noticed this today. Well, racket-expand-file, and a slightly different error. But also when doing RET in the racket-stepper-mode buffer. And probably similar root problem. I’ll take a look.


chansey97
2020-3-9 19:17:31

@chansey97 has joined the channel


sorawee
2020-3-9 19:30:50

Question (particularly for @ryanc I think): is there a way to make syntax-parse works nicely with syntax-disarm? I’m trying to do something similar to errortrace which needs to disarm/rearm syntax object for each depth (https://github.com/racket/errortrace/blob/master/errortrace-lib/errortrace/stacktrace.rkt#L385). If I attempt to do any more complex pattern matching, the result will be tainted.


sorawee
2020-3-9 19:32:21

In my previous project I solved the problem by recursively disarming everything (without rearming it afterward), but that’s probably not a good practice…


ryanc
2020-3-9 19:55:57

Here’s a pattern form that disarms the current term and then matches it against the given subpattern. In the simplify macro below, if you remove the ~disarm wrapper, you should get a tainted identifier error, but with ~disarm it works. #lang racket/base (require (for-syntax racket/base syntax/parse)) (begin-for-syntax (require (for-syntax racket/base)) ;; S-pattern ::= ... \| (~disarm S-pattern) ;; The pattern (~disarm p) matches a term t if p matches the term ;; after being disarmed with syntax-disarm. (define-syntax ~disarm (pattern-expander (lambda (stx) (syntax-case stx () [(_ pattern) #'(~and x (~parse pattern (syntax-disarm #'x #f)))]))))) (define-syntax thunk (syntax-parser [(_ e) (syntax-protect #'(lambda () e))])) (define-syntax simplify (syntax-parser [(_ e) (define ee (local-expand #'e 'expression null)) (syntax-parse ee #:literal-sets (kernel-literals) [(let-values ([(x:id) (~disarm (#%plain-lambda () e:expr))]) (#%plain-app y:id)) #:when (free-identifier=? #'x #'y) (eprintf "simplifying to ~e\n" (syntax->datum #'e)) #'e] [e (eprintf "could not simplify\n") #'e])])) (simplify (let ([t (thunk (+ 1 2))]) (t)))


sorawee
2020-3-9 19:56:47

Thanks!


greg
2020-3-9 20:14:45

Yeah the problem in both cases was that the proper current-namespace wasn’t set. For expanding expressions, this needs to come from a REPL for the .rkt file whose context you want to use, to expand. For expanding entire files, it simply needed a make-base-namespace. I have some code to handle both. “It works”. But I’d like to mull it over before I push a commit, even just to the check-syntax branch.


greg
2020-3-9 21:28:19

popa.bogdanp
2020-3-9 22:28:44

Works great now. Thank you!


programminglinguist
2020-3-10 01:24:17

@programminglinguist has joined the channel


programminglinguist
2020-3-10 01:47:35

hello all! I was wondering if you could help me out with a racket distribution question. I’m having trouble building a standalone executable with r-cade on a Mac. The repo’s owner pointed me to this slack group. https://github.com/massung/r-cade/issues/20

It relies on some libraries I installed via homebrew. I tried putting whole directories from /usr/local/Cellar/ into my http://main.app\|main.app file under various locations but my friend says it’s not booting on his Mac. It’s one of those “it works on my machine” problems. :confused:


soegaard2
2020-3-10 06:03:31

@programminglinguist I recommend using the official racket from http://download.racket-lang.org\|download.racket-lang.org. (Especially if your version is not update).


programminglinguist
2020-3-10 06:14:23

Hello! I think I am using the official racket program… right?

$ racket --version Welcome to Racket v7.5.