Какое смешное совпадение! Я знаю, что один язык обладает этим свойством, он существует с понедельника, здесь: https://github.com/drcz/ZJEB
Предполагалось, что это будет отчасти шутка и отчасти эксперимент в выразительности; вот сессия РЕПЛ с вашим примером:
(-- ALGORITHMIC LANGUAGE ZJEB v0.1 --)
copyleft 2016/08/08 by Scislav Dercz
type (halt) to quit
READY.
>(def func1 (bind (x) (* x x)))
(new shorthand func1 memoized)
>(def func2 (bind (x) (+ x 1)))
(new shorthand func2 memoized)
>(def a 1)
(new shorthand a memoized)
>(def b (func1 a))
(new shorthand b memoized)
>(def c (func2 b))
(new shorthand c memoized)
>c
2
>b
1
>(def a 2)
(new shorthand a memoized)
>c
5
>b
4
и вот проще один
>(def x 5)
(new shorthand x memoized)
>(def y (* x x))
(new shorthand y memoized)
>y
25
>(def x 3)
(new shorthand x memoized)
>y
9
Дело в том, в отличие от схемы (или любой другой сюсюкать я знаю), то «DEF» форма делает не оценивать второй операнд - он просто создает синтаксическую «стенографию» для данного выражения. Таким образом, в любое время, когда оценщик находит символ, он пытается найти его в среде (т. Е. Привязки переменных значений, созданных с помощью формы «bind» - это вариант соответствия шаблону «lambda» с несколькими вариантами из lisp) , и если он терпит неудачу, он также проверяет список определений - когда он преуспевает, он сразу же оценивает соответствующее выражение.
Он не предназначен для того, чтобы делать то, что вы описываете (и вообще не полезно вообще, только заставляя оценщика делать немного больше работы в текущей реализации), поскольку язык является чисто функциональным (и фактически возможно только переопределение указаний на сокращение, для удобства работы с repl). Это «особенность» находится там, потому что я хотел бы думать о рекурсивных определений как
(def fact (bind (0) 1
(n) (* n (fact (- n 1)))))
на самом деле означает бесконечное выражение
(bind (0) 1
(n) (* n ((bind (0) 1
(n) (* n ...)) (- n 1)))
в духе «Lattice диаграмм потоков» Dana Скотта.
Обратите внимание, что бесконечные структуры данных, как
(def evil `(ha ,evil))
сделать перерыв интерпретатор при попытке оценить их, хотя я, вероятно, следует сделать их законным [с помощью частично ленивой оценки или что-то], а также .. .
На ваш вопрос вы можете взглянуть на различные функционально-реактивные языки программирования/рамки, поскольку они обеспечивают поведение, о котором вы просите, по крайней мере для определенных типов данных.
Комментарий Svik также очень приятный, электронные таблицы работают так (и некоторые люди утверждают, что они являются FRP-языком).
(ленивая оценка вещь скорее не так, потому что переменная область на любом «ленивом» языке, который я знаю, лексика - лень + динамическое масштабирование будет слишком запутанным, как указано выше mcoblenz).
Возможно, вы захотите взглянуть на функциональные языки, такие как Haskell (который является одним из «чистейших» функциональных языков) – DAXaholic
Lazy оценка? https://en.wikipedia.org/wiki/Lazy_evaluation – Wickramaranga
Таблицы Excel подобны подобным работам. – svick