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.

Reply via email to