greg
2021-4-7 11:33:40

In some projects I’ve tried a naming convention where structs are Capitalized. (Similar to how Typed Racket capitalizes types.)


greg
2021-4-7 11:34:26

It seemed fine; I didn’t love it or hate it. (I think I might be more likely to use or recommend it, in a project where the struct names are a bigger proportion of the code. But I’m not sure.)


greg
2021-4-7 11:48:30

@notjack What do you do for something that is naturally just one word, like “apple”? Add a placeholder word?


greg
2021-4-7 11:50:28

Wow I ended up on wikipedia for “lorem ipsum”, which had a link to “metasyntactic variable”, which in turn had a link to “smurf”. I had no idea.


greg
2021-4-7 11:50:58

Although I knew what a Smurf looked like, I had no appreciation for their language. TIL. :slightly_smiling_face:


samth
2021-4-7 13:33:17

That seems like the right idea to me. cc @hazel


sschwarzer
2021-4-7 13:49:32

@greg Capitalized type names are also common in the signatures in HtdP.

Did you do anything special with the accessors? For example, if I define a (struct Board (data)), the default accessor would be Board-data. On the other hand, I have defined board-ref as a regular function taking a Board as first argument, and I’m unsure if having the capitalized names only for the accessors is a “bug” or a “feature.” That said, I guess I’d be ok with using the default naming for the accessors and lowercase names for my own functions that do something with the struct instances.

What do you think?


sschwarzer
2021-4-7 13:51:57

By the way, if I use a prefix word for the struct, I’d probably be even more confused whether the names of my functions working on the struct instances should have the prefix, too.


greg
2021-4-7 13:53:00

I found that capitalized struct names actually helped with accessors when the struct name includes hyphen. e.g. chess-board-width-pixels. Quick, is struct chess the struct and board-width-pixels the field? Or is is chess-board and width-pixels? It’s clearer with Chess-Board-width-pixels. Arguably uglier, but clearer.


greg
2021-4-7 13:53:12

Sometimes it’s just a sea of undifferentiated hyphens.


greg
2021-4-7 13:53:26

I guess a struct option to use something other than - might help more.


greg
2021-4-7 13:54:38

Like I said, I don’t have a strong opinion here — I’m getting too old for strong opinions about these things :slightly_smiling_face: — but I think some of these options can be clearer. Ultimately it depends on the audience. If a project is a team, whatever they agree to, is “best”.


sschwarzer
2021-4-7 13:54:45

> I guess a struct option to use something other than - might help more. Totally agreed.


greg
2021-4-7 13:56:10

Maybe emdash would be a better struct default (I’m only half-joking)


sschwarzer
2021-4-7 13:56:12

@greg In my case it’s a personal project, but I can’t stop thinking about good design nevertheless. :smile: Also, I’m the audience of my software, so it’s important how well I find my way around it. :slightly_smiling_face:


greg
2021-4-7 13:57:16

Oh for sure! I’m not belittling your interest in that. I still get picky about that, too. I just can’t justify my choices to someone else, too seriously, anymore. :slightly_smiling_face:


sschwarzer
2021-4-7 19:27:58

I want to write a for/... loop and exit it as soon as an expression calculated in the loop body is “true-ish.” The result of the loop should be this calculated expression.

