[racket-users] Re: Looking for idiomatic way to represent very similar but different data types

2021-01-31 Thread jackh...@gmail.com
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 

 
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 racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/a0220f5d-e278-454a-bc57-b7686551e486n%40googlegroups.com.


[racket-users] Looking for idiomatic way to represent very similar but different data types

2021-01-31 Thread making-a-racket
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 racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/8214d59a-d6de-445f-b203-b0a2b8c374cdn%40googlegroups.com.


Re: [racket-users] Moving a Rust/Haskell abstract algebra library to Racket?

2021-01-31 Thread Stuart Hungerford
On Sunday, 31 January 2021 at 08:07:27 UTC+11 Jens Axel Søgaard wrote:

Den tor. 21. jan. 2021 kl. 05.06 skrev Stuart Hungerford <
> stuart.h...@gmail.com>:
>
>> [...]
>> By using the Rust trait system (and later Haskell typeclasses) I could 
>> create structure traits/typeclasses that don't clash with the builtin 
>> numeric types or with the larger more production oriented libraries in 
>> those languages in the same general area of math.
>>
>> Once I added generative testing of the structure axioms I could 
>> experiment with, e.g. finite fields and ensure all the relevant axioms and 
>> laws were (at least probabilistically) met.
>>
>
> Not knowing Rust nor traits, I have amused myself writing a very simple 
> version of traits.
>  
>
> #lang racket
> (require (for-syntax syntax/parse racket/syntax))
>
> ;;;
> ;;; TRAITS
> ;;; 
>

Many thanks Jens.  This is an excellent example of Racket's 
build-your-own-abstractions philosophy at work.  (Although where I live I 
would have used bream or sharks instead of herring ;-)

If Hackett was still maintained I would probably use it too.

Thanks,

Stu




-- 
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 racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/4bd7fad3-0c68-46c0-9504-530b3d4e3ab4n%40googlegroups.com.