That’s perfect, thank you :slightly_smiling_face:
Are Cygwin DLLs and DLLs produced by Microsoft Visual Studio the same thing as far as Racket’s FFI goes for integrating C libraries?
Probably. It’s the same object format. I forget whether Cygwin DLLs pull in any dependencies or behavior that is inherently incompatible with Racket, but I don’t think it does.
@stefan.kruger has joined the channel
I’d like to reduce a hash to a list with fewer items than what the hash contains - for a list I’d look to use filter-map
or foldl
. I naively tried (filter-map (lambda (k v) ...) (in-hash ht))
but filter-map
no good on a sequence. Then I tried (for/list ([(k v) (in-hash ht)] ...
with a #:when
clause, which kind of works, except I’d need to do a bunch of (let...
in the #:when
… I had hoped I could do: (for/list ([(k v) (in-hash ht)])
(let ([new-v (...)])
(when (or (not (...)) (< new-v (...)))
(values k))))
but didn’t expect the void
s.
News about “How to design components”? https://stackoverflow.com/questions/56565321/any-thing-about-how-to-design-components-mentioned-in-how-to-design-programs
@stefan.kruger You can use for*/list
and then use in-value
to get let
-like bindings in the clauses.
For example: (define ht (hash 'a 1 'b 4 'c 7 'd 9))
(for*/list ([(k v) (in-hash ht)]
[new-v (in-value (* v 100))]
#:when (< new-v 500))
k)
;; '(a b)
Wow, that looks just what I was reaching for. Thanks for your help!
You’re welcome. in-value
is a good name in the sense that it describes what it does, but, it doesn’t really afford why you’d want to use it, so, it’s probably not ideally discoverable. Anyway this is a pretty common idiom in Racket and you’ll see examples in the docs or in various repos.
You can send place channels across place channels right? Have each request include a fresh single-use channel and have the hasher place send its response to the channel in the request
@notjack I’ve thought about that as well, but since FFI operations block the entire OS thread (in this case, the one backing the place — meaning the place can’t really process incoming messages concurrently), I don’t think that’ll make a huge difference compared to locking around the resource with call-with-semaphore
as I am right now. If/when I need to improve the speed of login operations, I think creating a pool of hasher places will be the way to go.
Oh I meant just as a way to ensure messages can’t get crossed
Works :slightly_smiling_face: — I’d never have discovered that on my own.
I forget about in-value
a lot, which is probably why a lot of my code is cluttered with for/fold
Is there an in-value
like solution for match
as well? The best I can come up with is:
(match (list 5 6 7)
[(list a (and b (app (lambda (x) (* 2 x)) d)) c)
#:when (>= d 10)
(list a b c d)])
But this looks kinda awful
have you looked at the as
pattern from unstable/match
?
@sorawee I would like to be able to write (require unstable/match)
(match (list 5 6 7)
[(list a (and b (as ([d (* 2 b)]))) c)
#:when (>= d 10)
(list a b c d)])
instead of that app
+ lambda
thing, but match
’s pattern language limits its binding
A more syntax-parse
-like match form would be able to handle this perfectly though
Yeah, I think as
can only see stuff outside of match
(same as ==
), but not variables bound in match
, which is what I want
as
will also get tedious when the pattern is bigger (e.g., the bound variable is in several branches of or
)
Ideally I want something like:
(match (list 5 6 7)
[(list a b c)
#:with d (* 2 b)
#:when (>= d 10)
(list a b c d)])
I believe @lexi.lambda at some point was working on a pattern-combinator language that would support syntax-parse
-like features, including delimited cuts. And I’ve written some macros that would be able to compile a match pattern to use such a pattern-combinator language in a way that would allow exactly that (come to think of it, it would also allow the (and b (as ([d (* 2 b)])))
pattern above)
Although IIRC there were performance issues
I never got to implementing head patterns.
I’m really looking forward to that :slightly_smiling_face:
I have an idea for a way to implement (ellipsis) head pattern-like things in a datatype-agnostic way using a monadic DSL, but I haven’t gotten around to trying to implement it.
Actually, I have a partially-working version of match patterns that would allow Sorawee’s example here https://github.com/AlexKnauth/match-pattern-synonym (require match-pattern-synonym)
(match (list 5 6 7)
[(list a (~refine b (~with d (* 2 b))) c)
#:when (>= d 10)
(list a b c d)])
The main goal of this project was to allow recursive pattern-synonyms, in the same way syntax-parse allows recursive syntax-classes, but I also got the ~refine
pattern to work like and
works in syntax-parse, along with a ~with
pattern
What is “that” in this context? If it’s monadic head patterns, the main thing I wanted to do differently is to make those patterns first-class values, the same way my existing implementation makes single-term patterns first-class values.
But then I’d probably want a domain-specific optimizer language to make common cases fast, like GHC’s rewrite rules… can someone go do a PhD on that, please? :)
“that” is the match-pattern-synonym
repository
I thought that was “here.” (But it probably doesn’t matter very much; don’t mind me.)
Oh. “version of that here” + “that” somewhere else would imply something I did not mean
Monadic head patterns sound interesting…
I don’t have head patterns for my version of match patterns either
3 more commits!
is anyone else going to ICFP in Berlin this August?