←2007-10-29 2007-10-30 2007-10-31→ ↑2007 ↑all
00:09:46 -!- RedDak has quit (Remote closed the connection).
00:49:02 -!- Tritonio has joined.
00:53:59 <pikhq> ehird`: Any further clues on PEBBLE in PEBBLE?
00:54:17 <ehird`> pikhq: no, i haven't tried today :( sorry
00:54:19 <bsmntbombdood> what?!?!
00:54:24 <ehird`> pikhq: tomorrow, though, i'll do it
00:54:26 <oerjan> It's pebbles all the way down!
00:54:30 <ehird`> bsmntbombdood: i'm going to write a pebble compiler in pebble
00:54:41 <ehird`> and vanquish the evil tcl... from my version, at least.
00:54:50 <ehird`> i mean, the compiler for pebble looks pretty trivial
00:55:00 <ehird`> but, no string manip in PEBBLE iirc, so a bit harder
00:55:03 <bsmntbombdood> for some reason i just started downloading 2gb of nigel kennedy >_<
01:02:45 -!- sebbu has quit ("@+").
01:08:05 -!- pikhq has quit (Read error: 104 (Connection reset by peer)).
01:10:28 -!- pikhq has joined.
01:26:45 <ehird`> pikhq: hmm, what would pebble-in-pebble mean for pfuck?
01:26:50 <ehird`> i'm sure there's some profound implication
01:31:13 <pikhq> XD
01:31:25 <ehird`> would the universe explode?
01:31:28 <ehird`> would it go 50 times faster?
01:35:02 <ehird`> :)
01:35:12 <ehird`> pikhq: IT WOULD ENVELOP AWESOMENESS INTO ITS COMPILED CODE
01:36:13 -!- oerjan has quit ("Late very good").
01:36:17 <pikhq> It would merely be amusingly recursive.
01:36:28 <ehird`> So, distro:
01:36:36 <ehird`> pebble.b src/lotsofstuff.pebble
01:36:52 <ehird`> pebble.b, compiled with PFUCK, running under a C version of PEBBLE, compiled by pebble.b
01:36:56 <ehird`> Understand THAT!
01:37:47 <pikhq> pebble compiles pebble.bfm. pfuck compiles pebble.b. gcc compiles pebble.c. pebble comipiles pfuck.bfm. pfuck compiles pfuck.b. gcc compiles pfuck.c.
01:37:52 <pikhq> ;)
01:38:01 <ehird`> (bfm? that's pebble, right?)
01:38:12 <pikhq> (I use the .bfm prefix still)
01:38:18 <pikhq> (s/pre/post/)
01:38:22 <ehird`> ok, right, i'll explain, in PEBBLE/tcl and PEBBLE/pebble:
01:38:32 <ehird`> PEBBLE/tcl, long time ago, compiles pebble.bfm
01:38:34 <ehird`> LATER
01:38:41 <ehird`> wait
01:38:50 <ehird`> PEBBLE/tcl, long time ago, compiles pebble.bfm to-C: now it's PEBBLE/pebbleC
01:38:51 <ehird`> LATER
01:39:05 <ehird`> PEBBLE/pebbleC runs PFUCK, compiles pebble.bfm
01:39:27 <ehird`> (producing PEBBLE/pebbleBF)
01:39:50 <ehird`> of course, since PEBBLE/pebble's output - BF and C - will not always be identical to PEBBLE/tcl
01:40:02 <ehird`> there are more iterations of PEBBLE/pebbleC compiling pebble.bfm to-C in "LATER"
01:41:17 <ehird`> :D
01:41:22 <ehird`> pikhq: crazy, no?
01:41:41 <pikhq> I'd consider pebble.bfm to be *another* implementation of PEBBLE; I'd still maintain pebble.tcl. ;)
01:41:47 <pikhq> And, yeah, that is crazy.
01:41:50 <ehird`> of course
01:42:10 * pikhq assumes pebble.bfm, for a first run, at least, would not support optimization, language-specific macros, etc.
01:42:24 <ehird`> pebble.tcl is needed!
01:42:25 <ehird`> (For bootstrapping, of course. What do you mean, it may be useful as an implementation? Pff. Surely you jest. pebble.tcl would not come out of my hands originally! My logic is infallable. I do not suffer from NIH-overload.)
01:42:37 <ehird`> yeah, i would implement those after though
01:44:00 <ehird`> i'm heading off now
01:44:10 <ehird`> pikhq: pebble.bfm - the revolution begins tomorrow! ;)
01:44:35 -!- ehird` has quit (Read error: 104 (Connection reset by peer)).
01:45:07 -!- RodgerTheGreat has joined.
01:45:17 <RodgerTheGreat> hi everyone
01:45:50 <pikhq> XD
01:46:31 * pikhq wants to see how ehird handles the "source" command.
02:30:16 <pikhq> Someone appears to be suggesting that ais523's 2,3 Turing machine proof is inaccurate. . .
02:31:02 <bsmntbombdood> haha
02:31:13 <bsmntbombdood> link
02:32:27 <bsmntbombdood> oh i see on slashdot
02:33:03 <pikhq> We of #esoteric should make the news by fixing that. ;p
02:33:19 <bsmntbombdood> what's FOM?
02:36:53 <bsmntbombdood> and what did we fix?
02:38:45 <bsmntbombdood> it's funny that a single mailing list post is enough for slashdot to post
02:39:11 -!- Sgeo has quit (Read error: 104 (Connection reset by peer)).
02:39:26 <pikhq> I'd need to review the proof quite thouroughly before being sure the mailing list post is at all correct.
02:42:22 <bsmntbombdood> ...as would anyone
02:42:28 <pikhq> Yeah.
02:48:09 -!- Sgeo has joined.
02:51:54 <bsmntbombdood> aww feck, homeworkd
02:55:36 <GregorR> homeworkd(1): Assigns homework based on crond scheduling.
02:56:43 <bsmntbombdood> lold
02:57:08 <bsmntbombdood> i should learn IPA
02:58:27 <bsmntbombdood> (instead of doing my homework)
02:59:19 <bsmntbombdood> transcription to extended ipa would be a fun speach compression method
03:33:18 <RodgerTheGreat> I recently came up with what I think is a fairly robust BF "While x> constant n: do code" construct
03:33:44 <RodgerTheGreat> I will use the notation n(stuff) to represent "stuff" being repeated n times
03:34:11 <RodgerTheGreat> x, tmp and flag are variable cells, and zero is initialized to be a constant zero
03:35:01 <RodgerTheGreat> x [ flag [-] n( [x - tmp + ) [ code flag + zero ] n( ] ) tmp [ - x + tmp ] flag ]
03:35:07 <RodgerTheGreat> what do you guys think?
03:35:42 <pikhq> Clever.
03:35:46 <RodgerTheGreat> :)
03:45:37 <RodgerTheGreat> I think it might be possible to do with fewer cells, but 1 cell for x and an overhead of 3 doesn't seem too bad for a reasonably high-level construct
03:58:50 <RodgerTheGreat> Is there a good general approach to string generation when you allow temporary space, or do most people do it with genetic algorithms/ brute force/ dynamic programming?
03:59:30 <pikhq> Define "good".
03:59:37 <pikhq> And the amount of temporary space.
04:00:37 <RodgerTheGreat> let's say three cells
04:01:01 <RodgerTheGreat> and the emphasis is on a "good, general" approach rather than simply a "good" approach
04:05:46 <pikhq> Well, you *could* do what PEBBLE does. . .
04:05:53 <bsmntbombdood> there needs to be a better algorithm for it
04:05:55 <bsmntbombdood> pikhq: what's that?
04:06:01 <pikhq> It ain't terribly good, but it's general.
04:06:25 <RodgerTheGreat> I am quite curious
04:06:38 <pikhq> bsmntbombdood: It just uses two-cell wrapping implementations of the constants to add and subtract from a cell. . .
04:06:46 <bsmntbombdood> lame
04:06:53 <RodgerTheGreat> the algorithm is very straightforward if you try generating strings from a single cell
04:06:56 <RodgerTheGreat> hm
04:07:03 <pikhq> It doesn't work too badly for a naive algorithm.
04:07:28 <RodgerTheGreat> I suppose that'd generate decent output, but clearly far from optimal
04:10:00 <bsmntbombdood> i think i'm going to work on an algorithm
04:10:42 <RodgerTheGreat> go for it, dude
04:12:08 <pikhq> If it's good, I may well include it in PEBBLE.
04:14:15 <RodgerTheGreat> maybe try to find numbers that meet a balance between being the most common in the target string and the furthest apart from one another?
04:24:28 -!- Tritonio has quit (Remote closed the connection).
04:42:55 <ttm> I'm looking at this "while". If n=3 then it translates as
04:42:59 <ttm> x tmp flag zero
04:42:59 <ttm> [>>[-][<<->+[<->+[<->+[code>+>]]]]<<[-<+>]>]
04:43:00 <ttm> ?
04:45:23 <RodgerTheGreat> that looks correct
04:45:48 <bsmntbombdood> geez, i haven't coded in a while
04:46:00 <bsmntbombdood> i'm getting confused >_<
04:47:15 <ttm> That can't be right. For one thing, it has a ][ in it.
04:47:50 <immibis> yes. removing the ][, you get [>>[-]<<[-<+>]>]
04:47:53 <bsmntbombdood> what's the brainfuck for taking [n, 0, 0, ...] to [n, n*2, n*3, ..., n*m, 0, 0 ...]?
04:48:12 <immibis> which never executes the code.
04:48:17 <RodgerTheGreat> ttm: ah... whoops
04:48:46 <RodgerTheGreat> good catch- you need to move to x after zeroing flag, before you begin the if block
04:49:01 <ttm> bsmnt how confident are you that all values will fit in a byte?
04:49:09 <bsmntbombdood> ttm: perfectly
04:49:22 <ttm> Okay. Let's think then.
04:49:30 <bsmntbombdood> m is below floor(n/256)
04:49:44 <bsmntbombdood> *m = floor(n/256)
04:50:55 <ttm> x tmp flag zero
04:50:55 <ttm> [>>[-]<<[->+[<->+[<->+[code>+>]]]]<<[-<+>]>]?
04:51:59 <RodgerTheGreat> yeah
04:58:52 <ttm> Hm. Still can't be right. [>>[-]<<[->+<[->+<[->+<[code>>+>]]]]<<[-<+>]>] is probably getting closer...
05:00:24 <RodgerTheGreat> that really depends on what's in code
05:01:24 <ttm> bsmnt is m stored in memory, and are we okay with wiping it out? Or is it constant?
05:08:35 <RodgerTheGreat> the two things that must occur in the main [] set with code are that flag is set to "true" (nonzero), and we move to constant zero to break out of all our nested brackets
05:08:57 <ttm> That's clear.
05:11:32 <ttm> What's not entirely clear is how the outermost loop is supposed to match up. We started it at x, and we end it at flag. So we need some code near the start of the outermost loop to resynch the pointer location...and we also need to leave ourselves a way, after we break out of that outer loop, to check on whether we went through it at all.
05:16:42 <RodgerTheGreat> that's the purpose of flag
05:17:13 <RodgerTheGreat> if we make it to the innermost loop and execute code, flag is set, and we continue the main while loop, and it's reset for the next iteration
05:22:26 <ttm> Yeah...but if we end the main while loop at flag, when we started it at x, then the code will not be acting on the same things unless we add other code to insure the pointer is at the same place in both cases.
05:22:59 <ttm> Whereas if we start the main loop at flag both times, then it won't have the correct value at first unless we add extra code first to set it...
05:26:57 -!- Sgeo has quit (Read error: 110 (Connection timed out)).
05:30:29 <RodgerTheGreat> well, I need to sleep. I'll look this over again in the morning, and think about some revisions
05:30:41 <ttm> Good night and good luck.
05:30:55 <RodgerTheGreat> thanks for helping me find my mistakes
05:31:01 -!- RodgerTheGreat has quit.
05:57:33 <bsmntbombdood> ttm: constant
05:58:19 <bsmntbombdood> and the code is [>+>++>+++<<<-]
05:58:44 <bsmntbombdood> etc
06:00:20 <bsmntbombdood> although that would get inneficient when n is small
06:10:42 <ttm> Ah. I was trying to figure the most concise way to do it with variable m.
06:12:00 <bsmntbombdood> it would be cool if there was a way to do it without all the redundant +s
06:14:30 <ttm> Well, if you put m just to the right of where you want the last one to end up, you can do [<[+<]+[>]<-]
06:14:58 <bsmntbombdood> where does that start?
06:15:08 <ttm> at m.
06:15:58 <bsmntbombdood> i don't think that works
06:20:06 <ttm> And...you're right. You can do it once, but it won't work right twice let alone n times.
06:20:41 -!- DawnLight has joined.
06:22:16 <bsmntbombdood> /bed
06:26:09 <ttm> It works if you space them out. for m=5 we have >>>>>>>>>>>>>>,[<<+++++[<[+<<]+[>>]<-]<[<<]>>[[<+>-]>>]>-]<<<<.<<.<<.<<.<<.
06:33:02 <DawnLight> my god
06:39:50 <ttm> There should be some really clever concise way to do this without using so much apparatus. But I'm not seeing it right now.
07:37:53 -!- DawnLight has quit (Read error: 110 (Connection timed out)).
07:51:14 -!- DawnLight has joined.
07:59:59 -!- clog has quit (ended).
08:00:00 -!- clog has joined.
08:21:02 <DawnLight> i need a command that will print a certain number of byes from a serial port and quit!
08:21:40 <immibis> a command in what language
08:22:17 <DawnLight> a linux command
08:22:25 <DawnLight> doh
08:23:03 <DawnLight> cat works the way it does because files have endings but /dev/ttyS0 doesn't
08:23:31 <DawnLight> that's also true about inotail and dog doesn't read it at all
08:25:30 <immibis> try 'head -cNUMBER_OF_BYTES /dev/ttyS0'
08:27:28 <DawnLight> immibis: yay!
08:28:12 <DawnLight> thanks
08:32:32 -!- immibis has quit (Read error: 104 (Connection reset by peer)).
09:54:38 -!- jix has joined.
10:34:37 -!- AnMaster has joined.
11:49:59 -!- RedDak has joined.
12:22:08 -!- sekhmet has quit (Read error: 110 (Connection timed out)).
12:25:25 <AnMaster> btw, somewhat insane optimizing brainfuck compiler coded in bash: http://rage.kuonet.org/~anmaster/bzr/index.py/get/bashfuck/head/bashfuck
12:25:31 <AnMaster> there are still a few bugs to fix in it
12:25:56 <AnMaster> it does have some problems with LostKng.b, some off by one error that I'm trying to find
12:26:35 <AnMaster> s/compiler/interpreter
13:34:38 -!- lifthrasiir has quit (Remote closed the connection).
13:51:20 -!- puzzlet has quit (Remote closed the connection).
13:51:28 -!- puzzlet has joined.
13:53:50 -!- oerjan has joined.
14:01:01 -!- DawnLight has quit (Read error: 113 (No route to host)).
14:26:59 -!- puzzlet has quit (Remote closed the connection).
14:27:06 -!- puzzlet has joined.
14:27:25 -!- sekhmet has joined.
15:09:29 -!- ehird` has joined.
15:56:57 <ehird`> does any known BF interp optimize [+>-+<-] to []?
16:04:00 <oklopol> EgoBot prolly
16:04:05 <oklopol> that's a trivial optimization
16:04:36 <oklopol> "+-" -> "", "><" -> "", actually, many of my bf's would do that too
16:05:09 <ehird`> yeah
16:05:12 <ehird`> mine is going to do that
16:05:41 <ehird`> it'll optimize in a loop
16:05:49 <ehird`> first it'll see -+
16:05:55 <ehird`> so [+><-]
16:05:58 <ehird`> then it'll see ><
16:05:59 <ehird`> so [+-]
16:06:02 <ehird`> then it'll see +-, so []
16:06:04 <ehird`> and we're done
16:09:23 <oklopol> i assume it optimizes any string of +
16:09:24 <oklopol> ...
16:09:36 <ehird`> yeah
16:09:38 <oklopol> i assume it optimizes any string of +'s and -'s into one with just one of them
16:09:39 <ehird`> but that's how mine does it
16:09:41 <ehird`> yeah
16:09:49 <ehird`> i have a "modify" instruction
16:09:55 <ehird`> +-- is { modify, -1 }
16:10:07 <oklopol> yeah i did it that way too
16:10:20 <ehird`> fast
16:18:16 -!- RedDak has quit (Remote closed the connection).
16:26:18 <ehird`> oh dear
16:26:20 <ehird`> http://cs.nyu.edu/pipermail/fom/2007-October/012156.html
16:26:23 <ehird`> found this on reddit...
16:26:35 <ehird`> apparently it's wrong
16:26:36 <ehird`> but...
16:37:05 <oerjan> poor guy
16:37:12 <ehird`> indeed
16:37:30 <ehird`> people seem to be disagreeing
16:38:02 <oerjan> it's a fundamental added subtlety when you have things like CAs with infinite initial state
16:39:01 <ehird`> lool
16:39:06 <ehird`> this crappy page on pi is hilarious
16:39:08 <ehird`> "*known to be over 5 billion digits long"
16:39:31 <ehird`> (this is from 1997, and has MIDI background music)
16:41:06 * cherez chortles his posterior off.
16:41:17 <cherez> ehird`: Where's this pi page?
16:41:29 <ehird`> http://members.aol.com/loosetooth/info.html
16:41:39 <ehird`> *the equivalent of 180 degrees when measured in radians
16:41:43 <ehird`> you know i don't think that's coincidential!
16:43:37 <cherez> "If pi were just 3, then we wouldn't have circles at all!"
16:45:20 <cherez> "At the end of most Macintosh source codes."
16:45:36 <cherez> Whenever I port stuff to Mac, I define pi at the end of the file.
16:45:45 <ehird`> it's probably a magic number
16:46:00 <ehird`> hm
16:46:11 <ehird`> what's the most efficient way of parsing brainfuck [ ... ]s when using instruction structs?
16:46:17 <ehird`> (i.e. you can't store positions in code in a stack)
16:47:35 -!- DawnLight has joined.
16:50:43 <DawnLight> is it ok if i come here once in a while asking questions that will probably be irrelevant to the channel but which i assume someone here may know the answer for? and they may be dumb questions. and they may be questions for which the answers may be a few pages of reading away from me. so can i do that?
16:52:25 <oerjan> well everyone here does that, but it would be nice if you were on-topic occasionally :)
16:52:29 <oklopol> no, this channel never gets offtopic, try asking something irrelevant and you get banned instantly
16:52:36 <oklopol> err... what oerjan said.
16:53:02 <ehird`> HEY, I LIKE PIE
16:53:15 <oerjan> we agree completely, as you can see
16:53:27 <oerjan> IN THE SKY
16:53:36 <oklopol> NEVERMIIIND THE WINDS
16:53:39 <ehird`> we agree completely IN THE SKY
16:53:55 * oerjan just learned that expression
16:53:59 <oklopol> did i guess the rest of the song correct?
16:54:16 <oerjan> oklopol: indeed
16:54:17 <oklopol> in the ski
16:54:31 <DawnLight> so i'm gon' ask
16:54:38 <oerjan> ``sk`sii```ksi
16:54:53 <oklopol> >>> sk ``sk`sii```ksi
16:54:58 <oklopol> >>> ul ``sk`sii```ksi
16:55:00 <ololobot> -> ('s', 'k', ('s', 'i'))
16:55:01 <oklopol> i should rename that.
16:55:03 <oklopol> it's not unlambda..
16:55:14 <oklopol> or better yet! i should make it unlambda ;)
16:55:19 <ehird`> >>> ul `ss
16:55:20 <ololobot> -> ('s', 's')
16:55:20 <oerjan> alas, it was just something i banged on my keyboard
16:55:22 <ehird`> >>> ul `s`sk
16:55:23 <ololobot> -> ('s', ('s', 'k'))
16:55:30 <ehird`> >>> ul `k`s`sk
16:55:31 <ololobot> -> ('k', ('s', ('s', 'k')))
16:55:49 <ehird`> >>> ul ```sii``sii
16:55:50 <ololobot> -> [['i', ('s', 'i', 'i')], ['i', ('s', 'i', 'i')]]
16:55:55 <ehird`> That's Not Right
16:56:01 <oklopol> oerjan: tell that to your computer next time you just "bang on your keyboard" and erase all your files.
16:56:30 <oklopol> interesting
16:56:50 <oklopol> >>> ul ```sii``si.k
16:56:51 <ololobot> kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk -> [['i', ('s', 'i', '.k')], ['.k', ('s', 'i', '.k')]]
16:57:02 <oklopol> yeah, it just terminates at some point
16:57:14 <oklopol> should i make it crash instead?
16:57:30 <ehird`> nah
16:57:30 -!- puzzlet has quit (Remote closed the connection).
16:57:35 -!- puzzlet has joined.
16:57:35 <ehird`> make it detect infinite loops
16:57:39 <oklopol> DAZ WHUTTI THOUGHT
16:57:41 <oerjan> as a mad genius to another, i say make it take over the world
16:57:53 <oklopol> MWAHAHAHA IT ALREADY DOES THAT!
16:57:55 <ehird`> store all previous states, if it returns to a previous state, output "infinite loop, reached [matching state]"
16:58:07 <ehird`> ski programs are not going to be big enough to make that slow :P
16:58:45 <oerjan> hm, what about making Alabama sink into the ocean?
16:58:57 <oklopol> that's a pretty useless optimization, since they only help with small progs like ```sii``sii, and irc bots never get short programs, it's always something huge.
16:58:58 <DawnLight> i need a linux command that will take some ascii as stdin and give raw bytes in stdout. for example, i give it 400132 and it gives me three bytes, 40, 01 and 32
16:59:07 <ehird`> oklopol: oh come on
16:59:09 <ehird`> oklopol: it'll be fun
16:59:13 <oklopol> kay
16:59:15 <oklopol> wait
16:59:55 <oklopol> btw. don't use it while i code, i could disable it, but i trust you
17:00:05 * oklopol likes egging ppl on
17:00:21 <ehird`> hey, that's clever
17:00:27 <ehird`> a bf interpreter using mmap
17:00:30 <ehird`> to read in code
17:01:41 <oerjan> DawnLight: in hex?
17:01:52 <DawnLight> oerjan: right
17:02:24 <oerjan> hm, can hexdump work in reverse?
17:02:47 <ehird`> does anyone know?
17:02:55 <ehird`> i mean you can't do a stack, with a struct
17:03:27 <oerjan> you can if it contains a pointer to the next one
17:03:42 <ehird`> right, but that's O(n) bracket matching
17:04:11 <oerjan> well obviously loops will be implemented as a unit
17:04:19 <DawnLight> oerjan: i think not
17:04:26 <ehird`> what do you mean oerjan?
17:04:39 <ehird`> by stack-parsing
17:04:41 <ehird`> i mean like this does http://www.hevanet.com/cristofd/brainfuck/sbi.c
17:04:53 <oklopol> uh, i just love python sometimes, i need to reindent every line, because it decided "indentation mixes spaces and tabs"
17:04:58 <oklopol> even though it totally doesn't.
17:05:10 <ehird`> indentation using both is forbidden in python
17:05:13 <ehird`> you can either use tabs or spaces
17:05:24 <oklopol> errr... orly :)
17:05:32 <oerjan> um, you can have a stack of currently open loops being parsed
17:05:54 <oerjan> that stack could be a linked list
17:06:00 <ehird`> yeah
17:06:03 <ehird`> that's what sbi.c does, kind of
17:06:09 <ehird`> but is it the fastest way?
17:06:31 <ehird`> i'm trying to make the parsing very quick in this interp, because the optimization step will be very heavy
17:06:47 <ehird`> the interpreting part is already compact, so if i can get the parsing fast too...
17:06:51 <ehird`> then i can concentrate on optimizations
17:07:55 <oklopol> interpreting will take too little to notice compared to the optimization even if you *try* to make it slow.
17:08:36 <ehird`> of course
17:08:37 <ehird`> but parsing
17:08:39 <ehird`> is pretty big
17:10:31 <oklopol> okay, i'll make the loop checker now
17:10:39 <oklopol> got everything reindented :P
17:10:47 <ehird`> IDLE can do that for you
17:13:35 <oklopol> >>> sk ```sii``sii
17:13:36 <ololobot> Infinite loop detected
17:13:59 <ehird`> noo
17:14:02 <ehird`> make it output where it finds it
17:14:05 <ehird`> i.e. the frame that it finds to repeat
17:14:06 <ehird`> :D
17:14:11 <oklopol> oh
17:14:11 <ehird`> it'll be a debugger!
17:14:13 <oklopol> kay.
17:15:18 <oklopol> glah, why isn't there a "return from whole recursion", like in oklotalk :<
17:15:34 <ehird`> just return None
17:15:35 <ehird`> then
17:15:38 <ehird`> when you recurse
17:15:44 <ehird`> if (recurse) == None: return None
17:16:33 -!- sebbu has joined.
17:16:50 -!- puzzlet has quit (Remote closed the connection).
17:16:57 -!- puzzlet has joined.
17:17:25 -!- SEO_DUDE56 has quit (Read error: 104 (Connection reset by peer)).
17:17:37 <oklopol> whoops.
17:17:52 <oklopol> i just realized that is not a trivial problem
17:18:08 <oklopol> given my current implementation, that is
17:18:19 <ehird`> XD
17:18:23 <ehird`> its very simple
17:18:26 <ehird`> each reduction step
17:18:30 <ehird`> states.append(frame)
17:18:33 <ehird`> then, each reduction step
17:18:37 <ehird`> if frame in states:
17:18:54 <ehird`> self.say("OMG " + frame + " REPEATS")
17:18:57 -!- DawnLight has left (?).
17:19:01 <oklopol> lol
17:19:17 <oklopol> i do evaluation recursively
17:19:33 <ehird`> so?
17:19:38 <oklopol> it's not trivial in that case, but this won't take long anyway
17:19:44 <oklopol> so? :\
17:20:04 <oklopol> i did exactly that, and now ```sii``sii evaluates i twice and says it's an infinite loop
17:20:14 <oklopol> it's not trivial, but it's easy
17:21:14 <oklopol> i mean, it's trivial if my next attemp works, if not, then i'll have to think a bit
17:21:54 <oklopol> okay
17:21:57 <oklopol> i think it's ready
17:22:06 <oklopol> >>> sk ```sii``sii
17:22:07 <ololobot> Infinite loop detected at [('s', 'i', 'i'), ('s', 'i', 'i')]
17:22:10 <ehird`> :D
17:22:16 <oklopol> >>> sk ``khs
17:22:17 <ololobot> -> h
17:22:55 <oklopol> i think i have a function to make that into an unlambda-like string, wait
17:23:05 <ehird`> >>> sk ``kh```sii``sii
17:23:06 <ololobot> Infinite loop detected at [('k', 'h'), [['i', ('s', 'i', 'i')], ['i', ('s', 'i', 'i')]]]
17:23:10 <ehird`> wtf
17:23:12 <ehird`> oh
17:23:13 <ehird`> no
17:23:14 <ehird`> that's right
17:23:16 <oklopol> i don't :<
17:23:18 <oklopol> hmm
17:23:25 <ehird`> it isn't lazily evaluating
17:23:27 <oklopol> it is? :\
17:23:41 <ehird`> ``kxy should only evaluate x
17:23:55 <oklopol> well, not really
17:23:57 <ehird`> no
17:24:00 <ehird`> that is how it works
17:24:01 <ehird`> its lazy
17:24:04 <oklopol> this is the ski part of unlambda
17:24:13 <oklopol> == strict
17:24:22 <oklopol> but...
17:24:24 <ehird`> well its not unlambda
17:24:29 <ehird`> so make it SKI and make it lazy :-)
17:24:41 <ehird`> so, what IS the most efficient method of matching braces brainfuck?
17:24:45 <oklopol> i can make k, i'm not making it fully lazy.
17:24:47 <ehird`> presumably not looping through teh program
17:25:17 <oklopol> oh, actually, i'm not making even k lazy.
17:25:28 <oklopol> now that i glanced at my code, and saw i'd have to do something.
17:26:24 <oerjan> ehird`: when you see a [ you start the parser recursively?
17:26:39 <ehird`> oerjan: recursion is bad though :/
17:26:42 <ehird`> oerjan: in this case
17:26:56 -!- jix has quit (Nick collision from services.).
17:27:06 -!- jix has joined.
17:27:15 <oerjan> equivalently, you push your current block on the stack, and start an empty one
17:27:33 <ehird`> that's pretty slow in this case though too
17:27:42 <oklopol> >>> sk `4 5
17:27:48 <oklopol> ..?
17:27:49 <oklopol> whut...
17:27:52 <ehird`> i just wonder, with my really simple struct what the most efficient way is to parse braces
17:27:55 <ehird`> >>> sk `45
17:28:01 <ehird`> that should return `45 :|
17:28:09 <oklopol> this is weird
17:29:50 <oklopol> i don't get it...
17:30:59 <oklopol> >>> sk ``s`kr``s``si`k.*`ki 4
17:31:00 <ololobot> -> ('s', ('k', 'r'), ('s', ('s', 'i', ('k', '.*')), ('k', 'i')))
17:31:05 <oklopol> ..
17:31:25 <oklopol> >>> pl ^n`r``$n.*i
17:31:26 <ololobot> ``s`kr``s``si`k.`k*
17:31:35 <oklopol> >>> pl ^n`r``$n*i
17:31:36 <ololobot> ``s`kr``s``si`k*`ki
17:32:36 <oklopol> i'm pretty sure that worked in the past...
17:32:47 <oklopol> oh
17:32:47 <ehird`> >>> pl ^a$a
17:32:48 <oklopol> r.
17:32:50 <ololobot> i
17:32:58 <ehird`> >>> pl ^a^b$a
17:32:59 <ololobot> ``s`kki
17:33:02 <ehird`> um
17:33:05 <ehird`> im pretty sure that's k
17:33:43 <oklopol> it doesn't optimize, it does the trick on the unlambda page
17:33:58 <ehird`> >>> pl ^a^b$b
17:33:59 <ololobot> `ki
17:34:23 <ehird`> >>> pl `^x`$x$x^x`$x$x
17:34:23 <ololobot> ```sii``sii
17:34:26 <ehird`> (gosh that syntax is ugly)
17:34:30 <oklopol> pl works, no doubt about it, it's the sk i'm worried about
17:35:05 <oklopol> shouldn't `4 5 exponentiate 4^5 :\
17:35:10 <ehird`> ...
17:35:12 <ehird`> what?
17:35:12 <ehird`> no
17:35:15 <oklopol> using the representation on the unlambda pge
17:35:15 <ehird`> it should return `45
17:35:16 <oklopol> *page
17:35:21 <oklopol> err kay.
17:35:31 <oklopol> >>> sk 4
17:35:32 <ololobot> -> ('s', ('s', ('k', 's'), 'k'), ('s', ('s', ('k', 's'), 'k'), ('s', ('s', ('k', 's'), 'k'), 'i')))
17:35:35 <ehird`> oh
17:35:38 <ehird`> you have them defined
17:35:39 <oklopol> that is correct
17:35:40 <ehird`> as constants
17:35:41 <oklopol> but...
17:36:03 <oklopol> >>> sk ` ``s`k.i``s``si`k.*`ki 4
17:36:04 <ololobot> ****i -> i
17:36:08 <oklopol> :DDDDDDDDDDDDDDDDDDDDDDDDDD
17:36:11 <ehird`> >>> sk *
17:36:12 <ololobot> -> *
17:36:12 <oklopol> god i'm an idiot xD
17:36:15 <ehird`> >>> sk x
17:36:16 <ololobot> -> x
17:36:17 <ehird`> >>> sk `xx
17:36:18 <ololobot> -> ('x', 'x')
17:36:19 <oklopol> >>> sk ` ``s`k.i``s``si`k.*`ki ` 4 5
17:36:25 <oklopol> >>> sk ` ``s`k.i``s``si`k.*`ki ` 4 3
17:36:26 <ololobot> *********************************************************************************i -> i
17:36:28 <ehird`> >>> sk `*`ik
17:36:29 <ololobot> -> ('*', 'k')
17:36:34 <ehird`> >>> sk `45
17:36:38 <ehird`> >>> sk `4 5
17:36:38 <oklopol> kay, it works, i just fail @ unlambda.
17:36:44 <ehird`> >>> sk `4 5
17:36:49 <ehird`> >>> sk ` 4 5
17:36:51 <ehird`> wtf
17:37:09 <oklopol> 4^5 is a big number, i also failed at math :))
17:37:36 <oklopol> if the result is too long, it just produces no output currently
17:37:48 <ehird`> >>> sk `s`4 5
17:37:56 <oklopol> omg, where's my time! it's 19:37 already :<
17:38:03 * ehird` wonders how to do "for i=0 to i=N, ..." in ski
17:38:19 <oklopol> use a different representation
17:38:22 <oklopol> for that
17:39:31 <ehird`> You would think parsing [] really quickly would be simple. :-|
17:40:25 <oklopol> >>> ` ``s`k.i``s``si`k.o`k. sk ```s``si`k``s``s``s``si`ki`k`ki`k`ki`s``s`ksk`k`k`kk4 5
17:40:32 <oklopol> whoops.
17:40:35 <oklopol> >>> ` ``s`k.i``s``si`k.o`k. sk ```s``si`k``s``s``s``si`ki`k`ki`k`ki`s``s`ksk`k`k`kk6 5
17:40:54 <oklopol> >>> ```s``si`k``s``s``s``si`ki`k`ki`k`ki`s``s`ksk`k`k`kk 6 5
17:40:59 <oklopol> >>> sk ```s``si`k``s``s``s``si`ki`k`ki`k`ki`s``s`ksk`k`k`kk 6 5
17:41:00 <oklopol> lol.
17:41:00 <ololobot> -> ('s', ('s', ('k', 's'), 'k'), ('s', ('s', ('k', 's'), 'k'), ('s', ('s', ('k', 's'), 'k'), ('s', ('s', ('k', 's'), 'k'), ('s', ('s', ('k', 's'), 'k'), ('k', 'i'))))))
17:41:14 <oklopol> >>> sk ` ``s`k.i``s``si`k.o`k. ```s``si`k``s``s``s``si`ki`k`ki`k`ki`s``s`ksk`k`k`kk7 5
17:41:15 <ololobot> ooooooi -> .
17:41:25 <oklopol> that's... almost correct.. :<
17:42:57 <oerjan> oklopol> omg, where's my time! it's 19:37 already :<
17:43:08 <oerjan> me thinks you forgot to change to winter time?
17:43:18 <ehird`> lol, daylight savings
17:44:38 <oerjan> unless finland actually changes on a different day than most of europe
17:44:39 <oklopol> oerjan: it's not my birthday yet, but thanks for the hour, best gift i've ever gotten :)
17:44:55 <oklopol> or...
17:44:56 <oerjan> yay
17:45:04 <oklopol> it's backwards right? :P
17:45:16 <oklopol> o
17:45:19 <oklopol> (19:44:40) (oklopol) it's backwards right? :P
17:45:19 <oklopol> (18:44:50) (oklopol) o
17:45:22 <oklopol> success!
17:45:24 <oerjan> 17:45 here
17:45:36 * ehird` wonders whether to mmap or getc repeatedly
17:45:36 * oklopol does a little dance
17:45:43 <ehird`> it seems like mmap would be more efficient
17:46:36 <oklopol> how would you use it?
17:48:31 <ehird`> umm
17:48:32 <ehird`> like mmap?
17:50:26 <oklopol> how would that help in parsing?
17:52:28 <ehird`> well
17:52:29 <ehird`> i just mean
17:52:31 <ehird`> for reading in
18:03:54 <ehird`> case O_JMP:
18:03:54 <ehird`> if ((arg && !tape[tapep]) || (!arg && tape[tapep])) {
18:03:54 <ehird`> i = i->arg2;
18:03:54 <ehird`> continue;
18:03:54 <ehird`> }
18:04:01 <ehird`> that's clever :-) no more [ and ] instructions
18:05:49 -!- RodgerTheGreat has joined.
18:10:44 -!- SEO_DUDE56 has joined.
18:10:49 <ehird`> ok, efficient interpreter - check
18:10:51 <ehird`> now to write the parser
18:10:52 <ehird`> :P
18:11:16 <ehird`> poll: mmap or getchar over and over?
18:11:53 <oklopol> mmap sounds nicer.
18:12:11 <ehird`> that's not helpf
18:12:13 <ehird`> ul
18:12:15 <ehird`> :P
18:31:09 -!- oerjan has quit ("Dinner from hazard").
18:38:04 <ehird`> oh well
18:38:09 <ehird`> you are all very helpful
18:41:31 <ehird`> hmm
19:19:22 <ehird`> which is more efficient:
19:19:26 <ehird`> optimizing after parsing
19:19:30 <ehird`> or parsing and optimizing at the same time
19:32:16 <bsmntbombdood> mmap?
19:32:21 <bsmntbombdood> you can mmap stdin?
19:35:44 <lament> um
19:35:52 <ehird`> bsmntbombdood: no
19:36:01 <lament> about the whole turing-completess thing
19:36:04 <ehird`> my interpreter takes program file name as first argument
19:36:06 <ehird`> ^a
19:36:08 <lament> if we allow "non-repetitive infinite initial conditions"
19:36:20 <bsmntbombdood> wha?
19:36:23 <lament> i'm pretty sure that makes SMETANA turing-complete as well
19:36:27 <lament> http://forum.wolframscience.com/showthread.php?s=&threadid=1472
19:37:30 <lament> it would be a very simple structure, it has a "head" and then a "tail" consisting of identical pieces of code with different numbers (trivially generated by any process)
19:37:40 <bsmntbombdood> how can you solve the halting problem with an infinite starting condition?
19:37:58 <lament> bsmntbombdood: "infinite starting condition" means an infinitely big program. You can do a lot of stuff with infinitely big programs.
19:38:07 <bsmntbombdood> how...
19:38:23 <ehird`> lament: you cannot solve the halting problem with an infinitely big program unless you hardcode EVERY SINGLE PROGRAM and if it halts or not
19:38:32 <ehird`> ... generating that program is equivilant to the halting problem of course
19:38:50 <lament> ehird`: right, but the point is that you can :)
19:38:58 <bsmntbombdood> oh that's lame
19:38:59 <lament> ehird`: and he does say such programs are uncomputable
19:39:13 <bsmntbombdood> no dice if the starting condition is uncomputable
19:39:20 <lament> right
19:39:30 <lament> ais's starting conditions in the proof are computable
19:39:33 <lament> but infinite
19:39:38 <lament> so this guy claims that that's enough
19:39:49 <lament> but if that's allowed, then SMETANA should be turing-complete
19:40:30 <lament> you can represent a brainfuck "memory cell" with ~20 lines of smetana
19:40:40 <lament> so with an infinite smetana program, you can represent the entire brainfuck memory tape
19:43:50 <ehird`> so anyone have comments on my parsing/optimizing order?
19:44:00 <ehird`> i would think that i should do parsing first, then optimize
19:44:05 <ehird`> because i have my nice tokens to play with
19:45:10 <ehird`> ok
19:45:18 <ehird`> i'll flip a coin for mmap vs getchar
19:45:18 <ehird`> :P
19:45:32 <bsmntbombdood> no me understando
19:45:39 <ehird`> bsmntbombdood: for what
19:45:49 <bsmntbombdood> then again i've never understood mmap
19:46:15 <ehird`> well
19:46:19 <ehird`> i shall mmap the code file
19:46:28 <ehird`> mmap just maps N bytes of a file to a pointer
19:46:33 <ehird`> and lazily reads them out on read
19:47:01 <ehird`> the major difference, i think, here, is that i need to do a stat on the file before mmaping
19:47:02 <ehird`> that's it
19:47:09 <ehird`> but of course getc is more complex
20:05:35 <bsmntbombdood> we s;; lmpe yjsy vpm[;rc od nryyrt
20:05:44 <bsmntbombdood> *we all know that complex is better
20:07:09 -!- sebbu2 has joined.
20:23:08 -!- sebbu has quit (Connection timed out).
20:23:09 -!- sebbu2 has changed nick to sebbu.
20:25:16 <ehird`> hmm
20:25:41 <ehird`> changing +-+ to +(1) should be done at optimizing stage right?
20:25:44 <ehird`> not parsing stage
20:25:50 <ehird`> (alternatively, just ++ to +(2))
20:33:11 <ehird`> anyone?
20:33:17 <ehird`> i'm thinking because i optimize away e.g. ><
20:33:17 <ehird`> so:
20:33:20 <ehird`> +><+
20:33:22 <ehird`> should be +(2)
20:33:33 <ehird`> but it'll be +(1)+(1) if i do ++->+(2) at parse-time
20:48:37 <ehird`> after working on this interp for hours
20:48:44 <ehird`> i'm compiling it for the First. Damn. Time.
20:48:47 <ehird`> here comes the bugfixes.
20:59:10 <ehird`> hm
21:00:00 <ehird`> hmm
21:00:12 <ehird`> all the brainfuck optimizations i can think of just remove redundant code
21:00:18 <ehird`> not really speed it up in any way
21:00:24 <ehird`> (apart from +++++++ -> + stuff)
21:00:31 <ehird`> are there any REAL optimizations you can do?
21:00:37 <ehird`> i currently optimize [-]...
21:00:43 <ehird`> (and [+] of course)
21:00:49 <ehird`> (and then [+--], etc)
21:22:17 <lament> [->>++<<] and everything else of that form can be quite trivially optimized
21:23:30 <lament> in fact, any loop which has no net effect on the memory pointer and contains no nested loops
21:24:39 <bsmntbombdood> ok i have a brainfuck text generating algorithm but it's pretty sucky
21:28:23 <oklopol> ehird`: didn't you say you have tons of brilliant brainfuck optimization techiniques?
21:28:28 <oklopol> asd typoes.
21:28:58 <oklopol> i've been watching south park for like 5 hours.
21:29:07 <oklopol> blah
21:29:10 <oklopol> soon
21:29:11 <oklopol> code
21:29:14 <oklopol> .
21:29:17 <oklopol> must
21:32:29 <bsmntbombdood> +++++[>+++++<-]>[>+>++>+++>++++>+++++<<<<<-]>>>.>+++++.+++++++..+++.<<----.<++++++++.>>>>-.<.+++.------.--------.<<<+.
21:32:39 <bsmntbombdood> that's "Hello, world!"
21:33:33 <bsmntbombdood> erm, no it's not
21:33:52 <ehird`> oklopol: yes, but compiler suited
21:33:56 <ehird`> oklopol: not for an interp
21:33:57 <bsmntbombdood> ++++++++++++++++++++++++[>+>++>+++>++++>+++++<<<<<-]>>>.>+++++.+++++++..+++.<<----.<++++++++.>>>>-.<.+++.------.--------.<<<+.
21:34:00 <bsmntbombdood> that is
21:35:16 <bsmntbombdood> whoa, that's better than the hello world on the wiki
21:38:42 <oklopol> ehird`: i see.
21:38:57 <oklopol> i don't see a difference, really
21:38:57 <ehird`> bsmntbombdood: is it?
21:39:09 <ehird`> oklopol: optimizations that take ages to apply = compiler territory
21:39:18 <bsmntbombdood> yeah
21:39:32 <oklopol> ehird`: i see
21:39:56 <ehird`> oklopol: after all, speed is the goal :)
21:41:18 <oklopol> true, but no one cares about a delay that only occurs once
21:41:32 <ehird`> think about mandelbrot.b runtime
21:41:41 <ehird`> if the parsing+optimizing takes a long time
21:41:47 <ehird`> then it'll rank, on the whole, badly
21:41:55 <oklopol> "rank"?
21:42:06 <ehird`> compared to other interps
21:42:08 <oklopol> on the top10 of bf-interpreters?
21:42:18 <oklopol> the official list
21:42:22 <ehird`> the official list?
21:43:13 <oklopol> what kind of optimizations do you have that would take long to apply, and what's a long time?
21:43:29 <ehird`> 1. everything non-trivial 2. everything that's slow
21:43:57 <oklopol> err... kay
21:44:06 <oklopol> now wanna answer at least one of those?
21:44:26 <ehird`> human nature is completely subjective
21:44:31 <ehird`> i cannot explain subjective things objectively
21:44:43 <oklopol> ...you can explain what you meant by a long time.
21:44:52 <ehird`> ok, let me elaborate
21:45:12 <ehird`> an optimization that takes a long time is an optimization where taking in account the time taken to apply it, it slows the interpretation process down on the whole
21:45:23 <ehird`> this of course does not matter for compilers - compiling time does not matter
21:45:54 <oklopol> ...okay, from now on, i'll just say not-orly everytime i don't feel like orlying what you say.
21:45:59 <oklopol> anyway, wanna answer the questions?
21:46:15 <ehird`> no
21:46:19 <oklopol> i see
21:48:40 <ehird`> what other big programs do people use to test their brainfuck interpreter?
21:48:46 <ehird`> right now i'm using mandelbrot.b and LostKng.b
21:59:39 <ehird`> anyone?
22:42:49 -!- RedDak has joined.
22:49:00 -!- ihope has joined.
22:53:17 <ehird`> "Leopard is so powerful, it makes Reddit's search function work right."
23:20:49 <ihope> I see we are not discussing parser-based esoteric programming languages. This must be rectified.
23:21:01 <ehird`> parser-based?
23:23:55 <ihope> Yes. Let me wrestle the logs and find it...
23:25:35 <ihope> Mmf. ircbrowse.com's search feature seems non-functional.
23:31:17 <ihope> Here we go! http://pastebin.ca/679421
23:31:58 <ehird`> ahh yes
23:32:24 <ehird`> show me a fibonacci generator and i'll be impressed
23:32:24 <ehird`> ;)
23:32:46 <ihope> Is unary okay? :-P
23:33:03 <ehird`> sure
23:33:14 <ehird`> then write an unary->something else converter :-)
23:33:22 <ehird`> "it's modular"
23:33:27 <ihope> I'll do the unary first.
23:33:37 <ihope> Or maybe decimal would actually be easier.
23:33:51 <ehird`> easiest is probably binary
23:34:00 <ihope> Oh, yes.
23:34:19 <ihope> Then I guess I need a parser that parses stuff like 101|1000 into stuff like 1000|1101.
23:34:26 <ehird`> http://en.wikipedia.org/wiki/L-system#Example_2:_Fibonacci_numbers
23:34:29 <ehird`> that will be the simplest
23:34:34 <ehird`> you can EASILY do that in your language
23:34:49 <ihope> Oh, of course.
23:34:56 <ehird`> it produces fibonacci numbers in unary
23:35:01 <ehird`> (B = A, of course)
23:35:13 <ehird`> so, wrap an unary->something else converter over that
23:35:13 <ehird`> and voila
23:36:01 * ihope nods
23:37:55 <ihope> Halfway done: http://pastebin.ca/755820
23:37:57 <ihope> Except not.
23:38:01 -!- oerjan has joined.
23:39:04 <ihope> I'll finish it later!
23:39:23 <ihope> Since I have to go eat and all.
23:40:00 <ehird`> bye :)
23:40:05 <ehird`> you havent been in here for ages
23:40:07 <ihope> (Also, I forgot the period at the end.)
23:40:09 <ihope> Bye.
23:41:16 <oerjan> <lament> i'm pretty sure that makes SMETANA turing-complete as well
23:41:57 <oerjan> indeed, i discussed that on the esoteric mailing list once upon a time
23:42:05 <oerjan> called it SMETANA+1
23:42:45 <oklopol> you'd think turing completeness would be an unambiguous consept
23:42:56 <ehird`> oklopol: it is
23:43:04 <ehird`> it's just hard to prove :-)
23:44:27 <ehird`> hmm
23:44:48 <ehird`> i wonder what the simplest pattern-matching-and-substitution language is that is TC
23:44:55 <ehird`> i.e. a mapping of state 1 to state 2
23:44:58 <oklopol> ehird`: i mean all these debates arguing over stuff like pointer-size-defined-when-program-starts (c) and initial-conditions-are-infinite-but-created-by-a-non-universal-machine (smetana, the 2,3 tm)
23:45:04 <ehird`> and the input to a program is transformed from state 1 to state 2 repeatedly
23:45:24 <oerjan> http://esoteric.sange.fi/archive/2001-q3
23:45:32 <oerjan> lament: ^^
23:45:48 <oklopol> the first one is trivially not turing complete, but i'm not sure about the second one.
23:45:58 <ehird`> i trust ais
23:45:59 <ehird`> :)
23:46:13 <oklopol> heh
23:46:38 <oerjan> later i extended it to something called Moldau, in http://esoteric.sange.fi/archive/2001-q4
23:46:51 <oklopol> ais is quite inactive, i don't have a strong opinion on him
23:46:52 <oklopol> *them
23:47:36 <oklopol> markus is sounds finnish.
23:47:46 <lament> oerjan: i'm talking about regular smetana.
23:47:55 <oklopol> *-is
23:48:08 <oerjan> lament: Smetana+1 can be considered simply a notation for your infinite initial pattern
23:50:43 <oklopol> i think i'm doZzZering off here ->
23:50:45 <oerjan> Moldau on the other hand was seriously overkill, as i mentioned already in my initial post
23:50:51 <oklopol> *dosing
23:50:55 <oklopol> ---->
23:51:15 <oerjan> with only Goto, it was essentially continuation-passing Prolog
23:51:27 <ehird`> anyone?
23:51:33 <ehird`> i wonder how minimal you can get it
23:51:40 <ehird`> obviously less minimal than tode (@oklopol ;))
23:53:51 <ehird`> :/
←2007-10-29 2007-10-30 2007-10-31→ ↑2007 ↑all