|
|
|
|
|
by sargstuff
924 days ago
|
|
from a assembly language structure point of view: 'pure' macros -> no state, everything registers as global. functions -> stack state, everything's local. non-locals get what ever maxwell's deamon decides to provide. methods -> heap state, methods to madness of functional local globals. at runtime, allows for everything to be routine or not. |
|
- Macros: arguments are interpreted as syntax, produces syntax, typically runs at compile-time. Their use case is anything functions can't do, e.g. define things or interpret syntax "abnormally" (different than parent language)
- Function: arguments are interpreted "normally" as values, outputs a value, usually runs at runtime.
- Method: function where one of the inputs is denoted as "self". Semantically there's no difference between `a.f(...)` and `f(a, ...)`, and some languages let you do both.
- Fexprs (https://en.wikipedia.org/wiki/Fexpr): weird macro/function hybrids, arguments are interpreted as syntax, but it produces a value and runs at runtime. I only know they exist in LISP and R, and only know how they work in R: certain operations (like assigning to a variable) evaluates the argument, the argument won't be evaluated if execution never reaches these operations (like if the assignment is in an `if` which doesn't get triggered; in other words, arguments are lazy), and special functions like `substitute` will extract the argument's syntax (e.g. if `⟦f⟧ = function(a) subsitute(a)`, `⟦f(foo(bar))⟧ = <syntax object foo(bar)>`; now if ⟦g⟧ = function(a) f(a)`, `⟦g(foo(bar))⟧ = <syntax object a>`). Personally I don't like these, and prefer separate macros and functions, which I believe can accomplish anything fexprs can with less confusing semantics and accidental bugs. But they're an interesting concept I just listed here because they're like a function or macro, but neither.