Skip to content(if available)orjump to list(if available)

Functions Are Asymmetric

Functions Are Asymmetric

8 comments

·October 12, 2025

d_tr

Functions map members of a set A to members of a set B. These can simply be Cartesian products whose members are tuples. In my dream PL syntax a function call would be a function name followed by a tuple, and that tuple would be no different than the tuples you would use in any other part of the program (and so you could use all the tuple manipulation library goodies). If the function preserves any other structure of the type, like an identity element, that could be stated so you could have morphisms. And that identity element or other properties could be declared just as other stuff like 'const' are declared, and since the compiler can't verify all these stated properties, it's on the user to provide correct info, just like it's on the user to write a correct program, so nothing lost here, and anything more, like verification by the compiler, would be a bonus.

Mathematicians have been packing all this stuff nicely for a couple of centuries now, maybe we could use more of their work on mainstream computing, and it could also be a nice opportunity to get more people to appreciate math and structure.

Something that has side effects all over the place should just not be called a function, but something else, maybe "procedure" would be an appropriate, clear term.

WJW

Haskell is much like this? A function like `borp :: a -> b` maps from type a to type b. If you want to have side effects like mutable state, you need to encode that in the function signature, like `borpWithState :: a -> State s b`, where s is the type of the mutable state.

In this case it's almost the opposite of most programming languages. In (say) Ruby or Java, any function or method can do anything; write to stdout, throw exceptions, access the network, mutate global state, etc. In haskell, a function can only do calculations and return the result by default. All the other things are still possible, but you do have to encode it in the type of the function.

EDIT: The annotations you mention with regards to identity elements etc do exist, but they live mostly on the data structures rather than on the functions that operate on those data structures.

agumonkey

There was one attempt at creating a language splitting both pure function and effectful procedures. Any construct with a procedure call was automatically/effectively typed as a procedure. But I can't recall the name so far..

paulddraper

That’s cool function coloring.

C++ sort of has this, with const.

hardlianotion

I am a fan of C++ const, but I don't really see what it has to do with effect labelling in this way.

asimpletune

Functions can accept/return multiple values though?

// In typescript const [a, b, c] = foo(d, e, f)

You could even pass this to itself

foo(…foo(d, e, f))

Also one definition of a function is a map from a domain to a range. There’s nothing that forbids multiple values, or is there?

PropagandaDude

> Maybe that doesn’t seem strange. It’s just how we’re used to functions working. Ah, those steeped in functional programming might say, but maybe this is the wrong way to look at it. Because if we curry functions and use partial application, we can say that they always have one argument and return one value, and then they are symmetric.

Ah, those steeped in functional programming might say, but maybe this is the wrong way to look at it. Because if we represent the represent the functions with explicit continuations, we can say that they have N arguments and pass N arguments to their continuations, and then they are symmetric.

It seems like this has fertile overlap with Scheme and the (concurrent computatation) Actor model.

Of course, I can imagine the Execution control library authors know full well about those, with existing C++ goals and designs making that a bridge too far.

ccppurcell

Sorry if this is low effort, but I wanted to show some appreciation for a subtle Monty Python reference here! I won't spoil it though...