4 ms·
> > Focus more on libraries, frameworks, and applications > I think this is the most important thing. Say I'm writing a web app -- I want a language that can r
by memling 5y ago
> > Focus more on libraries, frameworks, and applications
> I think this is the most important thing. Say I'm writing a web app -- I want a language that can run on both the server and browser and that has a web framework.
One of the things that bugged me initially about Racket (and still kind of does) is the implicit typing of some of the functions. Take `length` for example:
$ racket
Welcome to Racket v7.2.
> (length "asdf")
; length: contract violation
; expected: list?
; given: "asdf"
; [,bt for context]
If I wanted to get the length of the string, I have to use `string-length` instead. (Same with vectors and other sequences.)
I personally favor default abstract protocols over explicit type:
$ sbcl
* (length "asdf")
4
I know that Racket's `sequence-length` will do the same thing, but it feels like a misnomer to have `length` really mean `list-length`. It introduces cognitive load where it's not desired, usually, and tends to make my code longer (slower to read, slower to type, etc.).
Maybe this is a silly peccadillo, but as I wrestled with Racket over time I found myself frustrated by this in a way that Python, say, didn't. It's these sort of bits that I'd like to see sanded away, and not the parentheses, to make for cleaner, easier-to-read, easier-to-write code. More concise syntax for indexing and other such things could be nice, too! Standard means for accessing nested hash tables (here's looking at you, deeply nested JSON! Who wants to `(hash-ref (hash-ref some-hash key1) key2)`? Yes, the language can accommodate more concise idioms through macros, but it seems reasonable to have standards around this access.
I really, really want to use Racket: I'm attracted to DSLs (maybe moth to flame) and boilerplate reduction, but it's been a challenge to get over these humps.
- samdphillips 5y agoYou're critique is valid. `length` `vector-length` and `string-length` are from the very monomorphic old Scheme libraries. The Racket module system does provide ways to use the names you want without having to change the core language. The `collections` package (https://pkgs.racket-lang.org/package/collections https://pkgs.racket-lang.org/package/collections) also smooths over some of these issues.
- memling 5y agoThanks for the tip! I'll look over the collections package for sure. It looks like some of the things of interest to me are there already. I knew there were historical reasons behind some of these things (just like the old complaints about car and cdr not being called first and rest). Sometimes it feels like this hewing to history comes with some baggage that makes adoption a little more challenging. I find myself writing the following in some of my projects, for example: (define-syntax (hash-ref* stx) (syntax-case stx () [(_ hsh k1) #'(hash-ref hsh k1)] [(_ hsh k1 k2 ...) #'(hash-ref (hash-ref* hsh k1) k2 ...)])) So that I can do something like: > (define hsh '#hash((a . #hash((b . c))))) > (hash-ref* hsh 'a 'b) 'c I feel a little silly each time because it seems like the sort of thing that should just "be there," in the way you can do something like hsh['a']['b'] in Python. Of course there are ways to make it a bit more like Clojure--I think Greg Hendershott created a Clojure-like layer called rackjure--so that you can access using the variable name, etc. It would be nice to have something standardized to make the ergonomics nicer.
- soegaard 5y agoNote that Scheme made this choice in order to make it simpler for compilers to produce efficient code.