Home Forums Scheme let vs let*

Viewing 4 reply threads
  • Author
    Posts
    • #9495
      Rob DudaRob Duda
      Participant

      I would like to get an official stance from Nexj on usage of let vs let*. I have always considered it a best practice to use let when you can and only use let* when it makes the code easier to read.

      Based on some research I have also found that let allows the interpreter to bind in parallel where let* must bind sequentially. So regardless of whether Nexj Scheme binds in parallel today or not, using let allows for the optimization.

      Any insight or guidance would be much appreciated.

      Thanks in advance,

      Rob

      0
    • #9504
      Vassiliy Iordanovvi
      Participant

      >I have always considered it a best practice to use let when you can and only use let* when it makes the code easier to read.

      Yes, I also recommend this.

      >So regardless of whether Nexj Scheme binds in parallel today or not, using let allows for the optimization.

      Currently, let compiles to a more efficient code than let*.

      I prefer using define at the top of the functions, to reduce the indentation in cases where the special let and let* semantics is not needed. This is also more efficient than let*.

      Finally, letrec and letrec* have the same semantics as define, i.e. one can access the other variables during initialization, as an extension of the Scheme spec.

      Best regards,
      Vassiliy

       

      0
    • #9521
      Louis PaceLouis Pace
      Participant

      Vi, I’m hoping you can add some clarification to your response. Are you actually suggesting that global variables (define) are preferable to local (let, etc.)?

      What would be some examples of what either of you would consider to be valid use case for let or let*? Specifically, when (in your opinion) would let* make code easier to read? I’m asking this from the point of view that let, let*, etc. should be used often, as it facilitates cleaner, more readable code.

      Thank you.

      0
    • #9531
      Vassiliy Iordanovvi
      Participant

      >Are you actually suggesting that global variables (define) are preferable to local (let, etc.)?

      No, these are local, so called “internal definitions”: https://people.csail.mit.edu/jaffer/r4rs_7.html#SEC43

      These are mentioned briefly in later Scheme specs, but R4RS is the last readable one, IMO.

      >Specifically, when (in your opinion) would let* make code easier to read?

      let* is used instead of let based on dependency between the variables, rather than readability. See
      https://people.csail.mit.edu/jaffer/r4rs_6.html#SEC34: “In a let expression, the initial values are computed before any of
      the variables become bound; in a let* expression, the bindings and evaluations are performed sequentially”. So, if one has
      (let* ((a (+ x 1)) (b (* a 3)) …), and both a and b are used within the scope established by this let*, and b is computed
      in terms of a, one must use let* instead of let, otherwise b cannot be computed in terms of the just defined a: let would
      use “a” from an outer scope, e.g. global. If there is no such dependency, or the variable is used only once for the
      computation of another variable, one should use let instead, i.e., for the latter case, one would write just (let ((b (* (+
      x 1) 3))) …).

      My approach for improving code readability is keeping the procedure code short and declaring most of the variables and local
      procedures on their top with internal (local) define. let and let* can be used to move a variable declaration close to where
      it is used first, but often this indicates a new “theme” in the procedure, which might deserve having a dedicated named
      local procedure for it.

      Best regards,
      Vassiliy

      0
    • #9541
      Louis PaceLouis Pace
      Participant

      Thank you for that clarification.

      0
Viewing 4 reply threads
  • You must be logged in to reply to this topic.