Time 
Nick 
Message 
21:28 

ilbot3 joined #perl6monads 
21:28 
masak 
a guy once explained monads to an audience I was in by implementing turtle graphics 
21:29 
masak 
welcome! 
21:29 

perlpilot_ joined #perl6monads 
21:29 
masak 
so, I hear you're interested in monads, yah? 
21:29 
* moritz 
nods the bot's head 
21:29 
masak 
so, it's Saturday evening and 7 people are talking about monads... 
21:30 
* perlpilot_ 
is just intersted in the explanation as he hasn't thought about monads in several years 
21:30 
masak 
why turtle graphics? because you move the turtle around, and it has a bunch of state that you can change, OK? 
21:30 
perlpilot_ 
(I've forgotten whatever I knew I'm sure) 
21:30 
masak 
state is a knownsore point in functional languages 
21:31 
masak 
state is supereasy on a Turing machine model 
21:31 
masak 
because the Turing machine is a mechanical thing with lots of moving parts 
21:31 
masak 
functional programming (lambda calculus and its decendants) doesn't really have moving parts, just term rewriting 
21:31 
masak 
anyway 
21:32 

Topic for #perl6monads is now http://irclog.perlgeek.de/perl6monads 
21:32 
masak 
a monad is a turtle  is everyone clear on this so far? 
21:32 
masak 
any questions? 
21:33 
moritz 
they taste the same too? 
21:33 
perlpilot_ 
monad soup? 
21:33 
masak 
taste the same, but monads are slightly chewier 
21:34 
* masak 
has eaten turtle, once, in .cn 
21:34 
masak 
anyway, back to the guy with the turtle graphics 
21:34 
masak 
he was implementing all the normal things: move the turtle forwards, turn it this way and that, pen up, pen down 
21:35 
masak 
you can imagine how all of those change some internal state, and possibly also add graphic primitives to a canvas somewhere 
21:35 
masak 
then he went on to draw things 
21:36 
masak 
like a fractal tree like this: https://commons.wikimedia.org/wiki/File:Fractal_plant.jpg 
21:36 
masak 
now, it turns out 
21:36 
masak 
when you want to draw something like that, you suddenly want to "save" and "load" the turtle's whole state, like in a computer game 
21:37 
masak 
in order to "teleport" it back to some position so you don't have to painstakingly retrace your steps 
21:37 
moritz 
or clone it when it's at the save point 
21:38 
moritz 
and only move one copy in the first place 
21:38 
perlpilot 
bifurcated turtle 
21:38 
masak 
sure, but FP doesn't think in terms of modifying a turtle object 
21:39 
masak 
every "modification" in something like Haskell is conceptually a whole new copy 
21:40 
masak 
here's someone trying to do turtle graphics with a monad: http://stackoverflow.com/questions/13331336/turtlegraphicsasahaskellmonad#13333325 
21:40 
masak 
(though not the guy who was giving that talk) 
21:41 
masak 
anyway, let's back away from the specifics of turtles and look at the *type* of itch we're trying to scratch 
21:42 

notviki left #perl6monads 
21:43 
masak 
(a) we want to talk about sequences of actions 
21:43 

