Apr. 6th, 2016
После третьей лекции они уже сообщают, что дополнительно следует читать вот это:
http://chris-taylor.github.io/blog/2013/02/10/the-algebra-of-algebraic-data-types/
http://chris-taylor.github.io/blog/2013/02/10/the-algebra-of-algebraic-data-types/
to shave a yak
Apr. 6th, 2016 09:50 pmOk, my stuff is still not working. Discovered that for every imported row all kinds of hell are raised, including reading a "property" from db.
So I thought, wtf, let's use expiring cache, from spray. But spray for some reason is incompatible with the rest of the app, lift, etc. So I pulled the source code and decided to finish it with my own hands. Wtf, I wrote those expiring caches more than twice. Now what. Busy.
And then I figured, why map? All in need is an expiring value. So, "decorate" the property entries with caching. Stuff the property provider inside, give it TTL (time to live), and refresh on demand, storing it in a private
Wait, a
Ok, but what's
No, that's stupid. source is also a stream, and there's no need to pass it anywhere. This is how it should look:
But wait, so cache provides a flatMap, that's it right? And what does it do? It's a stream, but well... does it have a var? Probably not, just checks that the time is up, and then ends, meanwhile returning the same value all the time. What does it depend on? Time.
I want to mock time, how else do I check it all? So, I have to stuff the source of time, something like
Don't you see, time is also a stream.
What we produce, having a stream of time and a stream of values is pairs,
Of course the source of time is not infinite, it just lasts
In short, what do we have here? We have a Cartesian product of input source and time segments.
That's it.
Once I got it, the true nature of caching kind of became clear to me. Everything's illuminated. МПЯ, момент предельной ясности, как выражаются люди с туманом в голове.
Well, of course, additionally we can pass
So I thought, wtf, let's use expiring cache, from spray. But spray for some reason is incompatible with the rest of the app, lift, etc. So I pulled the source code and decided to finish it with my own hands. Wtf, I wrote those expiring caches more than twice. Now what. Busy.
And then I figured, why map? All in need is an expiring value. So, "decorate" the property entries with caching. Stuff the property provider inside, give it TTL (time to live), and refresh on demand, storing it in a private
var
.Wait, a
var
? Wtf, a variable? No way. Let's make it a stream, and use it in loops, like for { val value ← cached(source:Something, ttl: Duration) } doStuff(value)
Ok, but what's
source
? It was Future[T]
in Spray's ExpiringLruCache
, it was something like that in com.google.common.cache
that I was kind of developing with Bob Lee while at Google and while naïve like a boyscout.No, that's stupid. source is also a stream, and there's no need to pass it anywhere. This is how it should look:
for { val value0 ← (source:Stream[T]) // a stream val value ← cache(ttl: Duration)(value0) } doStuff(value)
But wait, so cache provides a flatMap, that's it right? And what does it do? It's a stream, but well... does it have a var? Probably not, just checks that the time is up, and then ends, meanwhile returning the same value all the time. What does it depend on? Time.
I want to mock time, how else do I check it all? So, I have to stuff the source of time, something like
for { val value0 ← (source:Stream[T]) // a stream val value ← cache(ttl: Duration, timeSource: TimeReader = StandardTime/*we have this class*/)(value0) } doStuff(value)
Don't you see, time is also a stream.
What we produce, having a stream of time and a stream of values is pairs,
(value:T, time:Timestamp)
, then we are free to abandon time
Of course the source of time is not infinite, it just lasts
ttl
units of time.In short, what do we have here? We have a Cartesian product of input source and time segments.
That's it.
Once I got it, the true nature of caching kind of became clear to me. Everything's illuminated. МПЯ, момент предельной ясности, как выражаются люди с туманом в голове.
Well, of course, additionally we can pass
doStuff
to the stream; it's a codata, is not it. Just not what I was going to talk about, but anyway.