strika
2021-5-18 07:00:59

@strika has joined the channel


hazel
2021-5-18 13:25:08

how would I construct a procedure that collects all keyword arguments, but additionally has existing ones? so like, as an example, for (define (func x #:y y #:keyword-hash kw-hash) (list x y kw-hash)) (func 3 #:y 4 #:bleh 'blah) ; (list 3 4 #hash((#:bleh . 'blah))) obviously this is not how define works, and I’m not sold on this syntax, but the idea stands


soegaard2
2021-5-18 13:28:37

Look at keyword-apply/dict and the simpler keyword-apply .


hazel
2021-5-18 13:30:45

absolutely, yeah, it’s about constructing the procedure and not applying a procedure with keywords, unless I’m misreading


sorawee
2021-5-18 13:31:00

There’s currently no way to do that easily


sorawee
2021-5-18 13:31:10

The best you got is make-keyword-procedure


hazel
2021-5-18 13:31:32

I mean I’m already using Alex Knauth’s kw-utils


hazel
2021-5-18 13:31:43

but that doesn’t support adding kwargs not collected into the hash


hazel
2021-5-18 13:31:48

I guess I can write yet another macro


sorawee
2021-5-18 13:32:44

hazel
2021-5-18 13:38:14

right, this is pretty close to what I want, thanks


hazel
2021-5-18 13:48:42

actually, this is exactly what I want


hazel
2021-5-18 13:48:45

thank you @sorawee


samth
2021-5-18 13:54:10

Make a package!


pocmatos
2021-5-18 15:16:12

I am trying to wrap a C function akin to strdup. Returns a string to be freed by the user. Just opened https://github.com/racket/racket/issues/3833 because the only example in the docs I could find that’s related doesn’t work with CS and could possibly be improved. I can do something like:


mflatt
2021-5-18 15:17:13

I’ll fix the docs. Meanwhile, the answer is to make the return type _pointer , which you can cast to _string and then free.


pocmatos
2021-5-18 15:18:40

So, the _string as a return type is not copied?


mflatt
2021-5-18 15:19:35

Casting to _string will create a copy from the _pointer content.


mflatt
2021-5-18 15:20:10

Using _string as a return type will also copy — which gives you a valid string, but loses the opportunity to free the pointer.


mflatt
2021-5-18 15:20:45

I think I’ve probably written a _string/then-free type once or twice.


pocmatos
2021-5-18 15:21:15

testing


pocmatos
2021-5-18 15:21:16

(define _string/free (make-ctype _pointer #f (lambda (x) (begin0 (cast x _pointer _string) (free x)))))

(define strdup (get-ffi-obj “strdup” #f (_fun _string -> _string/free)))

(for ([i (in-naturals 1000)]) (strdup “hello”))


pocmatos
2021-5-18 15:21:29

Didn’t know casting would copy…


pocmatos
2021-5-18 15:21:44

from the top of your head, will this solution also work in bc?


pocmatos
2021-5-18 15:22:51

I see the documentation for cast mentions the call to malloc.


pocmatos
2021-5-18 15:24:38

Thanks.


mflatt
2021-5-18 15:26:37

Yes, this solution should work in both CS and BC.


pocmatos
2021-5-18 15:34:58

Thanks


philip.mcgrath
2021-5-18 19:15:55

@hazel Here’s another version (minimally tested) and some notes. This is fun!


joel
2021-5-18 20:15:31

In #lang scribble/lp2, is there a way to get @defproc[(foo ...)] to register as the link target for a function foo defined within a chunk in the same file?


joel
2021-5-18 20:44:20

Reasoning that lp2 puts all scribble content in a submodule doc declared with module* I thought I could use @(require (for-label (submod ".."))) but that results in

standard-module-name-resolver: too many ".."s in submodule path: (submod (quote scribble-lp-tmp-name) "..")


massung
2021-5-18 21:15:52

Maybe I’m not seeing the obvious, but is there a kind of “step” with a for loop that’s possible (specifically w/ lists). I have a list like so: (x1 y1 x2 y2 ...) and I’d like to iterate over the pairs of x/y’s. I’d be fine with something like:

(for ([x lst #:step cddr] [y (cdr lst) #:step cddr]) ...) But I was hoping there might be another nice way to do it, too?


soegaard2
2021-5-18 21:17:41

I think, for/fold is the closest.


massung
2021-5-18 21:20:25

eh, recursion it is then :wink:


samdphillips
2021-5-18 21:27:00

There’s probably a way to make a sequence do that


jaz
2021-5-18 21:28:14

Yeah, you could make your own in-list++ or whatever to do that


shu--hung
2021-5-18 21:29:38

There’s in-slice to group the elements. You need to manually extract x and y, though. https://docs.racket-lang.org/reference/sequences.html#%28def._%28%28lib._racket%2Fsequence..rkt%29._in-slice%29%29


massung
2021-5-18 21:30:40

Ah, that’s nice. Thanks


samdphillips
2021-5-18 21:37:07

Here’s a sketch of doing it with streams #lang racket (define mylst '(x0 y0 x1 y1 x2 y2)) ;; eo is a garbage name (define (eo s next) (cond [(stream-empty? s) s] [else (stream-cons (stream-first s) (eo (next s) next))])) (define (stream-cddr s) (stream-rest (stream-rest s))) (for/list ([x (eo mylst stream-cddr)] [y (eo (cdr mylst) stream-cddr)]) (cons x y))


soegaard2
2021-5-18 21:48:25

I bet @notjack has a solution ;-)


samdphillips
2021-5-18 22:01:40

Maybe it will use … transducers?!?!


samdphillips
2021-5-18 22:01:46

:stuck_out_tongue:


soegaard2
2021-5-18 22:05:39

I guess one could throw in an [n (in-naturals)] together within an #:when (even? n).


jaz
2021-5-18 22:11:55

Hrm, using an arbitrary “step” function is a bit of a problem, since it makes it difficult to determine (efficiently) when you’re at the last position of the sequence.


notjack
2021-5-18 22:12:19

in-slice is how I do that usually :p


jaz
2021-5-18 22:12:59

Yeah, that’s fine if you want consecutive elements. @massung’s idea would be more general than that.


massung
2021-5-18 23:02:23

the in-slice worked okay. It kinda sucks creating a new list, just to deconstruct it again to get the elements I care about.

WRT streams, recursive functions, etc. Yeah, I could come up with my own solutions easily enough. I was just hoping that there was something already built-in I could leverage.


massung
2021-5-18 23:03:51

I always hate that in scheme (car null) and (cdr null) end up being errors unlike CL. But there are benefits to it as well.


massung
2021-5-18 23:06:17

It’s frustrating implementing certain algorithms that have to begin with checking if the list is empty, or - even worse - having to check lengths (e.g. for take/drop, etc.).

Hence the hope for for and a possible #:step being nice and handling it for me :wink:


jaz
2021-5-18 23:12:51

Yeah, match can be good in those situations, though not necessarily in combination with for, e.g.: #lang racket/base (require racket/match) (define input '(a 1 b 2 c 3 d 4 e 5 f 6)) (let loop ([xs input]) (match xs [(list* x y xs) (cons (cons x y) (loop xs))] [(list) null] [_ (error "input doesn't have an even number of elements")]))


pavpanchekha
2021-5-18 23:37:33

This seems like it might be a bug, but perhaps I’m misunderstanding


pavpanchekha
2021-5-18 23:37:40

> (for ([(a b) (in-producer (const #f) (const #t))]) (void)) result arity mismatch; expected number of values not received expected: 2 received: 1 in: local-binding form arguments...: #f context...: /Applications/Racket v8.0/collects/racket/repl.rkt:11:26


pavpanchekha
2021-5-18 23:37:55

In other words, I construct a sequence using in-producer which never contains any elements.


pavpanchekha
2021-5-18 23:40:07

Yet for somehow detects that (all none of) those elements aren’t multi-valued


jaz
2021-5-18 23:41:37

@pavpanchekha Are you using (const #t) as the stop value here?


jaz
2021-5-18 23:42:12

Oh sure — it’s a stop predicate.


pavpanchekha
2021-5-18 23:49:22

Yeah, that’s the stop predicate


jaz
2021-5-18 23:50:51

~Looking at the source, it appears to be using procedure-arity to special-case the 1 value case.~


jaz
2021-5-18 23:53:48

But that’s the stop code, which isn’t what’s causing this…


jaz
2021-5-19 00:01:01

Well, okay, in the macro stepper, I can see that we get: (let-values ([(a b) (#%app producer*)]) (if (#%app not (#%app stop? a b)) [...] So, it’s trying to bind two values, based on your binding syntax, before it tries to pass the results to the stop predicate.

I don’t know — based on the description of for in the docs, I wouldn’t expect an error here, but I’m not what an efficient implementation that avoided the error would look like.


ben.knoble
2021-5-19 00:15:39

Could be nice to zip your original data instead, so you have ((x0 y0) (x1 y1) …)


shu--hung
2021-5-19 01:03:34

I think it’s possible to create a new API that avoids creating an intermediate list and binds multiple elements at the same time. However, I wonder what should the API do if there are not enough elements left in the sequence.


notjack
2021-5-19 01:41:46

This is the kind of thing that generic collection interfaces would help with, if we had them


hazel
2021-5-19 02:36:17

https://docs.racket-lang.org/graphite-tutorial/index.html does this look odd for you all? the images towards the end are decidedly stretched out and not even the result of the code. could be my browser cache


hazel
2021-5-19 02:36:46

what I’m talking about — this isn’t even the result of the shown code


sorawee
2021-5-19 02:37:28

sorawee
2021-5-19 02:37:32

I saw this


hazel
2021-5-19 02:37:35

huh. it’s my cache, then


hazel
2021-5-19 02:37:40

that’s the intended result


hazel
2021-5-19 02:38:26

that’s the old pict_10.png — an image got removed from the tutorial and my browser cache must be displaying the old versions and shifting everything after the removal upwards


hazel
2021-5-19 02:38:32

which is deeply annoying. oh well


kartiksabharwal7
2021-5-19 03:46:21

In the case where the list’s length is n and you want to bind k elements at the same time but (n mod k > 0) there are two alternatives (at least in my eyes): • ignore the final (n mod k) elements entirely which is similar to the strategy of zip from Racket’s list-util OR • bind the final (n mod k) values to variables and leave the remaining variables bound to some default value. This would achieve the same result as padding the end of the list with (k - (n mod k)) copies of the default value before running it through the for I personally find the first alternative more intuitive


sorawee
2021-5-19 06:03:45

I’ve been noticing read-compiled-linklet every time I build Racket from source. E.g.,

raco setup: bootstrapping from source... read-compiled-linklet: version mismatch expected: "8.1.0.6" found: "8.1.0.2" in: /Users/sorawee/projects/racket/racket/collects/compiler/private/compiled/cm-minimal_rkt.zo raco setup: version: 8.1.0.6 raco setup: platform: aarch64-macosx [cs] ... Everything works fine though. Is this something that should be worried?