Live data from Hacker News

What Color Is Your Function?

journal.stuffwithstuff.com

91–100 of 153 posts

Re: What Color Is Your Function?

#91
post #88
post #35

Earlier quoted context omitted.

I think the point is that there is no good effect-union type; this has to be pieced together with monad transformers where you might have that types "Atransformer (Btransformer C)" is not equal to "Btransformer (Atransformer C)". This is, for example, why Haskell has one monolithic "IO" monad instead of one for hitting the filesystem, one for HTTP requests, one for IORefs, etc. Haskell does not, for example, represen…

I'm kind of interested in knowing why you don't think that there isn't an isomorphism along the ordering of the monad transformers. Wouldn't it just be a question of rebuilding combinators so that they're targetting the right depth? Or am I missing something

I'll demonstrate the lack of an isomorphism via a counterexample.

Consider MaybeT and WriterT (and the basic Identity monad for the bottom of our stack)

    newtype MaybeT    m a = MaybeT   { runMaybeT   :: m (Maybe a) }
    newtype WriterT w m a = WriterT  { runWriterT  :: m (a, w)    }
    newtype Identity    a = Identity { runIdentity :: a           }
I'm going to claim that MaybeT (WriterT w Identity) is not isomorphic to WriterT w (MaybeT Identity). If we expand the first

    MaybeT (WriterT w Identity) a
    ==
    WriterT w Identity (Maybe a)
    ==
    Identity (Maybe a, w)
    ==
    (Maybe a, w)
And if we expand the second

    WriterT w (MaybeT Identity) a
    ==
    MaybeT Identity (a, w)
    ==
    Identity (Maybe (a, w))
    ==
    Maybe (a, w)
So we can see that the Maybe is wrapped around something different in each stack. So now to the claim that there's no isomorphism should be obvious---any witnesses to the isomorphism f and g would have to have that for all w, f (g (Nothing, w)) = (Nothing, w), but since g :: (Maybe a, w) -> Maybe (a, w) cannot fabricate an `a`, it must be such that g (Nothing, w) = Nothing which means that f :: Maybe (a, w) -> (Maybe a, w) cannot determine the right `w` to return.

Re: What Color Is Your Function?

#92

I'm really out on most of the "async" stuff, after having used it. (Mostly in Node and Tornado) Remember in the early 90s when Windows and Mac OS were "cooperatively" multitasked? Which is to say, you had to explicitly yield to allow other applications to run (or risk locking up the entire system). And then it was replaced with pre-emptive multitasking, which allowed the scheduler to figure out what process deserved…

How does one request "forget to yield"?

Re: What Color Is Your Function?

#93
post #92

I'm really out on most of the "async" stuff, after having used it. (Mostly in Node and Tornado) Remember in the early 90s when Windows and Mac OS were "cooperatively" multitasked? Which is to say, you had to explicitly yield to allow other applications to run (or risk locking up the entire system). And then it was replaced with pre-emptive multitasking, which allowed the scheduler to figure out what process deserved…

How does one request "forget to yield"?

