logoalt Hacker News

tomberttoday at 1:08 AM4 repliesview on HN

I remember I got a little confused when I was first learning TLA+, because what you normally call "functions" are "operators" [1], and what you'd normally call "maps" or "lists" are called "functions".

It was odd to me, because it hadn't really occurred to me before that, given infinite memory (and within a mathematical framework), there's fundamentally not necessarily a difference between a "list" and a "function". With pure functions, you could in "theoretical-land", replace any "function" with an array, where the "argument" is replaced with an index.

And it makes sense to me now; TLA+ functions can be defined like maps or lists, but they can also be defined in terms of operations to create the values in the function. For example, you could define the first N factorials like

    Fact == <<1, 2, 6, 24, 120>> 
or like this:

    Fact[n \in Nat] ==
        IF n = 0 THEN 1
        ELSE n * Fact[n - 1]


in both cases, if you wanted to get the factorial of 5, you'd call Fact[5], and that's on purpose because ultimately from TLA+'s perspective they are equivalent.

[1] At least sort of; they superficially look like functions but they're closer to hygienic macros.


Replies

nimihtoday at 4:11 AM

I remember having a similar sort of realization early in my career when trying to implement some horribly convoluted business logic in SQL (I no longer remember the actual details of what I was trying to do, just the epiphany which resulted; I think it had something to do with proration of insurance premiums and commissions): I realized that if I simply pre-computed the value of the function in question and shoved it into a table (requiring "only" a couple million rows or so), then I could use a join in place of function application, and be done with it. An obvious idea in retrospect, but the sudden dredging of the set-theoretic formulation of functions--that they are simply collections of tuples--from deep within my memory was certainly startling at the time.

show 1 reply
erutoday at 3:12 AM

> It was odd to me, because it hadn't really occurred to me before that, given infinite memory (and within a mathematical framework), there's fundamentally not necessarily a difference between a "list" and a "function".

You don't even need infinite memory. If your function is over a limited domain like bool or u8 or an enum, very limited memory is enough.

However the big difference (in most languages) is that functions can take arbitrarily long. Array access either succeeds or fails quickly.

show 2 replies
viraptortoday at 6:06 AM

Reminds me of many years ago when people were fascinated by the discussion about whether closures are objects or objects are closures. Yes... Yes they are.

dmeadtoday at 3:02 AM

Is this what the fp community calls referential transparency?

show 1 reply