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.
I don’t think it has that. I often write a drop-at-most
variant indeed.
(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)
That’s a good point, since Racket will eval this eagerly not lazily like Haskell.
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))
.
That will probably expand to something like the sort of named let
you would write manually.
I’ve just learned this can be called cleave https://codegolf.stackexchange.com/q/230145/92951\|https://codegolf.stackexchange.com/q/230145/92951
Why the name “cleave”? Am I missing some analogy?
I have 0 ideas /shrug
Sancho might be right; perhaps just an opportunistic “this is what I’m calling it”
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 :)
Interesting that Factor has it built-in and named cleave
I like the Julia solution on that page: f = .\|>
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!
It can’t find wrap
because you need wrap
to be a definitition that the module-being form can expand to.
I also note that your program doesn’t have any definitions of acc
You might look into the implementation of module+
to see how that works
that also involves an accumulator
Oh yep indeed, I removed some stuff to unclutter the snippet and I took it out :sweat_smile:
I’ll look into that, thanks!
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
or maybe phrased better: is there a way I could declare wrap
such that it would be accessible?
The wrap
function there is a local definition, you can’t use it elsewhere
You would just want to have a separate top-level definition of wrap
yeah that’s what I did before, but then wrap
can’t have access to a local accumulator, I think
Right, that’s true, but that shows the local accumulator doesn’t work either
fair enough!
I feel like this is a limitation of make-wrapping-module-begin
tho. I had the feeling that what I want should be possible
but I’ll look into module+
, hopefully that’ll be easier to work out
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.
Here’s the source file: https://github.com/racket/racket/blob/master/racket/collects/racket/private/submodule.rkt
Thanks a lot!
note that it’s more complicated than the code you had, but most of that is necessary
Yeah I’m looking through it but I think I don’t have a good enough understanding of Racket to grasp the whole thing