sorawee
2021-7-23 07:03:28

Ah, so instead of:

(cond [(box-cas! ...) ...] [else ...]) I would need to change it to:

(let loop () (cond [(box-cas! ...) ...] [(old-value? (unbox ...)) (loop)] [else ...]))


popa.bogdanp
2021-7-23 08:47:39

I have some variant of <https://github.com/Bogdanp/koyo/blob/a140c9dadfeef80a69355aaff025d5c5cfc06a00/koyo-lib/koyo/util.rkt#L10-L14|this function> in multiple projects (sometimes it returns the result of the application, and sometimes it doesn’t). It would be nice to have something like it in base.


d_run
2021-7-23 10:45:08

:wave: GUI Q I have a small GUI that makes a web request and I need to display the returned JSON text in a %text field. Has anyone done any work on formatting/beautifying JSON in Racket? Any tips on direction if not?


laurent.orseau
2021-7-23 11:19:23

Just curious: Any particular reason why you’re calling unbox at each iteration?


popa.bogdanp
2021-7-23 11:26:43

If two threads race to change the value, one will succeed and the other will fail. If the one that succeeded changed the value in the box, the new one has to read the new value before it can change it (because box-cas! only changes the value in the box if its current value is eq? to the old argument).


popa.bogdanp
2021-7-23 11:37:58

Here’s an example:

#lang racket/base (define (box-swap! b f) (let loop ([v (unbox b)]) (unless (box-cas! b v (f v)) (loop (unbox b))))) (define b (box 0)) (define sema (make-semaphore)) (define thds (for/list ([_ (in-range 100)]) (thread (lambda () (sync sema) (for ([_ (in-range 10)]) (box-swap! b (λ (x) (sleep 0) (add1 x)))))))) (for ([_ (in-range (length thds))]) (semaphore-post sema)) (for-each thread-wait thds) (unbox b) If you change (loop (unbox b)) to (loop v) , the code will most likely go into an infinite loop.


laurent.orseau
2021-7-23 11:42:26

Makes perfect sense, thanks!


greg
2021-7-23 13:04:33

I don’t know of a Racket JSON pretty formatter, so:

If the GUI’s audience were Racketeers? I might turn the JSON into a jsexpr, pretty-print that s-expression, and declare mission accomplished. :)

If the audience were “normal people”? I might system out to some command-line JSON pretty formatter. (That’s probably fast enough, especially on *nix. If it weren’t, I might process to keep one instance running and pipe to/from it.)


sschwarzer
2021-7-23 13:10:55

• I don’t think it would make sense to have a dedicated keyword for each strategy. • If there are only two possibilities, a flag makes sense. • With the exception that if we want to extend the ordering options later, it should be a keyword argument taking symbols. • 'lazy sounds much too vague for me. If it’s a particular strategy, it could be 'szudzik etc., unless we may want to change this strategy later, i. e. 'lazy would be intentionally vague. But then, 'lazy doesn’t say anything without a proper explanation, at which point we probably want the more specific term(s) anyway. • I miss “my” ordering that led to this thread :satisfied: (@sorawee’s second implementation). It was (or would have been) actually needed for the use case.


djholtby
2021-7-23 13:19:03

I found someone that’s done work: https://gist.github.com/carl-eastlund/5398440 . Haven’t tried it


d_run
2021-7-23 13:33:44

oh nice, in the meantime I system‘d out to jq to do it quick and dirty. Will look at Carls’ code.


sschwarzer
2021-7-23 16:43:21

Is there in Racket a simple way to “unpack” a pair to two identifiers? For example (unpack-pair (first second) pair) would be equivalent to (define-values (first second) (values (car pair) (cdr pair))) I’m sure that could be achieved with a custom macro, but I wonder if there’s something in the standard-library.


d_run
2021-7-23 16:44:55

Now i’m wondering if I can package up jq into the app bundle…


claiborn
2021-7-23 16:46:52

I think you want racket/match . But I tend to just use a similar approach with values for small destructures.


shu--hung
2021-7-23 16:49:29

to add: (require racket/match) (match-define (cons fst snd) '(5 . 3))


greg
2021-7-23 17:08:05

As @shu—hung said, match-define is what you asked for. In fact it probably expands to something very like your definition of unpack-pair. There’s also a let flavor, match-let.


greg
2021-7-23 17:10:09

All of these will of course throw an exception if pair isn’t a pair. When you want to handle that possibility, see match, which is more cond-like. You try matching against successive patterns. The final pattern can be an identifier (conventionally _) which binds to/matches anything, which is your “else”.


greg
2021-7-23 17:11:55

(You could make that final pattern the identifier else, but it’s not a special keyword, it could be any identifier, and will be bound to the value you gave to match.)


sschwarzer
2021-7-23 17:25:29

Right, I always forget about racket/match, sorry. I usually avoid it because it doubles the startup time for simple programs (using racket/base), so it seems my brain refuses all recollection of racket/match. ;-/


sschwarzer
2021-7-23 17:25:45

But thanks, of course.


sschwarzer
2021-7-23 17:26:17

Otherwise I really like pattern matching.


shu--hung
2021-7-23 17:29:03

If the program is pre-compiled using raco make (for a single file) or raco setup (for a package), the startup time should reduce


shu--hung
2021-7-23 17:29:17

Well, I’m not sure how mucn though


sschwarzer
2021-7-23 17:29:29

Yes, it’s reduced, but not very much.


samth
2021-7-23 19:01:33

Turns out racket/match had accidentially added a dependency on racket/contract/base which made the startup time larger; that should be fixed soon.


d_run
2021-7-23 20:47:27

Follow on from my earlier question, is it possible to embed something like jq (https://stedolan.github.io/jq/) into a distributable app bundle?


samth
2021-7-23 20:51:10

Yes, you should be able to use define-runtime-path and raco distribute to do that.


d_run
2021-7-23 20:58:13

samth
2021-7-23 20:58:37

yeah



sschwarzer
2021-7-23 22:29:32

How large is the difference?

I thought racket/match took so much time because it pulled in lots of stuff from modules to match against.


samth
2021-7-23 22:52:54

It’s most of the difference.


sschwarzer
2021-7-23 22:55:18

Awesome! :slightly_smiling_face:


shu--hung
2021-7-23 22:55:44

On my machine, loading (roughly) racket/base takes 0.11 real, loading racket/contract/base takes 0.25 real and loading the old racket/match takes 0.30 real