steveh2009
2019-6-19 14:01:37

Is there a group of well known functions which can work with traversing a list of structs of the same composition, comparing fields of the same name for their values? For example, if I have a price field, I would want to compare a price outside of the list of structs to all the price fields, like member does for simple lists. My newbie-ness to Racket makes me want to ask here first so I can reuse instead of reinvent.


alexknauth
2019-6-19 14:13:36

Higher-order functions like findf, memf, filter, and argmin might help you, if you combine them with the right function arguments. For example: #lang agile (struct foo [price desc] #:transparent) ;; Price -> [Foo -> Bool] (define ((price<=? p) foo) (<= (foo-price foo) p)) > (findf (price<=? 30) (list (foo 31 "tantalus") (foo 85 "blue milk") (foo 29 "james madison") (foo 24 "missing out"))) (foo 29 "james madison") This is one example, but if you want to do something different from <=, you can change the predicate that you pass to it.


steveh2009
2019-6-19 15:08:33

Wow, thanks for the pointers. You know, I’m probably making this way too hard on myself. A list of structs could be turned inside out. That is, have ONE struct, each field has a list of values where the groupings of associated data are known by the index. Then all the built-in list operations can be applied after one struct field lookup.


alexknauth
2019-6-19 15:09:56

No, most of the time a list of structs is a better design than “parallel lists whose values are only related by having the same index in the list”


greg
2019-6-19 15:20:52

@steveh2009 Also keep in mind you can produce a list of prices with just (map foo-price xs). (Where xs is the list of foo structs.) Then do comparisons as you would do with any simple list of price numbers. The way @alexknauth showed with findf avoids creating any such intermediate list, which is likely to be faster (but that might not matter much unless the list is very large).


ben
2019-6-19 15:25:18

contract internals question: does anyone know the motivation for contract-pos/neg-doubling' ? <https://github.com/racket/racket/blob/master/racket/collects/racket/contract/private/guts.rkt#L1002> I see how it's used and what it does, and I figured it must help performance sometimes ... but I ran a quick test on the gradual typing benchmarks and the results were slightly faster (0.5sec) after removing thewith-continuation-mark` and always forcing the thunks.

So it seems like we’d be better off removing it to simplify things (esp. the collapsible-vectors late-negs)


samth
2019-6-19 15:37:53

@ben the explanation in this commit seems pretty clear: https://github.com/racket/racket/commit/ff588f93eb04221089803597baab5c4a9a7e0199


notjack
2019-6-19 15:40:59

Re: struct of lists vs list of structs: that problem is partly why I made table and record types Tables: https://docs.racket-lang.org/rebellion/Tables.html Records: https://docs.racket-lang.org/rebellion/Records.html


sorawee
2019-6-19 16:25:50

In racket-mode, each racket-run gets a fresh custodian including a fresh dedicated thread for the REPL. As a result, parameters are reset (from https://github.com/greghendershott/racket-mode/issues/381).

But are there anything else that are not reset back (port-write-handler, which is not a parameter, seems to be one of these)? And what’s needed to reset them back?


greg
2019-6-19 18:26:26

@notjack Looks cool. Is there a record match-expander similar to the struct and/or hash-table match patterns? Or is the idea you’d probably just match using list on record-values, depending on keyword sorting?


notjack
2019-6-19 18:44:45

@greg There isn’t a match expander, but only because I haven’t implemented one yet. Please open an issue for that, if it’s not too much trouble https://github.com/jackfirth/rebellion