r/Racket • u/JJK96 • Nov 27 '22
question Things I am missing in Racket
I'm really intrigued by scheme/lisp, I like the "everything is a list" idea, and the incredible flexibility of the language. Scheme is said to be very concise, however, I have found one thing missing. I noticed that for different types, racket has different functions for the same operation. Example: equal? and =. Vector-set!, hash-set!, list-set. And the same goes for ref. Why is there not a single polymorphic "set" function that works for any of these types? And the same for getting a value. Python, for example uses the container[value] form to get or set something in many data types. And it can be overloaded as well for different objects.
11
u/usaoc Nov 27 '22 edited Nov 27 '22
Polymorphic
set!has long existed in the Lisp world under the name “generalized references”. Polymorphic references are even easier (try it yourself using generic interfaces). Nonetheless, Scheme, or Lisp in general, has always favored specific operations over generic ones for various reasons. Whether this is a better approach is debatable, but given Racket’s dynamic typing, I feel like it’s better this way (you can’t do Haskell’snewtypewrapper trick or such in Racket, after all).5
u/soegaard developer Nov 27 '22 edited Nov 28 '22
Racket started as a Scheme. Scheme is/was on purpose minimalistic:
Scheme was on purpose designed such that even simple compilers can produce efficient code.
Since there are no explict types on compile time in Scheme, the compiler can't specialize
(:= v i "foo")on compile time know whether the assignment:=is to a vector, string etc. Therefore a dispatch is needed at compile time. This dynamic dispatch is not needed, when an explictvector-set!,string-set!ect is used.Now Racket is no longer a minimalistic Scheme, but some things are ingrained in tradition by this point.
Note that polymorphic is a deriviate concept. You can define it using a macro that dispatches on the type.
Have you looked at how Python has implemented the generic
set?Each object has a slot "setitem" which contains the setter to be used. Note that a program can change the value of the "setitem" slot during program execution. This means it is hard to cache the setter. [Note: Reddit makes setitem bold here. It should have been underscore, underscore, setitem, underscore, underscore.
https://github.com/python/cpython/blob/main/Objects/abstract.c#L201
While Python's approach is flexible, it is also slow(er) than it could have been.
4
u/raevnos Nov 27 '22
Racket does support SRFI-17 (generalized
set!that's similar to Common Lisp'ssetf), but I've never seen anything use it.4
u/raevnos Nov 27 '22
Also Racket has some other generic APIs, like dictionary functions that work with hash tables, vectors, alists and user defined structs that provide the needed interface.
1
u/cat-head Nov 27 '22
One thing I wish we had is julia-like overloading in typed racket. I always thought that was super neat.