I think of let as a “parallel assignment”. Here’s an example.
(define (f x y)
(let ([y x]
[x y])
(- x y)))
honestly I’m of the opinion that you’re right, and therefore everyone should just always use define and let the schemify compiler pass figure it out
Not yet but that would be so awesome, I recommend preserving this idea in a github issue
idk, define makes it impossible to shadow. In Rhombus, I hope that define doesn’t have letrec behavior.
@joshibharathiramana it doesn’t work if the second version has to refer to the first one
I love [the] historical background!! I seem to be unable to understand anything unless someone tells me the story!
we could have a redefine form, though I’m not convinced either way that shadowing is worth that additional complexity
ML has define-like form that behaves like let, and when one wants it to be like letrec, just add the word “rec”.
@notjack re: always using define and letting schemify figure it out, I think there are advantages to explicitness over implicitness
I generally think there are too. I don’t think they outweigh the costs in this specific case.
I can’t recall ever being surprised by the let family, but I have been surprised by define. I don’t like surprises when coding :)
I guess I’m confused by the combination of “always use define” and “this specific case”, but that’s probably a tangent.
“this specific case” = let vs define
The only reason I’m commenting is it would be awful if Rhombus did away with the let family in favor of only having define.
I don’t think it would be that bad honestly. Other languages manage just fine with only block-scoped variable declarations.
To be clear, I’m speaking personally. It would be awful for me :)
Racket/Scheme’s scoping is very high on my list of attractive features, and one that differentiates it from many languages IMO.
Ah, gotcha. Would you be willing to share some code where you found it essential?
Here’s a recent example: https://racket.slack.com/archives/C06V96CKX/p1608759531295300
In this case, I prefer the explicitness of let, let* and letrec behaving in a specific way. I don’t like that define ’s behavior is context dependent.
I also like the fact that let encloses variables, and the code depending on those variables in one list. It’s tidy.
I’m not sure if this is a good question to ask in the beginners channel but here goes I guess I’m working through LACI (https://cs.uwaterloo.ca/~plragde/flaneries/LACI, it’s good) and I’m confused as to how to implement Kind as the type of types. I defined Kind to be a struct with no fields, and in my synthesis function I return Kind whenever synthesizing Type, and I error when synthesizing Kind
(for context I literally do not know where/who to ask about this if not here)
got it, I think