Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Topics - TheWormKill

Pages: [1] 2
1
Found it on the Webs / Links for today (part 3)
« on: October 17, 2015, 01:51:14 pm »
So, in come links again.

* Markdeep - a markdown with rendering and syntax extensions.
* Quipper - a functional programming language for quantum computing
* Stuff on coredumps
* From python to Go and back - an interesting, though non-technical presentation on switching to differnt technologies, understanding requirements etc.
* Cron pitfalls - although I hate this site's hipsterish style, the content is rather good, don't let the view distract you
* Windows 10 upgrade is getting more intrusive - not sure how true that is, but alarming nonetheless
* Fun stuff with a lot of data and python

Below some links on installing/maintaining OpenRC on Arch Linux. Haven't tried them yet, but I plan to.
* The wiki article
* Installation notices from systemd-free.org
* Config notices from the same plae
* A blog entry on the topic

As always, tell me what you think. I'm especially intrigued to hear your opinions on the OpenRC+Arch combo.

2
Found it on the Webs / Links for today (part 2)
« on: October 09, 2015, 04:39:55 pm »
More links, yay!
* Accelerating the (mobile) web
* The milky way across the spectrum
* Thoughts on quantum theory (and what that means for Schroedinger's famous thought-experiment
* Pretty fun (and admittedly light) read on setting up large infrastructure
* High level CPU's (A challenge, rant, and technical article - all in one page)
* New stuff on Pluto
* Debian drops support for LSB (The Linux Standard Base is a standard on tools, libraries and interfaces that should be available by default on a Linux system. Due to it being quite bloated and under-used, the Debian devs... uhm, read the article.)
* Links on C/C++ (Mostly in russian, but the URLs speak for themselves.)

Well, this is longer than it should be. Maybe I should cut the format down to be weekly. If you have thoughts or feedback, do tell. Is the collecting-links-in-a-bunch practise a good idea? Is it too unsorted? Does it lack quality?

3
Found it on the Webs / Links for today (part 1)
« on: October 08, 2015, 03:40:54 pm »
Some interesting links for today:
* "Mostly functional programming" does not work (not a big surprise, really)
* Beware of the gargantua (They released Perl 6)
* SHA-1 collisions
* Fun with PNG's
* Graph visualization for control-flow-graphs (a paper that is quite specific and limited to a narrow scope, but pretty interesting to me nonetheless)
* A phrack article on rootkit detection (we love phrack for a reason)

I guess I'll summarize the interesting links from now on in posts like this.

4
Found it on the Webs / The microservice cargo cult
« on: October 06, 2015, 04:32:19 pm »
Found this interesting link, basically a through and non-biased evaluation of microservice-based system architecture:

http://www.stavros.io/posts/microservices-cargo-cult/

5
Found it on the Webs / Surprisingly Turing-Complete
« on: October 02, 2015, 10:57:50 pm »
I found this link which basically serves as reference and a guide for further reading to anyone who is interested.
http://www.gwern.net/Turing-complete

6
Tutorials / An informal talk about monads
« on: October 01, 2015, 09:02:16 pm »
Well somehow, discussion got to package managers, I mentioned Haskell's cabal, and we ended talking about monads in their own channel. So I'll post the logs because I think it might be a) worth the read b) funny c) an inspiration and maybe a reason to do a second talk of that kind.
Quote from: #monads
[19:32:06] *** Joins: thewormkill (~thewormki@worms.lair)
[19:32:06] *** Server sets mode: +
[19:32:08] *** Server sets mode: +
[19:32:14] *** Joins: lenoch (~lenoch@61476DB6.A460EC41.F860C5F1.IP)
[19:32:28] *** Joins: acaan (~doctor@evilzone-F267F0C0.whyrlpool.com)
[19:34:21] <thewormkill> we're waiting for poly
[19:34:43] <acaan> kk i will go to bring some food i have to eat
[19:34:44] <lenoch> fucking slow guy
[19:34:48] <lenoch> :D
[19:34:49] <thewormkill> :D
[19:35:43] <lenoch> and thewormkill i'm actually serious about giving haskell maybe a go
[19:35:50] <thewormkill> that's great
[19:35:53] <thewormkill> :)
[19:36:16] <lenoch> should learn a functional language someday so why not in the near future
[19:36:49] <thewormkill> second, I'll be back in 5 minutes, dishes await
[19:36:52] *** Joins: Polyphony (~Polyphony@local.host)
[19:36:57] <Polyphony> i'm a shitty student
[19:36:58] <lenoch> oh man
[19:36:59] <lenoch> lol
[19:37:05] <thewormkill> brb
[19:38:47] <Polyphony> i need to start learning some haskell too
[19:38:57] <Polyphony> i've played with it before, just never actually used it
[19:42:20] <thewormkill> so I am back
[19:42:32] <acaan> wooo
[19:42:34] <thewormkill> acaan, lenoch, Polyphony, let's begin
[19:42:38] <Polyphony> kk
[19:43:11] <thewormkill> well, we talk about monads today
[19:43:33] <thewormkill> these are a construct from a field of mathematics called category theory
[19:43:53] <thewormkill> which roughly deals with categorizing things (woo!), mathematical things
[19:44:12] <thewormkill> so, if anyone of you has a question, just interrupt, we have time for that
[19:44:27] <acaan> question
[19:44:34] <thewormkill> so, let's start with simple values...
[19:44:38] <thewormkill> yeah, acaan?
[19:44:51] <acaan> does it categorizes just numbers or some other objects ?
[19:44:58] <thewormkill> objects in general
[19:45:03] <acaan> kk
[19:45:06] <thewormkill> that's the point
[19:45:16] <thewormkill> well, a value is just that, some data
[19:45:34] <thewormkill> using haskell syntax to bind a name to a value looks like so:
[19:45:37] <thewormkill> let a = 5
[19:46:00] <thewormkill> this is not universally valid syntax, but it makes claer what's going on
[19:46:33] <thewormkill> now, the point is, functional languages generally don't allow for *changing* the value of a variable
[19:46:50] <thewormkill> so if you already have a defined, changing what it means isn't possible
[19:47:10] <thewormkill> instead, you can use functions to transform values
[19:47:26] <lenoch> aight seems logical I was thinking of that
[19:47:30] <thewormkill> now, these functions aren't like functions in, say, Ceither
[19:47:37] <thewormkill> *C either
[19:47:44] <thewormkill> in C I can write
[19:47:59] <thewormkill> void a(){some_global++;}
[19:48:11] <thewormkill> which does something but does not return a value
[19:48:35] <thewormkill> so, if we compare it to the mathematical notion of a function, we see some glaring differences
[19:49:08] <thewormkill> in mathematics, a function just maps values of an input domain to values of an output domain, so that you have unambiguous results
[19:49:27] <thewormkill> now we see that this notion does not apply to void a, because it behaves very differently
[19:49:44] <thewormkill> instead of just computing a value, it... well what does it? any ideas?
[19:49:54] <acaan> changes it
[19:49:59] <thewormkill> changes what?
[19:50:04] <acaan> value
[19:50:13] <acaan> of a global, side efect
[19:50:13] <Polyphony> a is just a pointer
[19:50:39] <thewormkill> actually both of you are right to some extend
[19:50:57] <Polyphony> it's not a function because there's no output
[19:50:58] <thewormkill> 1. it does not compute a value, so it has nothing to return (useless as a mathematical function)
[19:51:10] <Polyphony> ^^ "mathematical function"
[19:51:20] <lenoch> it's just a subroutien
[19:51:31] <Polyphony> yeah, it's just a chunk of instruction
[19:51:37] <thewormkill> 2. it does something else, which is modifying global state
[19:51:55] <thewormkill> so, to sum up, it is not a real function, but a procedure.
[19:52:01] <Polyphony> ah
[19:52:11] <thewormkill> this means that it does not behave well in some contexts
[19:52:20] <thewormkill> think of concurrency
[19:52:57] <thewormkill> if you have multiple threads, the changes they apply to some data might be interfering with each other
[19:53:39] <thewormkill> so some people thought that it might be a good idea to avoid these side-effects as they are called, what acaan already mentioned
[19:53:46] <thewormkill> and I forgot to honour
[19:54:38] <thewormkill> now, let's take a different approach of thinking, or simply get back to the point we are at now from a different direction
[19:55:17] <thewormkill> so if data is just a bunch of values and we can calculate the results of functions on those to get *new* values
[19:55:27] <thewormkill> how do we distinguish values?
[19:55:32] <thewormkill> any ideas?
[19:55:38] <acaan> we dont  ?
[19:56:04] <acaan> no
[19:56:06] <acaan> MONAD
[19:56:08] <acaan> :O
[19:56:12] <thewormkill> lol
[19:56:21] <thewormkill> okay, I'll spoiler it
[19:56:26] <thewormkill> adding context to values
[19:56:37] <thewormkill> sounds easy, but what does that mean?
[19:56:46] <acaan> wait
[19:56:50] <thewormkill> well, let's introduce a new concept...
[19:56:53] <thewormkill> yeah?
[19:56:59] <acaan> what do you mean by adding context
[19:57:24] <thewormkill> well, say you have a function
[19:57:54] <thewormkill> a pure function (which is how funcional programming calls mathematical functions with no side effects)
[19:58:06] <thewormkill> code follows:
[19:58:25] <thewormkill> f(x) = 1 / x
[19:58:32] <thewormkill> (not haskell but w/e)
[19:58:54] <thewormkill> it is certainly nothing special
[19:59:09] <thewormkill> but, if you use it in source code, what will happen if we pass x=0
[19:59:12] <thewormkill> ?
[19:59:26] <lenoch> infinity
[19:59:27] <acaan> undefined
[19:59:32] <Polyphony> "undefined behavior" lol
[19:59:40] <acaan> error
[19:59:41] <Polyphony> actually i don't know, i just love C
[19:59:52] <lenoch> you can't divide by 0
[19:59:52] <acaan> i love U
[19:59:52] <thewormkill> well, actually you crash your proggram
[19:59:54] <acaan> LOL
[20:00:02] <thewormkill> because you can't divide by 0
[20:00:23] <thewormkill> it doesn't make sense in maths, so why should it make sense in our program?
[20:00:26] <lenoch> well I heard it is something with infinity and stuff
[20:00:29] <lenoch> but yeah you can't
[20:00:30] <lenoch> :p
[20:00:47] <lenoch> because um we want to bend the laws of space
[20:00:54] <acaan> and time
[20:00:54] <thewormkill> well, you could just check whether x is 0 but that leaves you with deciding what to do now
[20:01:19] <Polyphony> "floating point exception (core dumped)"
[20:01:26] <Polyphony> that's what happens with c
[20:01:43] <thewormkill> so, basically we conclude that our function can *fail*
[20:01:57] <lenoch> kinda like exceptions
[20:01:59] <Polyphony> set errno and return NULL
[20:02:26] <thewormkill> well, that's a way of representing failure, but it certainly isn't beautiful
[20:02:35] <thewormkill> ...or not feasible in a pure context
[20:02:39] <Polyphony> lol
[20:02:43] <acaan> well just say undefined
[20:02:55] <thewormkill> so instead we alter the output range of our function
[20:02:55] <Polyphony> can we just pause for a moment, i'm gonna switch computers real quick
[20:02:56] <acaan> its nothing
[20:03:00] <thewormkill> Polyphony: sure
[20:03:11] <lenoch> ok i'm reboot to the linoox then
[20:03:13] <Polyphony> kk, it'll take like 5 seconds
[20:03:14] <thewormkill> acaan: sure, but we're coming to that
[20:03:20] <thewormkill> we'll wait
[20:03:27] <acaan> sure
[20:03:47] *** lenoch is now known as lenoch_away
[20:04:14] <Polyphony> o/
[20:04:22] <Polyphony> i'm back, told you it'd be quick
[20:04:44] <thewormkill> lenoch left
[20:05:33] <thewormkill> still left
[20:05:35] <acaan> it connection i gues
[20:06:03] <thewormkill> no he's rebooting
[20:06:23] *** lenoch_away is now known as lenoch
[20:06:30] <thewormkill> oh, we can proceedd
[20:06:45] <thewormkill> well, acaan proposed to add undefined to the range of our function
[20:06:45] <lenoch> fucking windows update
[20:07:16] <thewormkill> that makes sense, but if we pass our result on to other functions (look up composition if you don't know what that is)
[20:07:34] <thewormkill> , we need those functions to know of undefined
[20:07:37] <thewormkill> meh, ugly
[20:07:54] <thewormkill> so, instead we decide to add the *context of failure*
[20:07:56] <lenoch> can't you do an if?
[20:08:15] <thewormkill> lenoch: we do, but that's ugly if we need to repeat it
[20:08:59] <Polyphony> so how does haskell handle it?
[20:09:01] <lenoch> so what do we use?
[20:09:04] <thewormkill> so, let's redefine the range of our function to two values: "Nothing" and "Just x"
[20:09:06] <acaan> MONAD
[20:09:18] <thewormkill> where x is the result of our computation
[20:09:32] <acaan> the same function f(x)=1/x ?
[20:09:44] <thewormkill> we basically pull out undefined from the range of results and handle it dufferently
[20:09:53] <thewormkill> acaan: yes, with a quirk
[20:09:55] <thewormkill> observe
[20:10:06] <thewormkill> f(x) = 1/x if x != 0
[20:10:15] <thewormkill> f(x) = Nothing otherwise
[20:10:35] <lenoch> can you do it in haskell? that just looks weird :p
[20:10:46] <thewormkill> *FIX: the first line has a Just
[20:10:50] <thewormkill> lenoch: yes, you can
[20:10:57] <acaan> well its like c with if statement
[20:11:03] <thewormkill> haskell has a datatype called Maybe a
[20:11:10] <thewormkill> a is any type
[20:11:23] <thewormkill> and Maybe has two value constructors
[20:11:27] <lenoch> yeah I saw that pop around
[20:11:42] <thewormkill> 1. Nothing 2. Just a
[20:11:48] <thewormkill> where a is a value of type a
[20:11:57] <thewormkill> fuck I took the same name for both -.-
[20:12:37] <thewormkill> is that clear that way of should I clarify?
[20:13:10] <acaan> not really
[20:13:25] <acaan> maybe is datatype that we pass two values ?
[20:15:56] <thewormkill> No, Maybe is a datatype that has two constructors
[20:16:04] <thewormkill> Nothing, which takes no arguments
[20:16:13] <thewormkill> and Just x that takes one (x)
[20:16:25] <lenoch> constructors in the oop sense?
[20:16:31] <thewormkill> not exactly
[20:16:48] <thewormkill> a value constructor constructs a value by representing the arguments
[20:17:01] <thewormkill> basically it's a pattern for a value of a type
[20:17:08] <thewormkill> but you can have multiple patterns
[20:17:47] <thewormkill> so, we have a datatype that incorporates failure
[20:18:11] <thewormkill> a function that returns something of type Maybe Int can return:
[20:18:18] <thewormkill> 1. Just <an int here>
[20:18:20] <thewormkill> 2. Nothing
[20:18:36] <thewormkill> but what if we want to chain functions?
[20:18:40] <acaan> ohhh
[20:19:01] <acaan> well it fine if it returns maybe
[20:19:19] <thewormkill> and if the second one *takes* a maybe as argument
[20:19:29] <thewormkill> if it takes an int, we can't do that
[20:19:58] <thewormkill> but there is a concept called a Functor
[20:20:28] <thewormkill> a functor is just this: some construct that contains a value and adds some specific context to it
[20:20:42] <thewormkill> but now comes the interesting part:
[20:21:17] <thewormkill> a functor defines a function fmap that takes a function that takes a type a and a functor with a type a in it
[20:21:32] <thewormkill> and returns a functor with the result of the function in it
[20:21:41] <thewormkill> and it obeys one law
[20:21:44] <thewormkill> if you call
[20:22:07] <thewormkill> fmap identity f where f is an arbitry functor with something inside, you get f back
[20:22:22] <thewormkill> so, that was a lot of info, are there any questions?
[20:22:58] <lenoch> I should learn haskell to understand it fully right?
[20:23:08] <acaan> and math
[20:23:15] <acaan> i mean just enoguh
[20:23:46] <thewormkill> lenoch: well, is there something unclear? because this is just generic atm
[20:24:15] <lenoch> the context thing with a functor
[20:24:29] <lenoch> what do you mean with context?
[20:24:39] <thewormkill> in our example it is failure
[20:25:03] <thewormkill> but it can be basically anything: non-determinism, side-effects...
[20:25:12] <lenoch> oh so a functor is like a return value for a function?
[20:25:26] <thewormkill> no, it's a thing that contains a value
[20:25:34] <thewormkill> and adds some context to it by being thee
[20:25:37] <thewormkill> *there
[20:25:45] <lenoch> anything? or just a function as value?
[20:26:20] <thewormkill> I don't really understand what you mean
[20:26:46] <lenoch> is it like a lambda?
[20:26:54] <thewormkill> no.
[20:27:08] <thewormkill> lists are functors
[20:27:14] <thewormkill> maybe's are as well
[20:27:29] <thewormkill> the idea is that each functor contains values
[20:27:37] <thewormkill> and that it adds context
[20:27:49] <thewormkill> in case of maybe that's the possible absence of a value
[20:28:09] <thewormkill> in case of a list that's the possibly unlimited number of values
[20:28:35] <thewormkill> acaan, Polyphony, do you have questions as well?
[20:29:29] <acaan> hmm, what does functor returns ?
[20:29:45] <Polyphony> honestly i'm just logging this convo so i can look at it later
[20:29:58] <thewormkill> okay, Polyphony
[20:30:05] <thewormkill> acaan: it does not return anything
[20:30:08] <Polyphony> i am a data hoarder, and this is kind of interesting :P
[20:30:16] <thewormkill> it's not a function
[20:30:31] <acaan> its a special haskell construtc ?
[20:30:34] <thewormkill> a list doesn't return anything, doesn't it?
[20:30:35] <acaan> *construct
[20:30:43] <thewormkill> acaan: no, that's category theory
[20:30:55] <acaan> ohh its like wrapper for datatype ?
[20:30:57] <thewormkill> lenoch: is it getting a bit clearer now?
[20:30:59] <thewormkill> acaan: yes
[20:31:05] <thewormkill> absolutely
[20:31:09] <lenoch> ooooh
[20:31:44] <lenoch> Yeah I think it's good
[20:31:52] <acaan> its good now
[20:31:55] <acaan> alot clearer
[20:31:56] <thewormkill> good :)
[20:32:32] <thewormkill> now, we can just fmap functions over functors and thus apply functions to values inside them
[20:32:52] <thewormkill> but now there are some other contexts that are more complex, behod
[20:32:55] <thewormkill> *behold
[20:33:19] <lenoch> in haskel you can in theory chain infinite functions?
[20:33:32] <thewormkill> yes, but that gets messy around 500 ;)
[20:33:56] <lenoch> yeah I mean lol
[20:34:06] <thewormkill> jokes aside, what if our context is "having side effects"?
[20:34:09] <lenoch> seems quite powerfull in some scenario's
[20:34:14] <thewormkill> in all ;)
[20:34:29] <thewormkill> you can split it in parts, which you do
[20:34:32] <lenoch> use a Maybe
[20:34:37] <acaan> it can't have them ?
[20:34:44] <thewormkill> well, but you need them
[20:34:59] <thewormkill> if your program can't print to the screen, you might as well not run it
[20:35:23] <acaan> hmm
[20:35:31] <thewormkill> well, if you need to have a function to have side effects, the values it returns need a context
[20:35:38] <thewormkill> they are "contaminated"
[20:36:06] <thewormkill> I mean if you list a directory, your program needs to know that the data it got could have been different
[20:36:23] <thewormkill> and that it's computation required interacting with teh outside world
[20:37:02] <thewormkill> well, this also requires sequencing
[20:37:20] <thewormkill> let's say you print to the screen and print to the screen again
[20:37:28] <thewormkill> you want the data to appear in order
[20:37:56] <thewormkill> but if all your functions are pure, the compiler can do A LOT of optimizations, rearranging and the like to them
[20:38:10] <thewormkill> so, sequencing is explicit
[20:38:17] <thewormkill> enter monads
[20:38:23] * thewormkill bangs drum
[20:38:43] <thewormkill> a monad is a functor
[20:38:51] <thewormkill> but not each functor is a monad
[20:39:03] <thewormkill> a monad supports a few operations
[20:39:27] <thewormkill> 1. inserting a pure, a context-less value, into a default context
[20:40:17] <thewormkill> 2. taking a value in a monad (a monadic value) and a function that takes a pure value of the same type and returns a monadic value
[20:40:25] <thewormkill> let's express that in code:
[20:40:50] <thewormkill> (>>=) :: Monad m => m a -> (a -> m b) -> m b
[20:40:56] <thewormkill> whoo scary haskell
[20:41:04] <acaan> damn
[20:41:07] <thewormkill> but that's easy: it expresses a type
[20:41:14] <thewormkill> >>= is the function name
[20:41:35] <thewormkill> Monad m means that m is a monad (look up typeclasses if you want to know more)
[20:41:45] <thewormkill> m a is the first argument
[20:41:55] <thewormkill> it's a monad m with a value of type a inside
[20:42:09] <thewormkill> the second argument, (a -> m b) is function
[20:42:17] <thewormkill> now guess what it does
[20:42:40] <acaan> returns monad ?
[20:42:47] <acaan> or functor ?
[20:42:50] <acaan> or b
[20:42:52] <thewormkill> yes it takes an a and returns a monad with b inside
[20:42:59] <thewormkill> * a monad m
[20:43:18] <thewormkill> lenoch: you with us so far?
[20:43:57] * thewormkill throws chalk at lenoch
[20:44:18] <acaan> lol
[20:44:28] <thewormkill> is he asleep?
[20:44:56] <acaan> throw another one
[20:44:57] <Polyphony> heh
[20:45:20] <Polyphony> why in the hell would you name a function >>=
[20:45:33] *** lenoch is now known as lenoch_away
[20:45:41] <Polyphony> inb4 thewormkill is just trolling us all
[20:45:43] <thewormkill> Polyphony: you call it in infix notation
[20:45:55] <thewormkill> arg1 >>= arg2
[20:46:14] <thewormkill> inb4 you ask + is a function in haskell
[20:46:29] <Polyphony> oh lol i get it then
[20:47:33] <thewormkill> hm, not sure if I should carry on without lenoch, he has my last piece of chalk in his beer
[20:47:41] <thewormkill> oh the fucker is away
[20:47:56] <Polyphony> lel
[20:48:37] * thewormkill gets uses a nail to write on
[20:48:46] <thewormkill> okay, he'll catch up I'm sure
[20:49:11] <Polyphony> we're learning shell scripting in OS class... D:
[20:49:14] <thewormkill> well, this way you can chain monadic actions together
[20:49:27] <thewormkill> acaan: are you following at least?
[20:49:30] <thewormkill> ;)
[20:49:40] <Polyphony> acaan is now known as acaan_away
[20:49:42] <acaan> yes
[20:49:52] <thewormkill> good
[20:50:02] <thewormkill> well, now you can add order, how cool is that?
[20:50:38] <thewormkill> there are some more functions defined for monads tho:
[20:50:54] <thewormkill> fail (which just tells us that a monadic action is not possible)
[20:51:17] <thewormkill> and (>>) which has the type
[20:51:32] <thewormkill> (>>) :: Monad m => m a -> m b -> m b
[20:51:49] <thewormkill> it just executes it's arguments in order and returns the second
[20:52:37] <acaan> it returns b ?
[20:52:38] <thewormkill> This way, you can perform IO (although it is buried a bit in the actual implementation of haskell's features
[20:52:49] <thewormkill> acaan: it returns a monad with b inside
[20:53:09] <thewormkill> now, you may ask why we did all this
[20:53:19] <acaan> for no side effects ?
[20:53:38] *** lenoch_away is now known as lenoch
[20:54:03] <thewormkill> yes, you can have complete purity everywhere, unless you need something to perform IO
[20:54:11] <thewormkill> but even those functions are pure
[20:54:14] <thewormkill> you ask why?
[20:54:23] <thewormkill> simple, they just chain monadic actions
[20:54:30] <thewormkill> thus, they return a monad
[20:54:55] <thewormkill> and how that monad does what it does (IO, carrying state, adding read-only data...)
[20:55:06] <thewormkill> is completely independent of it's usage
[20:55:13] <acaan> it wraps it bascicly
[20:55:16] <acaan> it protects purenes
[20:55:17] <thewormkill> yes
[20:55:47] <thewormkill> IO is done by creating IO actions you need and generating the stuff you need to do for them
[20:56:03] <thewormkill> now, you may have noticed that a value can't escape a monad
[20:56:23] <thewormkill> if you put it in, you can transform it etc.
[20:56:27] <thewormkill> but it stays in there
[20:56:34] <thewormkill> because the context can't be undone
[20:56:49] <thewormkill> if you did IO to get a value, that value needs to be treated as such
[20:57:03] <thewormkill> lenoch: you missed a bit, right?
[20:57:13] <lenoch> yeah
[20:58:11] <thewormkill> well, I did essentially explain the basic concept of monads, so you just need to let me know what you missed :)
[20:58:26] <thewormkill> if anyone else has questions, feel free to ask them as well
[20:59:08] <lenoch> hmm no i don't think I missed it
[20:59:12] <lenoch> the bouncer had it
[20:59:26] <thewormkill> oh, nice
[20:59:39] <thewormkill> well, I'll put it up on evilzone, okay?
[20:59:47] <lenoch> good idea!
[21:00:02] * thewormkill is going to get the logs
[21:00:37] <acaan> cool, thanks thewormkill :D
[21:00:41] <thewormkill> np
[21:01:45] <acaan> ok i am starting with haskell now]

