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