My current approach looks like this: (for/last ([guess (in-range 1 (add1 9))] #:break candidate-solution) ... (define candidate-solution (if ... something-true #f))) but I get a stacktrace complaining that candidate-solution is an unbound identifier.

Is it possible to write such a loop with any of the for/... forms and if yes, how?


samth
2021-4-7 19:33:29

#lang racket (for/last ([i (in-range 100)]) (define candidate (* i i)) #:break (> candidate 50) (list i candidate))


samth
2021-4-7 19:33:42

@sschwarzer ^


sschwarzer
2021-4-7 19:34:42

@samth Aha, I wasn’t even aware I could use #:break inside the loop body. I always thought it has to be in the “head” of the for form.


sschwarzer
2021-4-7 19:34:49

I’ll give it a try.


sschwarzer
2021-4-7 19:38:08

I can’t tell yet if it works correctly, but at least I don’t get any error messages about how I write the for loop.


sschwarzer
2021-4-7 20:35:23

What I needed was #:final instead of #:break , but otherwise it worked. :slightly_smiling_face:


samdphillips
2021-4-7 20:49:42

Woah. I didn’t know that either. I kept pushing things up into the sequence block using in-value


sorawee
2021-4-7 20:51:07

I think you need to do that for #:when.


samdphillips
2021-4-7 20:51:54

Ahh yes, most of the time I’m using #:when so doesn’t change my behavior that much.


sschwarzer
2021-4-7 20:55:59

@samdphillips Can you show an example?


samdphillips
2021-4-7 20:57:23

Actually was tweaking this code this morning (define (all-procinfo) (for*/list ([rel-pid-dir (directory-list "/proc")] [a-path (in-value (build-path "/proc" rel-pid-dir))] #:when (pid-path? a-path)) (procinfo a-path)))


sschwarzer
2021-4-7 20:57:46

My solver works. :tada: https://git.sr.ht/~sschwarzer/sodoku-solver/tree/main/item/sodoku-solver.rkt#L215 (Yes, this can probably made faster, but it was more important for me to have clear code than the fastest possible implementation, in which case I would have done some things differently.)


sschwarzer
2021-4-7 20:58:23

This was an exercise from an online course I attended last week.


ben.knoble
2021-4-7 21:47:50

Related: does Racket have anything like Clojure’s reduced? https://clojuredocs.org/clojure.core/reduced Useful when short-circuiting “loops” built out of fold/map/filter idioms, e.g., like this state-machine: https://gist.github.com/benknoble/f6d157217a7a814450d6fc9cf45625ee#file-parens-clj


notjack
2021-4-7 21:59:21

> @notjack What do you do for something that is naturally just one word, like “apple”? Add a placeholder word?

Suffer


sorawee
2021-4-7 22:01:51

Generally, you can use continuation, like let/ec or let/cc.

(let/ec reduced (foldl (λ (v a) (if (< a 100) (+ a v) (reduced 'big))) 0 (range 10))) (let/ec reduced (foldl (λ (v a) (if (< a 100) (+ a v) (reduced 'big))) 0 (range 20)))


notjack
2021-4-7 22:02:04

Maybe resyntax should suggest pushing #:break into the body sometimes?


notjack
2021-4-7 22:03:19

You could also use reducers, but it would be bulkier


sorawee
2021-4-7 22:03:37

Within for-like forms, #:final could potentially work.

(for/fold ([a 0]) ([v (in-range 10)]) (define condition (< a 100)) #:final (not condition) (if condition (+ a v) 'big)) (for/fold ([a 0]) ([v (in-range 20)]) (define condition (< a 100)) #:final (not condition) (if condition (+ a v) 'big))



sschwarzer
2021-4-7 22:13:18

If the advice is appropriate most of the time, this sounds like a good idea. :+1:


sschwarzer
2021-4-7 22:14:00

I think I’m going with the capitalized types for now. :slightly_smiling_face:


kellysmith12.21
2021-4-7 22:20:45

I’ve yet to come up with naming conventions that I like. Sometimes, I’ll use mathematical conventions, using single letters and symbols; sometimes, single words; sometimes, short phrases.


greg
2021-4-8 01:13:36

@notjack Don’t suffer. I recommend apple-smurf. Seems weird? Give it time to grow on you. In fact, maybe start by really leaning in with names like apple- SMURF!.


greg
2021-4-8 01:13:59

Or if the struct has any mutable fields, apple-SMURF!! Nuances like that are what give a great naming convention that special obsessive frisson.


notjack
2021-4-8 01:14:27

so a predicate for a mutable struct would clearly be apple-SMURF!?, correct?


greg
2021-4-8 01:15:29

I think actually apple-SMURF!!?. But we should have a week-long 40-message email thread about it, to be sure.


notjack
2021-4-8 01:19:42

clearly, community consensus is important


samdphillips
2021-4-8 02:03:48

Is the type in there? Company policy says we must use hungarian notation.


kellysmith12.21
2021-4-8 03:00:12

Do things like <%> or /c count as Hungarian Notation, or are those sigils? Maybe someone should make a Grand Unified Theory of Name Ornaments…


hoshom
2021-4-8 05:20:23

@sschwarzer for/or also does precisely what you asked


hoshom
2021-4-8 05:22:20

eg. (for/or ([i (in-range 100)]) (define candidate (* i i)) (and (> candidate 50) (list i candidate)))


soegaard2
2021-4-8 06:14:33

Do we have an in-map ? (for/or ([c (in-map sqr (in-range 100))]) (and (> c 50) (list i c)))


notjack
2021-4-8 06:14:48

there’s a sequence-map


soegaard2
2021-4-8 06:15:39

Is that “inlined” when used with for?


notjack
2021-4-8 06:16:50

good question