7
Found it on the Webs / A geometric proof that e is irrational
« on: September 29, 2015, 03:05:42 pm »
See link below, pretty good read to those interested in mathematics:
http://fermatslibrary.com/s/a-geometric-proof-that-e-is-irrational

8
Science / Erdös discrepancy problem solved
« on: September 26, 2015, 08:27:22 pm »
The article linked below sums it up pretty well, a very interesting read:
http://www.nature.com/news/maths-whizz-solves-a-master-s-riddle-1.18441

9
Well, I wrote it, it's as simple as it gets, but nonetheless complete. It simply runs scripts in a specific directory when a command is issued and returns their output. This has the benefit that we get module (un)loading, an interface and other nifty features essentially for free, keeping the core small (~180 SLOC), clean and fast (this is Haskell after all).

Apart from that, it interacts with IRC as a bot should; answers in PM's as well as channels, joins multiple channels, rejoins on kick, lists available scripts, and runs overall stable.

The project can be found over at github, where development takes place. Feel free to issue comments, suggestions, bugreports etc. there or in this thread.

Furthermore, if people like it and we gather some scripts for it, which should be very easy considering the no-API approach, and the developers of Techbot and BeastBot don't oppose this decision, we might use it as the "official" bot on IRC.

10
Found it on the Webs / Declarative Programming
« on: September 15, 2015, 06:25:44 pm »
This seems to be a quite interesting article, talking about abstaraction and programming paradigms, as well
as the heavily differing approaches thereof.

