other-languages

here be heresies and things we have to use for work
borkdude 2017-11-24T11:56:31.000044Z

What do Haskellers mean with “IO monad is not the effect itself, but is a recipe for the effect”. Isn’t all code a recipe for making things happen?

sundarj 2017-11-24T12:07:59.000204Z

by that logic there is no difference between a function and a partially-applied version of that function. indirection can be semantically significant (just look at transducers)

borkdude 2017-11-24T12:13:15.000051Z

@sundarj Trying to understand what they man. What is a function of IO String different than the same function in another language that goes out in the world to fetch a string?

sundarj 2017-11-24T12:14:14.000202Z

a function of IO String is still technically pure

sundarj 2017-11-24T12:14:30.000301Z

it takes a value as input, and returns a value as output - nothing else

sundarj 2017-11-24T12:15:06.000352Z

it is Haskell itself that then uses that to do the side-effect when you use it from the main function

sundarj 2017-11-24T12:15:40.000049Z

note i am not a Haskeller myself, so i could be a bit off here - but that is my understanding

borkdude 2017-11-24T12:15:45.000067Z

ok, from a type perspective it’s pure. it’s just that Haskell implements the IO monad as effecting?

sundarj 2017-11-24T12:16:03.000021Z

right

borkdude 2017-11-24T12:16:32.000230Z

I don’t see how it helps of viewing that function as pure though. Same input, same output. Not always the case with IO or random, etc.

sundarj 2017-11-24T12:16:32.000281Z

but to the code itself, what Haskell does with it in the end is not relevant

sundarj 2017-11-24T12:17:33.000024Z

you could imagine replacing the IO String with MyIO String and the function would still work the same, right?

borkdude 2017-11-24T12:18:24.000063Z

Purity guarantees me that I can substitute values for function calls. This is not the case with IO. So I still don’t get it.

sundarj 2017-11-24T12:20:00.000155Z

in terms of files and http calls, you cannot gurantee referential transparency. but IO is the next best thing.. the function does not do any effects itself - it can be tested independently of whatever effect it is doing

sundarj 2017-11-24T12:20:38.000389Z

the random functions in Haskell, however, are referentially transparent

sundarj 2017-11-24T12:20:43.000238Z

they take an explicit seed argument

borkdude 2017-11-24T12:21:56.000163Z

> it can be tested independently of whatever effect it is doing Can you explain this for e.g. a function that does an HTTP request?

sundarj 2017-11-24T12:22:48.000069Z

it's like Ring response handlers. they just return {:body "foo"} or w/e, and then Ring itself does the grunt work

sundarj 2017-11-24T12:23:32.000342Z

those functions can then be tested like (= (:body (handler)) "foo"), and that is independent of the actual http request stuff

sundarj 2017-11-24T12:24:39.000021Z

of course, monads are a little more involved than plain data, but i think the same thing applies

borkdude 2017-11-24T12:25:19.000275Z

For example:

get :: String -> IO String
get url = simpleHTTP (getRequest url) >>= getResponseBody
You say: > it can be tested independently of whatever effect it is doing So, how do you test this function without doing the effect? I didn’t get that.

sundarj 2017-11-24T12:26:16.000273Z

I believe Haskell only performs IO that is used from inside the main function. if it's not called from there, it doesn't do anything

sundarj 2017-11-24T12:26:39.000039Z

it just returns a monad

sundarj 2017-11-24T12:27:05.000125Z

only the main function is capable of using that monad to do anything

borkdude 2017-11-24T12:27:22.000002Z

you could just invoke this get function from ghci, would also work

borkdude 2017-11-24T12:27:46.000002Z

My point is, you cannot actually test this function without calling it?

sundarj 2017-11-24T12:28:00.000300Z

correct

sundarj 2017-11-24T12:29:12.000096Z

i was under the impression that calling it outside of the main function (or maybe the repl), did not do anything effectful

sundarj 2017-11-24T12:29:16.000427Z

perhaps i am wrong

borkdude 2017-11-24T12:29:39.000107Z

if that were true, what would the function return then?

sundarj 2017-11-24T12:29:55.000255Z

an instance of the IO monad

borkdude 2017-11-24T12:30:21.000188Z

with what in it?

sundarj 2017-11-24T12:30:43.000167Z

good question

sundarj 2017-11-24T12:30:48.000210Z

i don't know

borkdude 2017-11-24T12:30:50.000005Z

you can of course stub the function by returning some IO value, but that’s not the same as testing the function itself

sundarj 2017-11-24T12:30:58.000186Z

right

sundarj 2017-11-24T12:32:07.000003Z

perhaps it just contains what should happen once it has been called from main

sundarj 2017-11-24T12:37:29.000264Z

@borkdude this seems to confirm what i've been saying https://stackoverflow.com/a/28639600

borkdude 2017-11-24T12:39:55.000016Z

ok, so an IO String returned from a function is the action itself, which is always the same (because it’s some sort of reified effect), but the string may be different every time you run it… This messes with my head really.

borkdude 2017-11-24T12:41:30.000274Z

IO String is the action itself, reified, but the outcome of the action may be different, sort of?

sundarj 2017-11-24T12:42:16.000287Z

i guess you can think of it as, every function but main is referentially transparent

sundarj 2017-11-24T12:43:24.000114Z

the edge of the system is not referentially transparent, because it interfaces with the outside world - but the things that are removed from the outside world are

sundarj 2017-11-24T12:43:43.000073Z

in terms of what they take as input and produce as output

sundarj 2017-11-24T12:44:56.000172Z

main is different, because it is the thing that actually ends up doing the effects

sundarj 2017-11-24T12:47:52.000297Z

i suppose you could say they are only truly referentially transparent at compile-time

borkdude 2017-11-24T16:06:35.000204Z

http://conal.net/blog/posts/the-c-language-is-purely-functional

👍 3