Some of these cooperatively multithreaded implementations have "green" varieties of all your standard functions; these are greenlet-aware (that is, aware of the cooperative threading & I/O loop that's happening) functions that do things like, for example, sleep. So, you might have a my_green_library.sleep and a calls_the_os.sleep; the latter of which will yield the hardware thread directly to the OS, and block that thread completely until its done. Whereas the former will perform a sort of userland context switch, and note something to the I/O loop, and then sleep until the next event.

Worse, this problem makes composition hard: you need to know the entire implementation of any function you call, in order to be aware of whether or not it will cause the calling thread to block.

Re: What Color Is Your Function?

#94
post #60

A lot of commentors are mentioning that this is just a specific case of effect typing. Haskell and monads have been brought up as an example of effects typing, but I'd like to present another example that more closely resemble familiar static type systems. Nim[1], at least at one point (I'm looking at the current manual and can't find it documented), had support for tagging functions with a pragma and the compiler wo…

Custom pragmas in Nim are supported although I'm not sure they do what you're after. You may also be talking about Nim's effect tracking.

Nim also supports async await.

(I can't give you any links as I am on mobile right now)

Re: What Color Is Your Function?

#95
post #28

Earlier quoted context omitted.

Funny to consider this alongside Guido's refusal to add full anonymous functions to Python. His argument seems to be "If it's too long for a single-line lambda, then it's long enough to deserve a name"

Guido has a different, legitimate reason to not add multi-line lambdas to Python: they are super nasty to integrate with Python's grammar. Python has a strict grammar where statements (which use indentation) contain expressions, but never vice versa. Allowing statement-body lambdas would give you an expression form that contains significant indentation that could be embedded in the middle of some larger expression, l…

Nim also handles it and it works pretty well I think.

Re: What Color Is Your Function?

#96
post #54

So I've been writing javascript full time for a couple years at this point, client, server, and open source, and what I have adopted is coercing everything into promises, which I suppose would be the author's way of saying making everything red. If you have something that is not async mixed in with something that's async, you can still add it to the promise chain and it will resolve right away. If you have a library…

This is great for one's own projects, but if creating something for more than one's immediate project (i.e. libraries), it forces everyone else to adopt the same style.

Maybe those other projects are also using other libraries that don't use promises, so now there is a problem. Do you wrap the other library in promises too, if that is even a viable option for you?

Colorness is a problem for the whole ecosystem too.

Re: What Color Is Your Function?

#97
post #92

I'm really out on most of the "async" stuff, after having used it. (Mostly in Node and Tornado) Remember in the early 90s when Windows and Mac OS were "cooperatively" multitasked? Which is to say, you had to explicitly yield to allow other applications to run (or risk locking up the entire system). And then it was replaced with pre-emptive multitasking, which allowed the scheduler to figure out what process deserved…

How does one request "forget to yield"?

I'm mostly thinking Tornado/Python, where the async stuff happened via generators (IE, the "yield" keyword). But that meant there were large chunks of the python standard library that were basically off limits because they blocked and couldn't be used with a generator, so if you used those functions the main event loop would be stuck waiting.

For node, we happen to have a server that calls into a geometric modeler (for collaborative 3d modeling). Since it's doing a lot of math, you could totally conceive that while an expensive modeling operation is running and chewing through CPU cycles, all the other sessions on the system are just waiting. That's kind of a specific use case admittedly, but with threads it wouldn't even be an issue, but with async it's a problem. I get there's ways around it (offload the work to a worker process asynchronously, for instance, which is what we're doing), but it's annoying that it's a thing I have to think about when the functionality is built into the OS.

Re: What Color Is Your Function?

#98

I'm really out on most of the "async" stuff, after having used it. (Mostly in Node and Tornado) Remember in the early 90s when Windows and Mac OS were "cooperatively" multitasked? Which is to say, you had to explicitly yield to allow other applications to run (or risk locking up the entire system). And then it was replaced with pre-emptive multitasking, which allowed the scheduler to figure out what process deserved…

100% agree.

Think of your code as an operating system. And heck if you write anything complicated it will start to look like that.

As you said, if you write code that needs to co-operatively yield, needs to use defereds, promises, futures, you are back to Windows 3.1 Which is nice, when it came out.[+]

The next level in evolution is pre-emptive multi-tasking. A scheduler interrupts your task and make sure to run other task. You don't have to worry about fairness (or another task being unfair). This is your classic threads running in the same shared memory -- C++,Java,C#. In OS equivalent this is Windows 95. It was a glorious OS for its time. It really was, I am not kidding.

Next level in evolution is pre-emptive multi-tasking with isolated memory. Aha, now one broken/evil/greedy task can't easily foul up other tasks. This was huge. Think jumping from Window 95 to NT or to Unix/Linux. Awesome things like multi-user system, reliable systems with multiple processes starting/stopping that could run for more than 3 days without rebooting. This is what makes the world run today in general computing. In programming languages paradigm there is ... (sorry, if this is dissapointing) only Erlang. You can add its friends (Elixir, LFE and few others running on same VM). Yap, the only one I know that has built-in heap isolation and light tasks (a couple of K's of memory). The non-programming language specific paradigm is of course OS processes, with some messaging. Now you can call them micro-services living in containers to be cool and that's fine. But is really nice. You've caught up with OS technology finally.

[+] : One kind of in-between is semi-pre-emptive multi-tasking and that is when pre-emption happens implicitly during certain system calls (usually IO calls like socket.recv() or say disk.write() or time.sleep(). I think Go works like this and Python's eventlet and gevent work that ways.

Re: What Color Is Your Function?

#99
post #53
post #51

Earlier quoted context omitted.

Let's take a simple, quotidian example: logging and errors. I write functions that produce logs and may generate errors. If I were using monads, I'd have a log monad and an error monad. For logs, my functions would produce a value and a list of log messages. The monad would combine the list of messages. For errors, my functions return an OK and a value, or an error, and the monad short-circuits errors. Now I write fu…

Of course there are two ways. The problem is that there is not enough information in the mere product of the two algebras to indicate what proper behavior is. If you don't mind deferring the definition of "correct" to the interpreter writer then that intentional choice is captured by (MonadWriter Log m, MonadExcept m) => m a If you want more controls then we need to start specifying laws. For instance, the following…

I would even go so far as to suggest that there are applications where we want the other ordering of these two.

Re: What Color Is Your Function?

#100
post #53

Earlier quoted context omitted.

Of course there are two ways. The problem is that there is not enough information in the mere product of the two algebras to indicate what proper behavior is. If you don't mind deferring the definition of "correct" to the interpreter writer then that intentional choice is captured by (MonadWriter Log m, MonadExcept m) => m a If you want more controls then we need to start specifying laws. For instance, the following…

I would even go so far as to suggest that there are applications where we want the other ordering of these two.

Me too!
Post reply on HN