http://codon.com/hello-declarative-world

11
Found it on the Webs / IO in Haskell - a deeper look
« on: September 05, 2015, 12:38:16 am »
I found this great article about the inner workings of the IO monad in Haskell, and how it maintains purity in the context of functional programming:

https://pbrisbin.com/posts/the_advent_of_io/

Very informative and helpful, provided you know at least a bit Haskell and monads.

12
This is a set of tools I've written / currently work on. See the link below for a detailed description, installation instructions,
and the code. I'd love to hear suggestions, complaints and everything else you have to say here or on github.

https://github.com/ibabushkin/morgue

EDIT: I refactored the whole code, so the vim plugin moved to

https://github.com/ibabushkin/vim-markdown

... and is now intended to be used stand-alone, while maintaining compatibility with the fork-origin.

13
A few quite incoherent thoughts on software, interfaces and beauty, or how to think like a superuser

Introduction

In the following guide/tutorial/essay/call-it-how-you-like, I'll be talking a lot about productivity. When I use that word, I normally mean the speed at which you do some kind of work. While this is limited by your choice of text editor/document reader/insert-working-environment-here, other aspects of your environment influence the speed at which you actually think, so minimizing distraction will be a very important topic that, albeit not always explicitly mentioned, is almost always implicated.

Quote
But what is this writing for?