rafaschp joined #perl6monads 
21:43 
masak 
(b) a sequence of actions are carried out in the order written, and together compose to an action 
21:47 
masak 
in the case of the turtle and the state monad, we are also interested in those "load" and "save" operations  but that's specific to the state monad and not something monads in general do 
21:47 
masak 
anyway 
21:48 
rafaschp 
What's the difference between a monad and a program? 
21:48 
masak 
FP uses functions a lot. when all you have is a hammer^Wfunction, you tend to start to think in a certain way 
21:48 
masak 
rafaschp: a good question! 
21:48 
masak 
rafaschp: I get the feeling that in Haskell at least, the type of the program is `IO ()`  a monad 
21:48 
masak 
or the type of `main` or whatever 
21:49 
masak 
why? because the only way you have side effects in Haskell is through monads, and the program itself most certainly does have side effects 
21:49 
hartenfels 
Using that hammer, solving sequences of actions seems to involve passing and returning the turtle to and from each function, because that's the only way you'll get a different result from them. 
21:51 
rafaschp 
So, a monad is like a programable state machine? 
21:52 
* moritz 
doesn't think masak has gotten to the point what a monad actually is 
21:52 
masak 
hartenfels: yes 
21:52 
masak 
rafaschp: hm  not sure how well that analogy holds up 
21:52 
masak 
sorry, I lost the connection there for a while 
21:53 
rafaschp 
I'm listening. 
21:53 
rafaschp 
I asked the question because you were disconnected, sorry. 
21:53 
masak 
even though Haskell programs are of type `IO ()`, I also get the feeling that you try to write most of the program "outside of the monad", because pure FP code is nicer 
21:54 
rafaschp 
Pure FP code is nicer for some definition of nicer. 
21:54 
masak 
anyway, FP is most certainly equipped to handle *sequencing*, which is what most of this is about 
21:54 
masak 
how do you implement sequencing in lambda calculus? you basically just pass something to a function, and let the argument evaluation logic provide the sequence points 
21:55 
masak 
so it does work, to get turtlegraphicslike sequencing from an FP program 
21:55 
masak 
but it doesn't look so nice :) 
21:55 
masak 
look at the `add` example at https://en.wikipedia.org/wiki/Monad_(functional_programming)#The_Maybe_monad and you see what I mean 
21:55 
masak 
people talk about "pyramid of doom" in the JavaScript world when doing callbacks in callbacks several nested levels deep 
21:55 
masak 
same thing would happen here 
21:56 
masak 
and then look at the code under "Using some additional syntactic sugar known as donotation, the example can be written as:" 
21:56 
masak 
that's what monadic logic gives you 
21:57 
masak 
but it's quite important  and pretty impressive  that the `do` notation in Haskell is actually syntactic sugar for the code right *above* that sentence 
21:57 
masak 
yes, there you see the raw lambdas being passed around. those lambdas are the ones that make the sequencing happen 
21:57 
moritz 
that makes a scary amount of sense 
21:58 
masak 
:) 
21:58 
masak 
linger on this for a moment, though 
21:58 
rafaschp 
I see, "nomads" is a fancy name for people that like to say FP is way better to do imperative programming without having to admit to it. xD 
21:58 
masak 
in Haskell, `do` notation (that is, all imperative programming) is *syntactic sugar* for lambdas being passed around to produce sequencing 
21:58 
masak 
rafaschp: correct 
21:58 
geekosaur 
there's an impressive amount of takeup of haskell as javascript generator (or a haskelllike language generating javascript) precisely because you can use do notation to describe all the callbacks as if you were programming imperatively 
21:59 
moritz 
so there are two lambdas that extract the values from the Maybe monad, so that you can focus on the base case 
21:59 
masak 
rafaschp: I mean, if someone claimed that they had reduced imperative programming to something more fundamental, at least I would perk up a bit and listen 
22:00 
masak 
moritz: yeah. in the Maybe monad, only the `Just` case is actually interesting. the `Nothing` case usually means you just don't consider it, and execution stops/backtracks 
22:00 
rafaschp 
I don't see FP as a "more fundamental" way, just as an equivalent way. The processors are imperative. 
22:00 
hartenfels 
The reason behind the `return` is just to make the type system happy? 
22:00 
rafaschp 
The fact that it can be translated automatically is very cool, though. 
22:00 
geekosaur 
it turns "value" into "callback producing value" 
22:00 
masak 
hartenfels: you should read `return` here as "here, take this normal value and produce a monad from it that wraps that value" 
22:01 
geekosaur 
sometimes you could infer this in a language with a looser type system, but sometimes you can't (and in Haskell, such inference never happens) 
22:01 
hartenfels 
Yeah, I get that. But it's not like I actually care about the monad at that point, I just want the value. 
22:01 
hartenfels 
But it makes sense, since I might also get Nothing. 
22:01 
hartenfels 
In this case. 
22:01 
masak 
moritz: even cooler: the exact same `do` notation works for (e.g.) the List monad, and what's implicit there is `flatmap` instead of the Nothing/Just distinction 
22:01 
masak 
moritz: and so on for every monad 
22:03 
masak 
hartenfels: once you're in a monad, you can't get a raw value out of it, ever 
22:03 
masak 
see https://xkcd.com/248/ 
22:03 
hartenfels 
Can't I case over it in the function that calls it? 
22:03 
hartenfels 
Or whatever Haskell calls it 
22:04 
hartenfels 
Pattern match over it. 
22:04 
masak 
nope 
22:04 
moritz 
yes, but the function in which you do it still has to return a monad 
22:04 
masak 
hartenfels: perhaps easiest to understand with the `IO` monad 
22:04 
hartenfels 
Oh, I think I'm misunderstanding “in a monad” 
22:04 
masak 
once something starts to have side effects, you can't just wash it and make it pure again 
22:05 
masak 
everything that touches something with a monad similarly becomes "tainted" 
22:05 
masak 
it's like a pirate curse 
22:05 
hartenfels 
I mean once I am done with doing the sequence stuff, I can pattern match over the resulting monad and get the value out if it produced one. 
22:05 
masak 
only *inside the monad* 
22:06 
masak 
case in point: once you get a value back from a Promise, you can only relate to that value inside of the .then callback 
22:06 
moritz 
masak: so how does reduce work? it takes a monad (list) as an input, and produces a single value, no? 
22:06 
moritz 
s/reduce/fold/ 
22:07 
masak 
moritz: monad is a type class/interface/role here  if you can get the value back out you can be sure it wasn't thanks to the monad typeclass :) 
22:08 
moritz 
masak: ah, so a list is more than just a monad, and the morethan part allows things like fold or head 
22:09 
hartenfels 
Something like `Maybe Int > Int f; f Nothing = 0; f Just a = a` would let me get the value out of the Maybe monad, but not because of its monadyness? 
22:09 
rafaschp 
"type" is a way for the "FP is superior" people to likewise do OOP without adminting it? 
22:09 
geekosaur 
hartenfels, the monad interface itself doesn't give you a way to get anuything out. *particular* monads may 
22:09 
masak 
moritz: aye 
22:10 
hartenfels 
Ah okay, so getting stuff out is not a thing that a monad does on its own. 
22:10 
geekosaur 
rafaschp, not really, depending on what you mean by OOP. OOP is generally understood to be subtyping; monads don't help you with that, nor do Haskell typeclasses (and if you try to abuse typeclasses as OOP, you quickly run into the difference between HindleyMilner typing and subtyping) 
22:11 
rafaschp 
Ok, thanks. 
22:11 
geekosaur 
you could say subtyping runs "backwards" from most FP type systems 
22:11 
rafaschp 
I was thinking about other things I knew about types, then. 
22:11 
masak 
hartenfels: I think you just implemented fromJust :) 
22:12 
masak 
hartenfels: see https://hackage.haskell.org/package/base4.2.0.1/docs/DataMaybe.html#v%3AfromJust 
22:12 
geekosaur 
instead of, say, Num giving you access to anything that any Num instance could do, it gives you access only to the things that *all* of them can do. 
22:12 
masak 
yeah, that's a good way to phrase it 
22:12 
geekosaur 
(which is, more or less, the difference between subtyping and HindleyMilner, respectively) 
22:12 
masak 
it feels a bit insideout 
22:13 
geekosaur 
subtyping is union, HM is intersection 
22:13 
geekosaur 
or, equivalently, "or" vs. "and" 
22:13 
masak 
duals, they strike again! 
22:13 
masak 
anyway 
22:14 
masak 
we haven't really pinned down what monads are yet, have we? 
22:14 
geekosaur 
nope :) 
22:14 
masak 
but we've seen several examples: State, IO, Maybe, List... 
22:14 
geekosaur 
well, sort of operationally 
22:14 
masak 
and they all look quite different 
22:14 
geekosaur 
but then, by some arguments that's all that matters 
22:14 
masak 
some of them (like Maybe and List) focus on data structures 
22:15 
geekosaur 
not like you have to know category theory to *use* them effectively 
22:15 
masak 
some of them (like State and IO) focus on sequencing and side effects 
22:15 
masak 
these are two aspects of monads, and they're somewhat at odds 
22:15 
masak 
in the sense that they are two competing mental models 
22:15 
masak 
kind of like particle vs wave, I guess 
22:16 
masak 
so let's find a uniting common ground 
22:16 
masak 
a monad is just this: 
22:16 
masak 
(ready?) 
22:16 
masak 
it's something with a `return` and with a `bind` 
22:16 
masak 
and those have to live up to some pretty basic rules 
22:16 
masak 
that's all 
22:17 
masak 
all the examples you've seen above define their `return` and their `bind` in some way, and that's what makes them monads 
22:17 
masak 
all the monad tutorials out there should just say this and be done with it 
22:17 
moritz 
so, how doe IO and List return and bind? 
22:17 
moritz 
s/doe/do/ 
22:17 
masak 
good, let's talk about that 
22:17 
masak 
List first, because I know it quite well :) 
22:18 
masak 
`return 42` should put 42 in the List monad 
22:18 
masak 
so the result is... `[42]`. done 
22:20 
masak 
`bind xs f` is implemented as `flatmap` 
22:20 
masak 
much like Perl 5's `map` 
22:21 
masak 
so if xs is `[1, 2, 3]` and `f` is `\n > [n, n * 2]`, then `bind xs f` gives you `[1, 2, 2, 4, 3, 6]` 
22:22 
masak 
written as Perl 5: `map { $_, $_ * 2 } 1, 2, 3` gives you `1, 2, 2, 4, 3, 6` 
22:22 
masak 
note the cute symmetry here: 
22:22 
masak 
`return` knows how to turn *zero* layers of monad to *one* layer of monad 
22:23 
masak 
meanwhile, `bind` says "but what if you have *two* layers of monad; I only wanted one!" 
22:23 
masak 
and then solves that for you 
22:23 
rafaschp 
It's jast a lame function, then. 
22:23 
masak 
that's why it's `flatmap`, and that's why you don't get `[[1, 2], [2, 4], [3, 6]]` 
22:24 
masak 
rafaschp: but then again, what isn't? 
22:25 
rafaschp 
They should generalize their models. 
22:25 
geekosaur 
that's ... what monad is about 
22:25 
moritz 
so next time somebody asks me what monads are, I say "just a bunch of functions, d'oh" :) 
22:26 
geekosaur 
pretty much 
22:27 
masak 
moritz: I think I can even get you to grok http://stackoverflow.com/questions/3870088/amonadisjustamonoidinthecategoryofendofunctorswhatstheproble%E2%85%BF  it's pretty straightforward :) 
22:27 
geekosaur 
there's an ongoing joke in the haskell community about monad tutorials that all miss the point ("burrito" is a reference to a joke monad tutorial that mocks the whole class of monad tutorials) 
22:27 
rafaschp 
If they want functions in their language, they should add that. And stop pretending it's some mathematical holy grail because it's missing features. 
22:27 
masak 
geekosaur: the "burrito" monad tutorial was written by mjd 
22:27 
masak 
geekosaur: and what makes you think he was joking? :) 
22:27 
geekosaur 
maybe there's two of them then. I'm thinking of one done by Don Stewart 
22:27 
masak 
ah. 
22:28 
geekosaur 
two of them, the burrito and the spacesuit 
22:28 
masak 
http://blog.plover.com/prog/burritos.html 
22:28 
geekosaur 
the burrito caught on 
22:28 
geekosaur 
possibly because of mjd's 
22:29 
masak 
there's a bit of survivor's bias in monad tutorials, I guess 
22:29 
masak 
something makes it click for a certain person 
22:30 
masak 
and they write that part up, convinced it will help lots of others 
22:30 
rafaschp 
It could all be so simple. 
22:30 
masak 
well, monads *are* simple  in about the same way Git is 
22:30 
geekosaur 
except most such tutorials you can point to a particular monad and ask how that fits in, and the answer is "it doesn't" 
22:30 
masak 
the problem is clearing away all the mental baggage that obstructs the simplicity 
22:31 
hartenfels 
Presumably what makes monads nice is having the syntax sugar to deal with them? 
22:31 
masak 
geekosaur: well, the abovementioned container/sequencing split doesn't help, of course 
22:31 
masak 
hartenfels: oh, that's certainly a big deal, yes 
22:31 
geekosaur 
most monad tutorials I've seen miss the point in some way  granted I stopped looking after awhile 
22:31 
moritz 
masak: why does that stackoverflow post use "join" instead of "bind"? 
22:31 
masak 
hartenfels: but it goes beyond that  the underlying semantic framework is simply very general 
22:31 
geekosaur 
...hoo boy... 
22:31 
masak 
hartenfels: in the same way as saying "it's a visitor pattern", you can say "it's a monad", and it means something useful 
22:32 
masak 
moritz: there are several possible fundamental operators 
22:32 
moritz 
masak: ok 
22:32 
masak 
moritz: I think `bind` is Haskell's favorite. `join` is more towards CT... I think... 
22:32 
geekosaur 
yes and no 
22:32 
masak 
it all comes out the same. you can define one in terms of the other, that's the important bit 
22:33 
geekosaur 
think of it this way: for a list, you can break "bind" down into two operations, map and concat 
22:33 
geekosaur 
"join" is the generalized term for the concat operation 
22:34 
masak 
ah, geekosaur++ 
22:34 
geekosaur 
it's most clearly visible for lists, where map = map and join = concat, but the same breakdown can be done for any monad 
22:34 
hartenfels 
I will now start calling it the monad pattern then. 
22:34 
masak 
I'm used to thinking about it in terms of functor, η and μ :P 
22:35 
masak 
hartenfels: again, as above, the hardcore thing to say is "a monad is just a monoid in the category of endomorphisms, what's the big deal?" 
22:36 
geekosaur 
and the usual category theory representation is based on that breakdown. but for Haskell, bind is a more useful general operation because it gives a simple translation from do notation to callback expressions 
22:36 
rafaschp 
I like "a monad is a lame function" better, because people that like monads are usually hangup on the (equally meaningless) definition mathematians use for "funtion". 
22:37 
* moritz 
has to sleep soon, but will backlog 
22:37 
geekosaur 
(and then Haskell reconstructs join from bind, because join is just binding the identity function 
22:37 
hartenfels 
Well, I want it to be less hardcore. Calling them monads always makes them seem like things and not just bits of code that work a certain way. 
22:37 
masak 
hartenfels: it is a pattern, for sure 
22:37 
masak 
or rather, a typeclass 
22:38 
masak 
hartenfels: but I think you're onto something. what you should translate "it's just a monad" to in your head is something akin to "it gives a certain set of wellknown guarantees" 
22:38 
hartenfels 
Pretty much. 
22:38 
masak 
the specifics of which are important of course, but also easy to learn 
22:39 
geekosaur 
one of the confusions here is that many things which have to be treated as design patterns in other languages can be captured as libraries in Haskell, so we don't tend to think in terms of Monad as design pattern 
22:39 
masak 
for me, thinking of `return` as "turning a muggle value into a monad value" and `bind` as "combining two monad values into one monad value" helps a lot 
22:39 
geekosaur 
but when viewed from the standpoint of other languages, that's exactly what it is 
22:39 
masak 
aye 
22:40 
masak 
again, in Haskell/FP, some things are a bit insideout 
22:41 
hartenfels 
Somehow calling them “monads” made it sound like they were godgiven entities like functions or record values, rather than just codified common behavior. 
22:42 
geekosaur 
(there is a certain dismissive attitude in the Haskell community that a "design pattern" indicates a shortcoming in a language being worked around. which isn't really true (usually; mostly that's a barb aimed at Java) and means many Haskellers won't admit that something is a design pattern when it actually is) 
22:42 
masak 
geekosaur: oh! good to know. 
22:42 
masak 
geekosaur: I know mjd has said something similar, that design patterns are weaknesses in the underlying language 
22:43 
moritz 
one could say something similar about Haskell 
22:43 
masak 
hartenfels: right  calling it a monad means we recognize some *part* of its behavior as being similar to many other things 
22:43 
moritz 
the fact that you need monads to do IO is a weakness, because monads are hard to understand 
22:43 
masak 
I don't know that they are, though 
22:43 
rafaschp 
Then instead of describing the thing directly, they try and make up a mathematical model for it? To pretend something is more than it really is? 
22:43 
hartenfels 
Maybe I'll even call it an interface design pattern to make the Java analogy even worse :P 
22:44 
masak 
I mean, you can explain Go to someone in a very inefficient/confusing way 
22:44 
masak 
doesn't mean that Go is difficult to understand 
22:44 
hartenfels 
But great explanation masak++ 
22:44 
geekosaur 
masak, sometimes it is true. and sometimes a design pattern is nothing more than an API. 
22:44 
masak 
rafaschp: monads are older than Haskell :) 
22:44 
masak 
*nod* 
22:45 
masak 
and, on that note... 
22:45 
rafaschp 
Lispers are the same way? 
22:45 
masak 
...thanks for coming. try the veal. 
22:45 

rafaschp left #perl6monads 
22:45 
hartenfels 
Thanks for explaining. 
22:46 
masak 
pleasure. I learned some things, too. 
22:46 
geekosaur 
and often it's something in between  becuase, no matter how flexible the languge, the real world is more flexible yet 
22:55 

geekosaur left #perl6monads 
23:24 

geekosaur joined #perl6monads 