Apologies. By fourth optional argument, I meant a fourth field with the #auto field option. I'm experimenting with this now.
On Monday, February 1, 2021 at 3:24:49 PM UTC-6 making-a-racket wrote: > Thanks for the suggestion and for the macro implementation. I'll have to > pour over that a bit. > > I wanted to do map because I wanted to make it easy to idiomatically > implement addition and other such operators on my data types such that they > accept arbitrary amounts of arguments and provide the map for other uses. > > So that's why the vector (in the Racket sense) is the most simple option > in that respect, since I can trivially do: > > (define (sum-vector v) > (apply + (vector->list v))) > > (define (vector+ . vs) > (apply vector-map + vs)) > > (define (vector-i v) > (vector-ref v 0)) > ;; and so on > > The only think I don't get there are my wanted datatypes and associated > predicates, since vectors, points, and colors would all be Racket vectors. > > I could almost do structs with a fourth optional argument that holds a > Racket vector that never gets used explicitly by the "user" and build > helper functions to properly update it, which is then used to build all the > operator and other such functions. > > If I just do structs as I originally notated, how do you suggest I > implement things like vector+ to take in arbitrary amounts of arguments? > > > On Monday, February 1, 2021 at 12:48:19 AM UTC-6 [email protected] wrote: > >> I'd suggest just going with the structs and making them transparent. It's >> only three structs and only with a handful of fields, abstracting over them >> with map and fold doesn't seem worth the added complexity IMO. But if you'd >> really like to map and fold over structs, I highly recommend using macros, >> `syntax-parse` and the struct-id >> <https://docs.racket-lang.org/syntax-classes/index.html?q=struct-id#%28form._%28%28lib._syntax%2Fparse%2Fclass%2Fstruct-id..rkt%29._struct-id%29%29> >> >> syntax class to do so: >> >> (require (for-syntax syntax/parse/class/struct-id) >> syntax/parse/define) >> >> (define-simple-macro (struct-map type:struct-id instance-expr:expr >> map-function-expr:expr) >> (let ([map-function map-function-expr] >> [instance instance-expr]) >> (type.constructor-id (map-function (type.accessor-id instance)) ...))) >> >> (struct point (x y z) #:transparent) >> >> ;; Outputs (point 2 3 4) >> (struct-map point (point 1 2 3) add1) >> On Sunday, January 31, 2021 at 4:20:03 PM UTC-8 making-a-racket wrote: >> >>> Hello. I have a project where I am needing to represent vectors (in the >>> mathematical sense), points, and colors. Both the vectors and points will >>> be 3D. I'm having trouble knowing what's an idiomatic way to represent and >>> interact with data types that are similar but different. >>> >>> In general, I could simply all represent them with a list or vector (in >>> the Racket sense). So I could have: >>> >>> (define (vector i j k) #(i j k)) >>> (define (point x y z) #(x y z)) >>> >>> Then I could readily use the existing vector functions, such as >>> vector-map without having to define my own. But I don't super like this >>> because I have to define my own accessor functions like vector-i and >>> point-y and also don't get predicates like vector? for free. >>> >>> Another way is that I could use structs, but then I'm stuck implementing >>> things myself and across the structs. To avoid the latter point, I could >>> use pattern matching. So something like: >>> >>> (struct vector (i j k)) >>> (struct point (x y z)) >>> >>> (define (tuple-map proc tuple) >>> (match tuple >>> [(struct vector (i j k)) (vector (proc (vector-i tuple)) >>> (proc (vector-j tuple)) >>> (proc (vector-k tuple)))] >>> [(struct point (x y z)) (point (proc (point-x tuple)) >>> (proc (point-y tuple)) >>> (proc (point-z tuple)))] >>> [(struct color (r g b)) (color (proc (color-r tuple)) >>> (proc (color-g tuple)) >>> (proc (color-b tuple)))])) >>> >>> But of course, this map doesn't take multiple tuples. And this feels >>> awkward, because I'll need to implement other things, like fold. Map and >>> fold would be used in defining new operators on vectors and points, like >>> addition, normalization (for vectors only), etc. >>> >>> The ideal thing would be that I could define a struct for these types, >>> that had the accessor functions like vector-i and predicates likes >>> vector? but was actually represented by a vector (in the Racket sense) >>> underneath the hood. Does something like this exist in Racket (not classes >>> please). >>> >>> In F#, I did this same thing using F#'s records for the vector, point, >>> and color data types, and they inherited an ITuple interface (F#'s >>> immutable, functional data types can implement interfaces). Can Racket's >>> stucts inherit from interfaces? Is there something I can do with generics? >>> >>> Thanks for any help on this design. >>> >> -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/b57b6072-391c-4bac-bac5-670a974a2bcfn%40googlegroups.com.