To become more productive, or as some call it, to become a superuser, and, more importantly, to understand the principles that are behind productivity in a computing environment. Please note that this is a quite subjective topic, so some of the advice and especially examples I will give, are tailored to my personal preferences. Still, the goal is to make the reader understand the principles behind my setup, to optimize his own.

So, let's get started.

Most of us probably work in some kind of computing environment on a regular basis, but a much smaller percentage actually shape this environment actively, instead of letting the environment shape their workflow. This task (configuring and tinkering that is) can become a huge timesink and might seem like a huge waste of energy and personal resources to outsiders. But if done right, it can heavily increase your productivity and make your environment not just suitable to the current task at hand, but also versatile and flexible.

Actually, some weird souls actually enjoy configuring their systems, but if you belong to this group, I feel the urge to warn you: Don't make it an excess, otherwise you might end up just wasting your time*.

Still, it is a useful task which follows a few key principles that actually make it useful. Although I present these principles in terms of my own preferences, experience and opinions, I believe it to be partly universal, and to some extend transferable to other contexts (your setup that is).

Let's talk about beauty

First of all let's do what the section's title suggests (now don't go all like "Oh no, he's going to shove his opinion down our throats...", because I will. Bear with me). While in itself, beauty is hard to describe, and even harder to actually define, there exist a few key notions of it that are rooted in mathematics (or science in general), and formulas in particular. While working with the mathematical notation of an equation or a problem, it becomes clear that simplicity, clean expressions are much easier to handle, and thus allow a far more beautiful description of a problem, situation, task etc., which is applicable in a far more generalized, less specialized context. This is what so different things, like functional programming, tiling window managers, vim and the theory of special relativity have in common; they either form or allow for simple, concise building blocks that can be (re-)combined to a larger whole, while being very elegant themselves and this way allowing to express complex things in a natural fashion.

TL;DR simplicity is beautiful.

Quote from: clueless
But what does beauty have in common with my computing environment?

Simple. You want to keep things simple and effective, stay focused on your task and get stuff done. And we already know that simple things are beautiful. Sounds familiar? You're right - the UNIX philosophy goes down that lane. And now, we will apply this humble principle:

How to get simplicity into your workflow - a checklist

1. Get rid of your mouse. This one is mentioned a lot. And for a reason. First of all, mousedriven interfaces tend to be badly designed, because screen space for buttons and menus is rare. Secondly, using your mouse requires conscious thinking, whereas a keyboard shortcut finds it's way into muscle memory after regular usage. And you need time to get your hand from the keyboard, find the mouse, and reposition your hand on the keyboard afterwards. But not always this is possible and feasible. Keep a healthy balance where needed, which brings us to the next point.

2. Use software that helps you realize point 1. In case of bad keyboard support, get yourself a replacement that does it better. Simple, yet effective.

3. Use consistent interfaces. If common usage-patterns in different applications follow the same logic, they are easier to learn and use.

4. Keep things visually clean, too. The first three points dealt with removing clutter from interfaces and your workflow, so why not do the same to your screen space? If you never use a GUI menu, it's useless, so hide it or switch your app for a better (cleaner) one (see point 2). Remember: the fewer distractions, the more productivity.

Now how do you actually realize that?

Below is a list of tools that help you do what was said above.

1. Choose the right OS. There is this great guide about that. The logic behind this point is simple: if your OS embraces simplicity, it will be easy to configure, modify and configure.

2. Choose the right WM. Possibly a tiled one. You spend (almost) all your time in it, so choose wisely. * Wikipedia article on tiled window managers * Examples include awesomeWM, Xmonad, dwm, i3, herbstluftwm, … google's your friend. I personally use awesomeWM, because it is extremely simple, completely keyboard-driven, configurable via Lua and generally awesome.

3. Do stuff in terminals. The CLI is very powerful and configurable, also very keyboard-friendly (duh.) And, for instance the Z Shell (ZSH) is very feature-rich and allows for a great deal of productivity.

4. Choose the right text editor. If you write anything, be it code or prose, chances are that you do it often. So make sure that you do it effectively. Some people swear by vim (I do), others by EMACS, go with what suites you most. Both are very feature-rich, extensible, and widely used. For a reason.

5. Improve your browsing experience. Most people spend very much time in a browser window, and most GUI browsers have slightly imperfect keyboard interfaces. Luckily, there are plugins that introduce vim-like or emacs-like shortcuts, to avoid the mouse and keep your interfaces consistent with each other. I recommend VimFX for Firefox.

This was quite an elaborate thought on beauty, simplicity, and how it applies to computing. Of course, there is no go-to solution for everybody, so this is merely a guide to get you started finding your own. One last note on how I do it:
  • Try something new if you're not fully content with what you have already.
  • Test it. Look how others do it. Read the docs. Research.
  • Apply it.
  • Repeat.
This actually applies to many different things.

If someone is interested, I'll include more details about my own config. Screenshots can be found here

Same goes for your own experience. If you want me to include something, mention a topic etc., just comment below

Happy tinkering!



* I know what I talk of, since I've spent literally days configuring software etc. I didn't end up using.

14
This is a nifty tool that does what the title describes.
Only problem: it does not compile properly with newer versions of pandoc, which it uses internally.
Thus, I modified it to account for the changes; installation instructions can be found in the original
content. To those who didn't get it: It is NOT ONLY my work, I merely fixed a few lines and added some
functionality, since it might be useful if you prefer Markdown to BBCode (like I do), but have to use it
here and/or somewhere else.

EDIT: I also changed some of the core functionality to make it play nicely with Evilzone's BBS (SMF).

EDIT2: Added language-recognition. If your code block contains contains information about the language
the code is written in, it will be included in the BBCode output.
And I documented the code properly in case someone wants to extend it.

EDIT3: Added quote-author-recognition. Block quotes like this:
Code: [Select]
> @TheWormKill
> Stuff he ^ said...

get converted to
Quote from: TheWormKill
Stuff he ^ said
Code: (Haskell) [Select]
{-# LANGUAGE DeriveDataTypeable #-}
{-# OPTIONS_GHC -Wall -Werror #-}

import Text.Pandoc
import Text.Pandoc.Error
import Control.Exception
import Data.Typeable

data ImplementationException = MkImpExc String
    deriving (Typeable)

instance Show ImplementationException where
    show (MkImpExc s) = "ImplementationException: " ++ s

instance Exception ImplementationException

-- heading levels associated with fontsizes
headingToFontsize :: [(Int, [Char])]
headingToFontsize = [(1, "36pt"), (2, "24pt"), (3, "18pt"),
                     (4, "14pt"), (5, "12pt"), (6, "10pt")]

-- get a pandoc-specific representation of our markdown source (or an error) and handle it
writeBbcode :: WriterOptions -> Either PandocError Pandoc -> String
writeBbcode _ (Right (Pandoc _ blocks)) = formatBlocks blocks
writeBbcode _ _ = error "Pandoc error occured!"

-- wrap a chunk of text in a BBCode-tag
-- wrapInTag "b" "bold text" returns "[b]bold text[/b]"
wrapInTag :: String -> String -> String
wrapInTag tag content =
  "[" ++ tag ++ "]" ++ content ++ "[/" ++ tag ++ "]"

-- same as wrap in tag, but take an additional parameter string:
-- wrapInTagParam "size" "20pt" "large text" returns "[size=20pt]large text[/size]"
wrapInTagParam :: String -> String -> String -> String
wrapInTagParam tag param content =
    "[" ++ tag ++ "=" ++ param ++ "]" ++ content ++ "[/" ++ tag ++ "]"

-- same as wrapInTagParam, but with an additional parameter name:
-- wrapInTagNamedParam "quote" "author" "TheWormKill" "Stuff I said" returns
-- "[quote author=TheWormKill]Stuff I said[/quote]"
wrapInTagNamedParam :: String -> String -> String -> String -> String
wrapInTagNamedParam tag paramName paramVal content =
    "[" ++ tag ++ " " ++ paramName ++ "=" ++ paramVal ++ "]" ++ content ++ "[/" ++ tag ++ "]"

-- reformat blockwise. each block in BBCode is delimited by 2 newlines.
formatBlocks :: [Block] -> String
formatBlocks = doubleUnlines . (map formatBlock)

-- handle possible blocks and convert to BBCode
formatBlock :: Block -> String
formatBlock (Plain ss) = formatInlines ss
formatBlock (Para ss) = (formatInlines ss)
-- check whether language information is supplied with the codeblock, and include it
formatBlock (CodeBlock a string) = case a of
                                     (_, l:_, _) -> wrapInTagParam
                                        "code" l (escapeCode string)
                                     _           -> wrapInTag "code"
                                        (escapeCode string)
formatBlock (RawBlock _ string) =  wrapInTag "code" (escapeCode string)
-- handle blockquotes with author information.
formatBlock (BlockQuote blocks) = case blocks of
                                    (b:bs) -> case getQuoteAuthor b of
                                               Just (name, b') -> wrapInTagNamedParam
                                                 "quote" "author" name (formatBlocks (b':bs))
                                               Nothing   -> wrapInTag "quote" (formatBlocks blocks)
                                    []    -> error "Empty block quote!"
formatBlock (OrderedList attr bss) = formatList (Just attr) bss
formatBlock (BulletList bss) = formatList Nothing bss
formatBlock (DefinitionList defs) = formatDefinitionList defs
-- use a sane font size, as the forum's form does and default to 8pt
-- in case that the level goes beyond 6
formatBlock (Header l _ ss) = wrapInTagParam "size"
    (maybe "8pt" id $ lookup l headingToFontsize) (formatInlines ss)
formatBlock (HorizontalRule) = "
[hr]"
formatBlock (Table _ _ _ headerRow rows) = formatTable headerRow rows
formatBlock (Null) = ""
-- uncomment this line for pandoc < 1.12
formatBlock (Div _ bs) = formatBlocks bs

-- get the author and the quote *itself* from a block if first inline is a Cite
getQuoteAuthor :: Block -> Maybe (String, Block)
getQuoteAuthor (Plain ((Cite (c:_) _):is)) = Just $ (citationId c, Plain is)
getQuoteAuthor (Para ((Cite (c:_) _):is)) = Just $ (citationId c, Para is)
getQuoteAuthor _ = Nothing

-- handle all inline elements from a block
formatInlines :: [Inline] -> String
formatInlines = concat . (map formatInline)

-- handle possible inline elements
formatInline :: Inline -> String
formatInline (Str s) = s
formatInline (Emph ss) = wrapInTag "i" (formatInlines ss)
formatInline (Strong ss) = wrapInTag "b" (formatInlines ss)
formatInline (Strikeout ss) = wrapInTag "s" (formatInlines ss)
formatInline (Superscript ss) = wrapInTag "sup" (formatInlines ss)
formatInline (Subscript ss) = wrapInTag "sub" (formatInlines ss)
formatInline (SmallCaps _) = throw (MkImpExc "small caps are not (yet?) supported")
formatInline (Quoted SingleQuote _) = throw (MkImpExc "single quotes are not (yet?) supported")
--"'" ++ (formatInlines ss) ++ "'"
formatInline (Quoted DoubleQuote _) = throw (MkImpExc "double quotes are not (yet?) supported")
--"\"" ++ (formatInlines ss) ++ "\""
formatInline (Cite _ l) = case l of
                            (Str s):_ -> s
                            _         -> ""
formatInline (Code _ s) = wrapInTag "b" s
formatInline (Space) = " "
formatInline (LineBreak) = "\n"
formatInline (Math _ s) = wrapInTag "math" s
formatInline (RawInline _ s) = wrapInTag "b" s
formatInline (Link ss (url, _)) = "[url=" ++ url ++ "]" ++ (formatInlines ss) ++ "[/url]"
formatInline (Image alt (url, _)) = "[img=" ++ (formatInlines alt) ++ "]" ++ url ++ "[/img]"
formatInline (Note _) = throw (MkImpExc "notes are not (yet?) supported")
-- uncomment this line for pandoc < 1.12
formatInline (Span _ ss) = formatInlines ss

-- obv useless, maybe the original author intended to make it escape sth?
escapeCode :: String -> String
escapeCode = id

-- formatters for lists, tables
formatList :: (Maybe ListAttributes) -> [[Block]] -> String
formatList attr items =
  let opener =
          case attr of Just (_, LowerAlpha, _) -> "[list=a]\n"
                       Just (_, UpperAlpha, _) -> "[list=a]\n"
                       Just _ -> "[list=1]\n"
                       Nothing -> "[list]\n"
   in opener ++
    (unlines $ map formatListItem items) ++
    "[/list]"

formatListItem :: [Block] -> String
formatListItem bs = "[*]" ++ (formatBlocks bs)

formatDefinitionList :: [([Inline], [[Block]])] -> String
formatDefinitionList defs =
  "[list]\n" ++
  (doubleUnlines $ map formatDefinition defs) ++
  "[/list]"

formatDefinition :: ([Inline], [[Block]]) -> String
formatDefinition (header, body) =
  "[*]" ++ ((wrapInTag "b" $
      wrapInTag "u" (formatInlines header)) ++ " " ++ (unlines $ map formatBlocks body))

formatTable :: [TableCell] -> [[TableCell]] -> String
formatTable headerRow rows =
  wrapInTag "table" $
  (formatHeaderRow headerRow) ++
  "\n" ++
  (formatBodyRows rows)

formatHeaderRow :: [TableCell] -> String
formatHeaderRow hcs = wrapInTag "tr" (concat $ map formatHeaderCell hcs)

formatHeaderCell :: TableCell -> String
formatHeaderCell hc = wrapInTag "th" (formatBlocks hc)

formatBodyRows :: [[TableCell]] -> String
formatBodyRows = unlines . (map formatBodyRow)

formatBodyRow :: [TableCell] -> String
formatBodyRow hcs = wrapInTag "tr" (concat $ map formatBodyCell hcs)

formatBodyCell :: TableCell -> String
formatBodyCell bc = wrapInTag "td" (formatBlocks bc)

-- join blocks into one string with 2 newlines
doubleUnlines :: [String] -> String
doubleUnlines [] = ""
doubleUnlines (s:[]) = s
doubleUnlines (s:ss) = s ++ "\n\n" ++ (doubleUnlines ss)

-- get markdown from stdin, process it, and print the results to stdout
main :: IO ()
main =
  getContents >>= \ input ->
  let
    readerOpts = def { readerParseRaw = False }
    pandoc = readMarkdown readerOpts input
    output = writeBbcode def pandoc
  in
    putStrLn output


15
Scripting Languages / [python] A simple pastebin uploader
« on: July 19, 2015, 12:08:18 am »
I know there are plenty. I know they can do much. But I like to roll my own minimalistic solutions.

It can read from files, stdin (until an EOL is issued) and soon maybe the clipboard.
Pretty easy to use, you just need a pastebin API key (more info here), a terminal on some
Unix and something to paste.
EDIT: Of course you'll need requests, too.
To install,
Code: [Select]
$ sudo pip install requestsEDIT2:
To use the optional clipboard dependency, run
Code: [Select]
$ sudo pip install clipboard(I might write my own tho, if someone wants).

(Or just download and install from pypi).

EDIT: cleaned and updated the code a bit.
EDIT3: Incorporated kenjoe41's suggestions. Thank you.
Here's the code:
Code: (Python) [Select]
import argparse
import sys

import requests

HAS_CLIPBOARD = True
try:
    import clipboard
except ImportError:
    HAS_CLIPBOARD = False


def post(string, form, expiry):
    post_dict = {'api_dev_key': '51652104665c18834023dae5d21d2a56',
                 'api_option': 'paste',
                 'api_paste_code': string
                 }
    if form:
        post_dict['api_paste_format'] = form
    if expiry:
        post_dict['api_paste_expiry_date'] = expiry
    return requests.post('http://www.pastebin.com/api/api_post.php', post_dict)


def get_input(source):
    if source != 'stdin':
        with open(source, 'r') as f:
            return f.read()
    return sys.stdin.read()


if __name__ == '__main__':
    ARG_PARSER = argparse.ArgumentParser(
        description='Post something to pastebin.com')
    ARG_PARSER.add_argument('-s', default='stdin',
                            help='The source of the paste (default: stdin).')
    ARG_PARSER.add_argument('-f', help='The format (default: none.')
    ARG_PARSER.add_argument('-e', help='The expiry time (default:none).')
    ARG_PARSER.add_argument('-c', help='Use clipboard as source',
                            action='store_true')
    ARGS = ARG_PARSER.parse_args()
    if not ARGS.c:
        input_string = get_input(ARGS.s)
    elif HAS_CLIPBOARD:
        input_string = clipboard.paste()
    else:
        print 'You don\'t have https://pypi.python.org/pypi/clipboard!'
        sys.exit()
    print '\nuploading...'
    print post(input_string, ARGS.f, ARGS.e).content

Pages: [1] 2