Show FoC: I started writing up a language I've bee...
# thinking-together
j
Show FoC: I started writing up a language I've been brooding over for the past few months - https://scattered-thoughts.net/writing/imp-sets-and-funs/. The first post is not very future-of-coding, but just wait...
❤️ 9
s
Dude! Love this. I see now why you like datalog so much. I’m into your deontational semantics. It’s so FoC! Question why does this eval to none? I would’ve guessed the identity func would return colors
j
fruit -> fruit
is the set of
("apples" x "apples" | "foo" x "foo" etc...)
. So when you join it with colors, the intersection is empty.
colors (fruit color -> color)
will return just the colors, without the fruits.
Or
colors (fruit -> some)
s
Doesn't
fruit -> fruit
also contain
(apples x red) x (apples x red)
?
j
Everything is first order. So
(apples x red) x (apples x red)
=
(apples x red x apples x red)
which has arity 4.
fruit -> fruit
has arity two.
You are not the first functional programmer to be confused by this. Maybe I should just change
->
to a different symbol that has less preconceptions attached...
Here is a sketch of the denotation:
Copy code
Scalar = Integer + String
Value = union_all({ Scalar^i | i in Naturals })
Environment = Name -> Value

M: Environment -> Expression -> Value
M[[ env, 42 ]] = {(42,)}
M[[ env, A | B ]] = union(M[[ env, A ]], M[[ env, B ]])
M[[ env, A & B ]] = intersect(M[[ env, A ]], M[[ env, B ]])
M[[ env, A x B ]] = product(M[[ env, A ]], M[[ env, B ]])
M[[ env, !A ]] = if M[[ env, A ]] = {} then {()} else {}
M[[ env, name ]] = env(name) // handwave about no undefined names
M[[ env, let name = A in B ]] = M[[ bind(env, name, M[[ env, B ]]), C ]] 
M[[ env, A B ]] = union_all({ product(a[n..], b[n..]) | a in M[[ env, A ]], b in M[[ env, B ]], n = min(len(a), len(b)), if a[1..n] = b[1..n] })
M[[ env, name -> B ]] = union_all({ product({(a,)}, M[[ bind(env, name, a), B ]]) | a in Scalar })

D: Expression -> Value
D[[ A ]] = M[[ (_ -> missing), A ]]
w
@jamii glad to see you're still working on an "Imp". About the
->
notation, let me tell you what my first guess from it, then you can evaluate whether it's good or not. (I'm sure I'd figure it out from reading carefully, but the whole point is first impressions.) Now
->
should have a functiony, implicationy sort of meaning.
let inc = a -> a + 1
. Looks like a typical lambda to me, introducing
a
as a variable, the normal thing. "Well, the value of inc is a set of tuples." Do we really mean "is"? Does it work basically the same way? Let's see...
"apples" colors
. Oh! Yes. There it is. Okay, I'll buy it. You can use a
->
construct in the same places you can use a tuple. So sure, "inc is a set of tuples." Though not any set of tuples... One would initially expect a
->
to associate one output for every input. But that's totally not how it is going to work! In fact, I expect
"apples" (fruit -> fruit colors)
to be
"red" | "green"
. Moreover, Eta conversion should hold with
x -> x t
being the same as
t
always.
Are you familiar with Barry Jay's pattern calculus?
(Oops, bad use of
x
up there. Hmm... thinking.)
(Goddamnit fix your Repl to let me select text.)
👍 1
@stevekrouse let me blow your mind:
Copy code
let hmm = a -> a x a in
(3 x 3) q
Now, @jamii I didn't think I'd have a syntax recommendation for you, but what do you think of this for the same expression?
Copy code
hmm = [|a| a, a, a]
3, 3 . hmm
That's a few ideas at once. Comma is less assuming than
x
. Though
let ... in
is easy to parse it's annoying to type/read. but importantly with the Smalltalk block syntax, you aren't conflating the introduction of a variable with a mapping of that variable to something else. And the scope is explicit whereas something like a Prolog
hmm(A, A, A).
doesn't compose particularly well. Finally, notice that with the block syntax,
dec = [|a| a + 1, a]
feels really natural.
e
this is a very abstract notation, starting to remind me of APL. Not sure having abstract semantics is helpful to the millions of new programmers coming online.
w
You mean the denotational semantics? That much is tailored to a really specific audience.
@jamii One thought about keeping the set semantics pure. Anytime you display a set, the elements have to be in some order. Instead of making the order a random, non-deterministic, or an implementation accident, require that it be defined. You can have a default. It can even be implicit and subtle. For instance, in an list like
wow = 6 | 5 | 3
, you could print
6 | 5 | 3
by default instead of the standard order
3 | 5 | 6
. There's a natural way to extend this definitional order across operators. It's not simplest, but it is least surprising in its own way. Of course, the operators wouldn't commute with respect to order, but I think associativity is preserved.
b
@wtaysom it looks like you can select text it's just the style doesn't show. i was able to contrl+a ctrl+c
w
Sure enough! Still.
j
Fixed
👍 1
b
Fix confirmed @jamii 🙂