Several programming languages offer syntax shortcuts to deal with the notion of "current" or "topic" variable.

A topic variable is a special variable with a very short name which can also often be omitted.

Demonstrate the utilization and behaviour of the topic variable within the language and explain or demonstrate how the topic variable behaves under different levels of nesting or scope, if this applies, within the language.

For instance you can (but you don't have to) show how the topic variable can be used by assigning the number 



3


{\displaystyle 3}

 to it and then computing its square and square root.




 
#lang racket
 
(module topic1 racket
  ;; define $ as a "parameter", but make it look like a plain identifier
  (provide $ (rename-out [$if if] [$#%app #%app]))
  (define current-value (make-parameter #f))
  (define-syntax $
    (syntax-id-rules (set!)
      [(_ x ...) ((current-value) x ...)]
      [(set! _ val) (current-value val)]
      [_ (current-value)]))
  ;; make an `if' form that binds it to the condition result
  (define-syntax-rule ($if C T E)
    (parameterize ([current-value C])
      (if $ T E)))
  ;; function application with []s uses the topic variable for the first arg
  (define-syntax ($#%app stx)
    (syntax-case stx ()
      [(_ f x y ...) (equal? #\[ (syntax-property stx 'paren-shape))
       #'(parameterize ([current-value x]) (f y ...))]
      [(_ f x ...) #'(f x ...)])))
 
(module topic2 racket
  ;; better variant: define `$' as a syntax parameter, which is adjusted to an
  ;; actual local binding; make it work in `if', and have a function definition
  ;; form that binds it to the actual arguments
  (provide $ (rename-out [$if if]) defun)
  (require racket/stxparam)
  (define-syntax-parameter $ (λ(stx) (raise-syntax-error '$ "not in scope")))
  (define-syntax-rule ($if C T E)
    (let ([c C]) (syntax-parameterize ([$ (make-rename-transformer #'c)])
                   (if c T E))))
  (define-syntax-rule (defun name body ...)
    (define (name arg)
      (syntax-parameterize ([$ (make-rename-transformer #'arg)])
        body ...)))
  )
 
(module sample1 racket
  (require (submod ".." topic1))
  (if (memq 2 '(1 2 3)) (cadr $) 'missing)
  ;; => 3
  (define (foo) (list (sqrt $) (* $ $)))
  [foo 9]
  ;; => '(3 81)
  )
(require 'sample1)
 
(module sample2 racket
  (require (submod ".." topic2))
  (if (memq 2 '(1 2 3)) (cadr $) 'missing)
  ;; => 3
  (defun foo (list (sqrt $) (* $ $)))
  (foo 9)
  ;; => '(3 81)
  )
(require 'sample2)
 