kellysmith12.21
2020-9-11 08:00:05

What is the idiomatic way to represent a data type variant that contains no useful data (i.e. is a simple tag): a symbol, or a fieldless struct?


sorawee
2020-9-11 08:03:56

I personally like fieldless struct more than symbol. The problem with symbols is that it’s so easy to misspell, and there’s not really a way to prevent the mistake. With fieldless struct, the macroexpander can help you catch the mistake.


sorawee
2020-9-11 08:05:31

But idiomatically, I think it depends on other variants. If other variants are also structs, then it fieldless structs are definitely the idiomatic way and not symbols.


sorawee
2020-9-11 08:06:12

On the other hand, if other variants are numbers, booleans, etc., then symbols are usually used.


kellysmith12.21
2020-9-11 08:09:02

Ok. Since the other variants are structs, I’ll use a fieldless struct.


laurent.orseau
2020-9-11 08:20:35

You can still use https://docs.racket-lang.org/reference/symbols.html?q=gensym#%28def._%28%28quote._~23~25kernel%29._gensym%29%29\|gensym and name the symbol: (define my-special-symbol (gensym)) You don’t care about the actual name of the symbol, you only care that it’s something that cannot be eq? to anything generated elsewhere. Then you have to use the identifier my-special-symbol so if you misspell it you’ll be notified. (The symbol is uninterned, which means it can’t be written then read back to the same value)

The only other thing that fieldless struct give you is the corresponding predicate, but otherwise it’s also a little bit overblown compared to uninterned symbols.


laurent.orseau
2020-9-11 08:26:01

If you don’t want to use gensym you can equally still use https://docs.racket-lang.org/reference/symbols.html?q=gensym#%28def._%28%28quote._~23~25kernel%29._string-~3euninterned-symbol%29%29\|string-uninterned-symbol> : (define my-sym (string->uninterned-symbol "my-sym")) and this can be automated with a macro of course: #lang racket (require syntax/parse/define) (define-simple-macro (define-uninterned-symbol sym) (define sym (string->uninterned-symbol (format "~a" 'sym)))) (define-uninterned-symbol my-awesome-symbol) my-awesome-symbol ; 'my-awesome-symbol (eq? my-awesome-symbol my-awesome-symbol) ; #t (eq? my-awesome-symbol 'my-awesome-symbol) ; #f


laurent.orseau
2020-9-11 08:44:42

And since you didn’t ask for it, here’s a version that also creates the predicate: #lang racket (require (for-syntax syntax/parse racket/syntax)) (define-syntax (define-uninterned-symbol+predicate stx) (syntax-parse stx [(_ name:id) (with-syntax ([pred (format-id #'name "~a?" (syntax-e #'name) #:source #'name)]) #'(begin (define name (string->uninterned-symbol (format "~a" 'name))) (define (pred x) (eq? x name))))])) ;; Example: (define-uninterned-symbol+predicate abc) abc ; 'abc (eq? abc abc) ; #true (eq? abc 'abc) ; #false (abc? abc) ; #true (abc? 'abc) ; #false


sorawee
2020-9-11 09:22:21

If other variants are also structs, I still think that it’s more reasonable to use fieldless structs. As a plus, you will have a uniform pattern matching:

(match val [(nullary-node) ...] [(unary-node x) ...] [(binary-node x y) ...])


sorawee
2020-9-11 09:27:09

That’s not to say it’s not possible to pattern match symbols, but it would be less uniform:

(match val ['nullary-node ...] ;; also easy to misspell [(unary-node x) ...]) (define nullary-node 'nullary-node) (match val [(== nullary-node) ...] ;; it works I guess? [(unary-node x) ...])

(define (nullary-node? x) (eq? 'nullary-node)) (match val [(? nullary-node?) ...] ;; it works I guess? [(unary-node x) ...])


laurent.orseau
2020-9-11 09:27:45

I was considering the general case. If everything else are structs, I agree with you :slightly_smiling_face:


maxim_jaffe
2020-9-11 11:08:27

Hello, if a hash table only uses symbols as keys which of the equality predicates should I use? eqv? or eq?


maxim_jaffe
2020-9-11 11:08:55

for hash-ref


soegaard2
2020-9-11 11:08:56

Both would work. eq is fastest.


maxim_jaffe
2020-9-11 11:09:15

ok that’s what I thought, thanks :slightly_smiling_face:!


maxim_jaffe
2020-9-11 11:09:51

is it okay to build a hash table with symbols generated by gensym by the way?


soegaard2
2020-9-11 11:10:03

yes


maxim_jaffe
2020-9-11 11:12:48

alrighty thanks! Was trying to understand what would be a good correspondence to the value store of the first machine describe in the Van Roy book. Thought a hash table with gensym symbols would be good!


notjack
2020-9-11 17:27:53

laurent.orseau
2020-9-11 18:07:14

Downloading the whole of Rebellion just for this might be a little overblown maybe :wink:


laurent.orseau
2020-9-11 18:08:10

Though it’s a great way to entice exploration of the whole thing!


laurent.orseau
2020-9-11 18:09:16

You also have make-generative-token !


notjack
2020-9-11 18:18:51

yup :p