joshibharathiramana
2021-6-21 12:48:57

Does racket have something like haskell’s drop/take, where once the list is empty it returns the empty list instead of throwing a contract violation? I know I can write one myself, but was wondering if it already has it.


laurent.orseau
2021-6-21 12:56:04

I don’t think it has that. I often write a drop-at-most variant indeed.


laurent.orseau
2021-6-21 12:59:06

(and usually I do that with a named let loop, as using length takes time linear with the length of the list when it should be linear with the number of elements removed)


greg
2021-6-21 13:00:18

That’s a good point, since Racket will eval this eagerly not lazily like Haskell.


greg
2021-6-21 13:00:47

If it’s a situation where you want to examine each element of the sub-lists, it might turn out you can use in-slice, which behaves the desired way. e.g. (for/list ([xs (in-slice 2 '(1 2 3 4 5))]) xs) is '((1 2) (3 4) (5)).


greg
2021-6-21 13:02:23

That will probably expand to something like the sort of named let you would write manually.


ben.knoble
2021-6-21 15:39:51

soegaard2
2021-6-21 15:42:47

Why the name “cleave”? Am I missing some analogy?


ben.knoble
2021-6-21 15:43:25

I have 0 ideas /shrug


ben.knoble
2021-6-21 17:45:41

Sancho might be right; perhaps just an opportunistic “this is what I’m calling it”


badkins
2021-6-21 19:04:00

In addition to “split” or “sever”, cleave can also mean “to stick”, “to adhere”, “to hold” e.g. “A man shall leave father and mother, and cleave to his wife. Gen 2. Math 19” - from Noah Webster’s 1828 dictionary. Having said that, I don’t think “cleave” is the best name for this function :)


badkins
2021-6-21 19:04:18

Interesting that Factor has it built-in and named cleave


badkins
2021-6-21 19:11:10

I like the Julia solution on that page: f = .\|>


xlambein
2021-6-21 19:26:34

I’ve been struggling with something for a while. It’s kind-of unhygenic dark macro module magic, but basically I’d like to make a custom module that wraps each top-level expression into a set! that appends the result of the expressions to an accumulator that I later provide. So like, a module-begin that exposes a list of the result of each top-level expression. I managed to do it with make-wrapping-module-begin, but I have to declare the accumulator outside of the module-begin, which seems weird and maybe dangerous to me. I don’t know what the Racket runtime does, maybe that accumulator would be used more than once. So instead I’m trying something like the following: (define-syntax (module-begin stx) (with-syntax ([acc (datum->syntax stx 'acc)]) (define (wrap stx) (syntax-parse stx [(_ expr) #'(set! acc (cons expr acc))])) (define (plain-module-begin stx) (syntax-parse stx [(_ body ...) #'(#%plain-module-begin (provide acc) body ...)])) ((make-wrapping-module-begin #'wrap #'plain-module-begin) stx))) Basically, doing some unhygenic macro stuff to declare acc in the module-begin, and then referencing it in the wrap macro that make-wrapping-module-begin introduces around each top-level expression. Except that when I do that, Racket complains that it can’t find wrap, and I can’t figure out why.

This is probably a bit unclear, I’m sorry if it is. I also feel like I’m totally doing something I shouldn’t :sweat_smile: If you have an alternative way of doing what I’m trying to achieve, I’m very interested to hear it. Thanks!


samth
2021-6-21 19:37:43

It can’t find wrap because you need wrap to be a definitition that the module-being form can expand to.


samth
2021-6-21 19:38:23

I also note that your program doesn’t have any definitions of acc


samth
2021-6-21 19:39:05

You might look into the implementation of module+ to see how that works


samth
2021-6-21 19:39:15

that also involves an accumulator


xlambein
2021-6-21 19:39:20

Oh yep indeed, I removed some stuff to unclutter the snippet and I took it out :sweat_smile:


xlambein
2021-6-21 19:39:37

I’ll look into that, thanks!


xlambein
2021-6-21 19:40:48

Hmm and how do I know that the module-begin form doesn’t have access to it? I’m a bit lost here, I think this whole thing is too much for me to bite


xlambein
2021-6-21 19:41:14

or maybe phrased better: is there a way I could declare wrap such that it would be accessible?


samth
2021-6-21 19:41:22

The wrap function there is a local definition, you can’t use it elsewhere


samth
2021-6-21 19:41:34

You would just want to have a separate top-level definition of wrap


xlambein
2021-6-21 19:42:02

yeah that’s what I did before, but then wrap can’t have access to a local accumulator, I think


samth
2021-6-21 19:42:26

Right, that’s true, but that shows the local accumulator doesn’t work either


xlambein
2021-6-21 19:42:40

fair enough!


xlambein
2021-6-21 19:43:39

I feel like this is a limitation of make-wrapping-module-begin tho. I had the feeling that what I want should be possible


xlambein
2021-6-21 19:44:04

but I’ll look into module+, hopefully that’ll be easier to work out


samth
2021-6-21 19:44:42

make-wrapping-module-begin can’t work the way you were hoping — you can’t just take an locally-definied identifier and put it somewhere else.



xlambein
2021-6-21 19:45:39

Thanks a lot!


samth
2021-6-21 19:47:03

note that it’s more complicated than the code you had, but most of that is necessary


xlambein
2021-6-21 20:01:53

Yeah I’m looking through it but I think I don’t have a good enough understanding of Racket to grasp the whole thing