-1

I find that let has too many brackets. For example, when writing the following block of code, it was very easy to misplace lets many closing brakcets.

(define (adder n)
    (let ((a 1))
        (+ a n)))

All of these brackets are clearly necessary for huge let blocks, but they feel redundant for smaller calls. Does Scheme have any syntactic sugar for trivial calls to let? For example, what about cases where I only want to locally bind one variable? I had considered define, but apparent it's dangerously dependent on your choice of implementation. Is there any built-in solution to this that doesn't share that flaw? I'd prefer to not have to write a macro. Essentially, I'm looking for the procedure that is to let what if is to cond.

J. Mini
  • 1,868
  • 1
  • 9
  • 38
  • In Common Lisp you can do, e.g., `(let (a b c) ;; body)` and `a`, `b`, and `c` will all be bound to `nil`. Or you could do `(let (a (b 2) c) ;; body)` to get `nil` bindings, but `b` bound to 2. – ad absurdum Feb 02 '21 at 12:40

2 Answers2

3

The only other way to do it is with a lambda I guess:

((lambda (a) (+ a n) 1)

But:

I find that let has too many brackets.

You may need to switch to another language (it may sound harsh, but I mean it in a friendly way). If the number of parentheses is too high you might better enjoy languages that have less parentheses overall, because in Scheme no amount of macros will remove the fact that parentheses are frequent characters to see.

[...] it was very easy to misplace lets many closing brakcets.

It can be the case if you are writing your code in an editor that does not highlight matching parentheses and does not indent nested forms. Because in editors that support Lisp and Scheme (e.g. Emacs), misplacing a parentheses is usually not a risk (or at least, it becomes quickly apparent that there is a mistake if the (automatic) indentation goes too much on left or on right).

coredump
  • 37,664
  • 5
  • 43
  • 77
  • Is there a particular recommended DrRacket setting that you think that I may have disabled? – J. Mini Feb 02 '21 at 13:25
  • I don't use it much but I guess you can have a look at https://docs.racket-lang.org/drracket/prefs-explanation.html to see if some of the preferences are enabled – coredump Feb 02 '21 at 13:44
0

You have macros: you just need to invent the language you want.

For instance, how about this simple with form:

(define undefined #f)

(define-syntax with
  (syntax-rules ()
    ((_ (var val) form ...)
     (let ((var val)) form ...))
    ((_ (var) form ...)
     (let ((var undefined)) form ...))
    ((_ var form ...)
     (let ((var undefined)) form ...))))

Now things like

(with (a 2) ...)

(with (a)
  ;; a is undefined initially
  ...)

(with a
  ;; same as previous
  ...)

Will be fine

Or you can get much fancier (the below is minimally tested in Racket's R5RS language, and definitely does not catch all the function definition syntaxes I think):

(define-syntax binding
  (syntax-rules (bind)
    ((_ (bind (f arg ...) body ...) form ...)
     (letrec ((f (lambda (arg ...) body ...))) (binding form ...)))
    ((_ (bind (f . arg) body ...) form ...)
     (letrec ((f (lambda arg body ...))) (binding form ...)))
    ((_ (bind var val) form ...)
     (letrec ((var val))
       (binding form ...)))
    ((_ form)
     form)
    ((_ form1 form ...)
     (begin form1 (binding form ...)))))

And now you can say

(binding
 (display "here")
 (bind a 2)
 (display "there")
 (bind (f) (display a))
 (f)
 a)

for instance. And then you can add

(define-syntax define/binding
  ;; Does not get all the possible fn definition syntaxes for sure
  (syntax-rules ()
    ((_ var val)
     (define var val))
    ((_ (f arg ...) body ...)
     (define (f arg ...)
       (binding body ...)))
    ((_ (f . arg) body ...)
     (define (f . arg)
       (binding body ...)))))

And now

(define/binding (ts x)
  (display x)
  (bind x^2 (* x x))
  (+ x x^2))

Or whatever you want.