Closures are a feature of lexical scoping and dynamic function definition. For example, if you create a lambda inside another function, variables that are in the outer scope must be preserved for that lambda. When that lambda is later called, those variables that would have been available inside of the scope it was defined in are then activated in the current call's scope.
newLisp is dynamically scoped. Any time a function is called, it is called within the current scope, not the scope it was defined in.
newLisp has contexts, however, which are lexical namespaces that can simulate closures. You can do that with a functor (a function with the same name as its context, like foo:foo). The context preserves the symbols in the functor's scope, and they are available when the function is called later, no matter where it is called from.
However, the big difference is that within a context, dynamic scoping rules still apply. It is not a lexical scope. It is a lexically defined namespace that is parallel to the MAIN, dynamic scope. So:
Code: Select all
(setq foo:x "Hello world")
(define (foo:foo) (lambda () (println x)))
(setq x "Hello Corm")
(setq my-foo (foo:foo))
(my-foo) ; => prints "Hello Corm"
In Scheme, it would work like this:
Code: Select all
(define foo
(lambda ()
(let ((x "Hello world"))
(lambda () (print x)))))
(define my-foo (foo))
(define x "Hello Corm")
(my-foo) ; => prints "Hello world"