soegaard2
2020-4-14 07:36:21

https://twitter.com/samth/status/1249818179653832710?s=20 Impressed by the size of the implementation.


laurent.orseau
2020-4-14 08:32:58

I’m trying to implement an in-list+rest form for for and friends and came up with this: (define (list+rest l) (let loop ([l l]) (unless (null? l) (yield (car l) (cdr l)) (loop (cdr l))))) ; Ex: (for/list ([(x r) (in-generator (list+rest '(a b c)))]) (list x r)) --> '((a (b c)) (b (c)) (c ())) However, this is about 500× slower than a bare named let loop. Is there a proper and fast way to make such an in-list+rest?


sorawee
2020-4-14 08:35:45

In my experience, generator is very very slow in Racket BC


soegaard2
2020-4-14 08:35:57

Use define-sequence-syntax with :do-in


sorawee
2020-4-14 08:35:59

I think it improved significantly in Racket CS


soegaard2
2020-4-14 08:36:42

sorawee
2020-4-14 08:38:11

Honestly, I’m not a fan of make-do-sequence. It’s just… so unintuitive to use.


sorawee
2020-4-14 08:39:57

I attempted to read its docs for numerous times. Still couldn’t get through it. I understand that it needs to be complex to support various use cases. Still…


soegaard2
2020-4-14 08:42:07

The trick is to have the template in mind. Use the template to implement the loop, then give names to the various parts.

Once upon a time I reimplemented srfi–42 (Eager Comprehensions) so I got used to thinking this way.


sorawee
2020-4-14 08:43:22

What page is this from?



laurent.orseau
2020-4-14 08:43:51

Thank you both. Yeah, I agree with all you said. The template does help for :do-in indeed.


wanpeebaw
2020-4-14 08:58:06

laurent.orseau
2020-4-14 08:58:58

Excellent, define-sequence-syntax is just as fast as a named let loop, that’s really cool. Code in the thread for reference.


laurent.orseau
2020-4-14 08:59:18

(define-sequence-syntax in-list+rest (lambda () #'in-list+rest/proc) (lambda (stx) (syntax-case stx () [[(x r) (_ lst)] #'[(x r) (:do-in ([(l) lst]) (unless (list? l) (raise-argument-error 'in-list+rest "list?" l)) ([l l]) (not (null? l)) ([(x r) (values (car l) (cdr l))]) #true #true [r])]] [_ #f]))) (define (in-list+rest/proc l) (for/list ([(x r) (in-list+rest l)]) (list x r))) Thank you @soegaard2 @sorawee


wanpeebaw
2020-4-14 09:55:42

Found something fun to play with. If you define symbols in Chinese characters, you can write something like.

(定義 (階乘 某數) (若 (等於 某數 1) 1 (乘 某數 (階乘 (減 某數 1)))))


yfangzhe
2020-4-14 12:55:15

I think there is already some “Chinese translation” version on the package catalog.


samth
2020-4-14 13:43:31

No, there’s nothing that much like Cython for Racket. However: 1. Racket is usually a lot faster than pure Python so you don’t need it nearly as much 2. If what you want to is generate very low level code, you might be interested in Sham: https://github.com/rjnw/sham


wanpeebaw
2020-4-14 14:20:08

Oh, wow, that’s cool.


sorawee
2020-4-14 14:26:46

I tried both versions in Racket CS

(define xs (range 1000000)) (time (void (for/list ([(x r) (in-generator (list+rest xs))]) (list x r)))) (time (void (for/list ([chunk (in-list+rest xs)]) chunk)))


sorawee
2020-4-14 14:27:26

Here’s the result:

cpu time: 1182 real time: 1245 gc time: 223 cpu time: 544 real time: 577 gc time: 217


sorawee
2020-4-14 14:28:17

In Racket BC, the result is:

cpu time: 13851 real time: 14674 gc time: 6684 cpu time: 372 real time: 379 gc time: 175


sorawee
2020-4-14 14:28:53

Good news is that generator is indeed much faster.


sorawee
2020-4-14 14:29:40

Bad news is that the performance of define-sequence-syntax somehow decreases, though not significantly


sorawee
2020-4-14 14:54:20

@wanpeebaw if you want to view source code, in DrRacket, right click at an identifier and click “Open Defining File”/“Jump to Definition”


sorawee
2020-4-14 14:55:30

You can probably define a macro that extract an information from the identifier to do something like “Open Defining File”. See https://docs.racket-lang.org/drracket-tools/Accessing_Check_Syntax_Programmatically.html for instance


feariel
2020-4-14 15:05:02

@feariel has joined the channel


laurent.orseau
2020-4-14 15:17:35

why do you use in-list+rest/proc instead of in-list+rest ? The proc version is for use in map, say.


laurent.orseau
2020-4-14 16:25:26

thanks for the results all the same :slightly_smiling_face:


sorawee
2020-4-14 16:32:20

Oh lol, I misread it.


sorawee
2020-4-14 16:36:57

Actually this is a thing already: https://docs.racket-lang.org/whereis/index.html


soegaard2
2020-4-14 18:32:35

Did the time change too?


sorawee
2020-4-14 18:52:23

In BC, here’s the proc version:

cpu time: 401 real time: 404 gc time: 205 cpu time: 391 real time: 393 gc time: 183 cpu time: 464 real time: 467 gc time: 236 cpu time: 456 real time: 458 gc time: 250 cpu time: 3780 real time: 3785 gc time: 3563 cpu time: 393 real time: 398 gc time: 197 cpu time: 424 real time: 428 gc time: 214 cpu time: 432 real time: 436 gc time: 228 cpu time: 408 real time: 411 gc time: 204 cpu time: 377 real time: 379 gc time: 180 And here’s the direct version:

cpu time: 452 real time: 454 gc time: 253 cpu time: 3860 real time: 3875 gc time: 3625 cpu time: 385 real time: 393 gc time: 182 cpu time: 405 real time: 410 gc time: 193 cpu time: 393 real time: 395 gc time: 191 cpu time: 398 real time: 401 gc time: 195 cpu time: 377 real time: 380 gc time: 180 cpu time: 422 real time: 425 gc time: 212 cpu time: 403 real time: 408 gc time: 208 cpu time: 413 real time: 416 gc time: 202


sorawee
2020-4-14 18:52:33

I’d say no significant difference


soegaard2
2020-4-14 18:53:36

Thanks - that’s reassuring.


sorawee
2020-4-14 23:56:18

Quick question. I have two programs that use exn->string. One produces a detailed message and the other doesn’t. What causes the difference?

In particular, one produces:

arity mismatch;\n the expected number of arguments does not match the given number\n expected: at least 3\n given: 2\n and the other produces:

arity mismatch;\n the expected number of arguments does not match the given number\n expected: at least 3\n given: 2\n arguments...:\n 1\n 2


mflatt
2020-4-14 23:58:53

Does the first one use Racket CS?


sorawee
2020-4-14 23:59:35

No. They are both in 3m


wlbberman
2020-4-15 02:39:54

Does racket have a CLOS/emacslisp like advice capability?


wlbberman
2020-4-15 05:53:17

I’ve defined a struct using prop:procedure to give a function advising capability. However, I have a separate struct I’ve defined with prop:procedure to augment a function definition with separate capability. Is there a way to “compose” these two structs (a la multiple inheritance) such that all capabilities are available at once?


jesse
2020-4-15 06:31:10

@wlbberman I don’t believe so; that’s a CL/Elisp feature that, to my knowledge, doesn’t really have a Racket equivalent. At least, not one that’s built-in. (I may be wrong.)


wlbberman
2020-4-15 06:43:53

Is this with regards to the advice, the struct composition, or both?