Alpounet changed the topic of #ocaml to: Discussions about the OCaml programming language | http://caml.inria.fr/ | 3.11.1 out now! Get yours from http://caml.inria.fr/ocaml/release.html
<julm> optiz0r: are you on a windows system?
<julm> could be \r perhaps
<optiz0r> julm: linux
<julm> oki
<optiz0r> I think it's because it doesn't get sent the output from the terminal unless I hit enter after my character, but then it's received two chars, t and \n. So I guess input_char or scanf("%c") is just taking the latter?
<optiz0r> At least, that eplains why taking %c%c and throwing away the second one seems to fix it
<julm> I don't think there is a buffering at the terminal level, though
<julm> I think it's scanf that is waiting for the \n
<optiz0r> That would make sense for what I've got at the moment. Even with input_char it would hang until I hit enter though
<optiz0r> oh well, it does seem to be working now, so I won't fuss over why too much :)
<optiz0r> I think my last remaining issue is that the scanf is waiting for input before my prompt is being printed, so the user has no idea what they're being prompted for. If I can fix that, then I can write up a report of what I've done and move onto the next piece of work :)
<julm> optiz0r: could we have a self-contained version of your code?
<optiz0r> to execute? a tarball of the directory ok?
<julm> for instance
<thelema> optiz0r: flush the output channel
munga has joined #ocaml
<optiz0r> thelema: "flush stdout"? I added that after the printterm and before the scanf, but no joy
<optiz0r> julm: http://temp.sihnon.net/reconbase.tar.gz `make; ./f test.f` should do it
<julm> thx
Pimm has joined #ocaml
tmaedaZ is now known as tmaeda0
<optiz0r> when you run it, it'll sit there waiting for the input. typing 0\n will do it. it should print char: 0, input port(0002)>, 0 : Nat. The intention is for the "input port(0002)>" line to appear before it waits for input.
<julm> hum it's %! to flush with printf no?
thrasibule has joined #ocaml
<optiz0r> swapping `flush stdout;` for `printf "%!";` doesn't fix
<julm> let pr = Format.print_string
<julm> hm
<julm> Format.print_flush
<julm> use that ^ perhaps
<thelema> how are you printing?
<thelema> julm: yes, if you're using Format, there's a different flush needed
<julm> Format.print_flush seems to do it
<optiz0r> julm: When I call Format.print_flush, I get a compiler warning: Warning F: this function application is partial, maybe some arguments are missing.
<julm> Format.print_flush ();
<optiz0r> ah, thanks :)
<optiz0r> I think you are my new personal heros :) thanks very much for your help
<julm> mouarf xD
ikaros has joined #ocaml
tmaeda0 is now known as tmaedaZ
ikaros has quit ["Leave the magic to Houdini"]
_unK has quit [Remote closed the connection]
munga has quit [Read error: 113 (No route to host)]
thrasibule_ has joined #ocaml
Pimm has quit [Read error: 110 (Connection timed out)]
thrasibule has quit [Read error: 104 (Connection reset by peer)]
maskd has quit ["leaving"]
rwmjones_lptp_ has quit [Read error: 101 (Network is unreachable)]
thrasibule has joined #ocaml
thrasibule_ has quit [Read error: 104 (Connection reset by peer)]
pad has joined #ocaml
thrasibule has quit [Read error: 60 (Operation timed out)]
thrasibule has joined #ocaml
kotrin has quit ["Leaving"]
yakischloba has quit ["Leaving."]
valross has joined #ocaml
thrasibule has quit [Read error: 60 (Operation timed out)]
yakischloba has joined #ocaml
caligula__ has joined #ocaml
caligula_ has quit [Read error: 60 (Operation timed out)]
yakischloba has quit ["Leaving."]
thrasibule has joined #ocaml
thrasibule has quit [Read error: 110 (Connection timed out)]
Alpounet has quit [Read error: 113 (No route to host)]
joewilliams has quit [Remote closed the connection]
pad has quit [Remote closed the connection]
ulfdoz has joined #ocaml
flux has joined #ocaml
ski_ has joined #ocaml
BigJ has quit [Remote closed the connection]
ulfdoz has quit [Read error: 60 (Operation timed out)]
ttamttam has joined #ocaml
BigJ has joined #ocaml
ttamttam has quit ["Leaving."]
Yoric has joined #ocaml
valross has quit [Read error: 110 (Connection timed out)]
morse has joined #ocaml
a|3x has quit [Read error: 104 (Connection reset by peer)]
Modius has quit [Read error: 110 (Connection timed out)]
valross has joined #ocaml
yakischloba has joined #ocaml
morse has quit [Read error: 60 (Operation timed out)]
yakischloba has quit ["Leaving."]
ygrek has joined #ocaml
ttamttam has joined #ocaml
Yoric has quit []
yakischloba has joined #ocaml
fx___ has joined #ocaml
fx___ has quit [farmer.freenode.net irc.freenode.net]
yakischloba has quit [farmer.freenode.net irc.freenode.net]
BigJ has quit [farmer.freenode.net irc.freenode.net]
ski_ has quit [farmer.freenode.net irc.freenode.net]
caligula__ has quit [farmer.freenode.net irc.freenode.net]
diml has quit [farmer.freenode.net irc.freenode.net]
gildor has quit [farmer.freenode.net irc.freenode.net]
M| has quit [farmer.freenode.net irc.freenode.net]
infoe_ has quit [farmer.freenode.net irc.freenode.net]
fremo_ has quit [farmer.freenode.net irc.freenode.net]
ozzloy has quit [farmer.freenode.net irc.freenode.net]
peper has quit [farmer.freenode.net irc.freenode.net]
ygrek has quit [farmer.freenode.net irc.freenode.net]
hyperboreean has quit [farmer.freenode.net irc.freenode.net]
prigaux_ has quit [farmer.freenode.net irc.freenode.net]
willb has quit [farmer.freenode.net irc.freenode.net]
smimram has quit [farmer.freenode.net irc.freenode.net]
WuJiang_ has quit [farmer.freenode.net irc.freenode.net]
Tianon has quit [farmer.freenode.net irc.freenode.net]
bzzbzz has quit [farmer.freenode.net irc.freenode.net]
fx___ has joined #ocaml
yakischloba has joined #ocaml
ygrek has joined #ocaml
BigJ has joined #ocaml
ski_ has joined #ocaml
caligula__ has joined #ocaml
hyperboreean has joined #ocaml
diml has joined #ocaml
gildor has joined #ocaml
infoe_ has joined #ocaml
fremo_ has joined #ocaml
ozzloy has joined #ocaml
peper has joined #ocaml
M| has joined #ocaml
WuJiang_ has joined #ocaml
Tianon has joined #ocaml
smimram has joined #ocaml
willb has joined #ocaml
bzzbzz has joined #ocaml
prigaux_ has joined #ocaml
Submarine has joined #ocaml
rwmjones_lptp has joined #ocaml
yakischloba has quit ["Leaving."]
rwmjones_lptp is now known as rwmjones
ygrek has quit [Remote closed the connection]
Yoric has joined #ocaml
_zack has joined #ocaml
_zack has quit ["Leaving."]
munga has joined #ocaml
_zack has joined #ocaml
ikaros has joined #ocaml
rwmjones has quit [Read error: 113 (No route to host)]
Submarine has quit ["Leaving"]
rwmjones_lptp has joined #ocaml
Pimm has joined #ocaml
Alpounet has joined #ocaml
rwmjones_lptp_ has joined #ocaml
rwmjones_lptp has quit [Network is unreachable]
Submarine has joined #ocaml
avsm has joined #ocaml
<rwmjones_lptp_> gildor, "flyspray" is totally unintuitive ... how do I open a new bug?
<mrvn> open a bug that it is impossible to open new bugs
<gildor> rwmjones_lptp_: you want to open a new bug against which product ?
<gildor> (FYI, this is "Add new task" once you are logged in and have switched to a specific project)
<gildor> (FYI2, ocaml-gettext and ocaml-fileutils has moved to forge.ocamlcore.org: https://forge.ocamlcore.org/projects/ocaml-gettext/ https://forge.ocamlcore.org/projects/ocaml-fileutils/)
<rwmjones_lptp_> gildor, gettext
<rwmjones_lptp_> I couldn't work out how to do either of those things
<rwmjones_lptp_> I logged in
<rwmjones_lptp_> which was a start
<gildor> I removed the BTS project ocaml-gettext from flyspray, every bugs had been transferred to forge.ocamlcore.org
<gildor> I need to leave a note on the webpages
<rwmjones_lptp_> ok ... so where shall I enter a bug?
<gildor> you cannot enter it into flyspray ;-)
<gildor> so enter it on forge.ocamlcore.org
<rwmjones_lptp_> usability ...
<gildor> rwmjones_lptp_: you cannot create the bug on the BTS of forge.ocamlcore.org ?
<rwmjones_lptp_> I have now
<gildor> ok great, will fix it
_andre has joined #ocaml
<rwmjones_lptp_> cheers
maskd has joined #ocaml
valross has quit [Read error: 104 (Connection reset by peer)]
_zack1 has joined #ocaml
Submarine has quit [Read error: 110 (Connection timed out)]
Submarine has joined #ocaml
rwmjones_lptp_ is now known as rwmjones
_zack has quit [Read error: 113 (No route to host)]
_unK has joined #ocaml
ikaros has quit [Remote closed the connection]
Submarine has quit [Read error: 60 (Operation timed out)]
rwmjones has quit [Read error: 101 (Network is unreachable)]
rwmjones_lptp has joined #ocaml
Submarine has joined #ocaml
munga has quit [Read error: 113 (No route to host)]
rwmjones_lptp_ has joined #ocaml
rwmjones_lptp has quit [Read error: 101 (Network is unreachable)]
derdon has joined #ocaml
thrasibule has joined #ocaml
<derdon> funny tutorial: there is written "note the code highlighted in red", but all the code is written in black :/
Submarine has quit ["Leaving"]
_zack1 has quit ["Leaving."]
<mrvn> and your question is?
<mrvn> .oO(It is a coloring book. Get out your red pen. :)
rwmjones_lptp__ has joined #ocaml
rwmjones_lptp_ has quit [Network is unreachable]
ksson has joined #ocaml
_unK has quit [Remote closed the connection]
rwmjones_lptp_ has joined #ocaml
<rwmjones_lptp_> derdon, originally that page was static HTML. When we converted it to a wiki I'm afraid we lost those annotations.
rwmjones_lptp_ is now known as rwmjones
<derdon> rwmjones: I see
<derdon> rwmjones: are you the maintainer of this wiki?
<rwmjones> it's maintained by the community
<derdon> rwmjones: I want to translate some chapters (or maybe all of them) into German anytime
_zack has joined #ocaml
<rwmjones> derdon, /msg me your email address & I'll send you an invite
<derdon> done
rwmjones_lptp__ has quit [Read error: 101 (Network is unreachable)]
thrasibule has quit [Read error: 110 (Connection timed out)]
ikaros has joined #ocaml
[df] has left #ocaml []
<Leonidas> derdon: wth are you doing here? ;)
<derdon> Leonidas: disturbing :)
<derdon> Leonidas: I hoped that here are many users asking and answering questions, but it's so quiet here
<derdon> I thaught I could learn while listening to others who need help
<Leonidas> derdon: obviously, you're stalking me in my functional lair - but I'm not gonna give you my lambda. My preciousssssss
<Leonidas> derdon: weren't you rather on the way to learn haskell?
<Leonidas> Oh, there you have your question...
<derdon> Leonidas: No, I think haskell is yet to difficult for me
<derdon> and OCaml is prettier :)
<Leonidas> I am writing an unittest and want to print the results if not equal. oUnit supports this but needs a function with the signature 'a -> string
<orbitz> typeclasses keep on puling me back to haskell
<Leonidas> But I have an int - how can I construct a function that dispatches on the type and thows everything not int away?
<orbitz> Leonidas: what do you mean?
<Leonidas> derdon: while I do like ocaml, the syntax is killing me.
<derdon> Leonidas: I *love* the syntax
* orbitz prefers ML-like stynax too
<Leonidas> orbitz: http://paste.pocoo.org/show/164631/ <- something like this.
<Camarade_Tux> I love ocaml's syntax too :-)
<Leonidas> derdon: I just hate the whole module/sig/with type thing.
<Leonidas> and I am pretty sure I haven't even seen all
<derdon> as yet, I hate nothing about OCaml
<Leonidas> While, OTOH, I just love guards and like that the language has an official macro system.
<Leonidas> orbitz: my problem is that printer is int -> string and not 'a -> string
<orbitz> Leonidas: do you have an actual testcase?
noj has quit ["leaving"]
noj has joined #ocaml
<det> I think type classes are the best thing ever
<det> ... but Ocaml as a whole is nicer than Haskell
<det> I also dislike Ocaml syntax
<det> I prefer Python's syntax to anything else
<mrvn> det: write a camlp4 module
<det> Can you override the lexer in camlp4 ?
<det> For python syntax, you have to insert indent/newline/dedent tokens
<mrvn> I bet
<orbitz> eeep I like Python a lot but the syntax is one thing that I am not a big fan of
<orbitz> if Python had layouts like Haskell I think i'd like ita lot more
<det> Why are layouts better?
<orbitz> Because there are places where the syntax is an impediment, a la lambda's
<mrvn> What I find bad in python is that if you change the level of indentation it is easy to mess it up. You realy need an editor that and indent/deindent a block at once.
<det> python allows you to ignore indentation inside ()
<det> a = (
<det> ...
<det> )
<orbitz> not with code...
<det> I guess, ya
<det> Can you give an example that would be hard to express in python syntax
<orbitz> I also wish more code evaluated to a value in Python too
<orbitz> so i could do a = if foo then bar else zoom
<det> oh, sure
<det> I agree with that
<orbitz> dont' get me wrong, Python is my most used langauge right now
<orbitz> And I do love code HAVING to be indented properly and consistently, I just think it's too constrictiev sometimes
<orbitz> and when you use a language a lot the littlet hings are what bother you the most
<det> I am trying to design a Python-like syntax for a ML now
<mrvn> let a =
<mrvn> .value value value
<orbitz> det: what would the benefit be?
<mrvn> in
<mrvn> .code code code
<det> orbitz, easier to read and code
<det> mrvn, this is in response to me ?
<mrvn> yep
<det> what is .value ?
<orbitz> det: Hard for em to relate tehre since i find ML a pleasure to read. but aren'tyou going to lose a lot tryign to cram ML code into Python-like syntax?
<mrvn> The differenze for ocaml would be rather minor though as most of the time you don't have a sequenze of expressions.
<det> mrvn, I dont understand your example
<mrvn> Only place you would rely on indentation would be where you have begin/end now.
<mrvn> det: . being the indentation token
<det> mrvn, can you give a simple example that runs in the repl
<mrvn> det: nope. you have to write the lexer/parser first
<orbitz> det: he is talking about your syntax idea
<det> I mean
<orbitz> he isn't talking about how it currently wroks
<det> that runs fine as ocaml syntax
<det> but would be hard to express with indentation syntax
<mrvn> another example:
<mrvn> f x
<mrvn> y
<mrvn> g x
<mrvn> y
<mrvn> Instead of f x y; g x y
<orbitz> det: personally, I just don't see what real value python-like sytnax would have for ML, if anything I think it woudl be a limitation
<det> ok
<det> 1) I prefer tupling to currying
<det> You could write:
<mrvn> det: then write let f (x,y,z) =
<det> f(x,
<det> erm
derdon has quit []
<orbitz> you don't need a new syntax for that...
<det> I realize that
<orbitz> det: and that also greatly changes teh semantics of the language
<det> but part of my point is that function application always begins with a paren
<det> so splitting among many lines is no problem
<mrvn> I would hate having to write let f x = function y -> function z -> x+y+z to get currying.
<det> I dont think currying has any real value
<mrvn> det: why should function application start with a paren?
<det> mrvn, consistency
<det> and also
<Leonidas> det: I do currying quite often in python
<det> it lets you use the empty token for more than just function application
<det> for example: f[1]
<det> f{2}
<det> etc
<orbitz> Leonidas: same here
<Leonidas> and I get enraged when some function does not support proper currying because of fuckups in the implementation
<det> I have many people talking to me, so it is difficult to express my ideas
<mrvn> det: the only reason for tupling would be for speed.
<orbitz> det: i write my python very functional, and currying becomes handy for me
<det> mrvn, I dont think tupling has any performance advantage
<det> orbitz, for partial application ?
<mrvn> det: then why do it? it only limits you
<orbitz> yes
<det> I dislike partial application, I prefer it to be explicit
<mrvn> you could use C like syntax with wildcards: fun y -> f x y z becomes f(x,_,z)
<orbitz> det: i found partial application confusing at first, but the type system solved teh mental issue, fo rme.
<mrvn> or f x _ z
<det> yes, there could be a syntax for general partial application of tuples
<det> which would be more powerful that currying
<orbitz> why would it be more powerful?
<det> mrvn, A better question is why currying ?
ikaros has quit ["Leave the magic to Houdini"]
<mrvn> det: because it is often usefull
<det> it leads to confusing error messages, and is inconsistent with to return values
<det> aka: functions accept many arguments by currying, but return many tupling
<det> and constructions must be tupled
<det> constructors*
tmaedaZ is now known as tmaeda0
<mrvn> det: well, constructors should be first class values like functions, including currying
<det> well
<det> they must be tupled for matching at least
<orbitz> i dont' find the error message too confusing... but I also liek to type annotate top level
<det> orbitz, more powerful because you can partial apply any argument or even many
<det> instead of just the first
<det> I would also rather write:
<det> def sum(f, list): List.fold_left(f, 0, list)
<det> than
<orbitz> det: meh i have a hard time agreeing that is necessiarly more powerful. it is different i will agree, but it's a balance
<det> I mean
<det> def sum(list): List.fold_left((+), 0, list)
<det> than
<det> let sum list = List.fold_left (+) 0
<det> or in Ocaml:
<orbitz> current syntax gives me a very concise consistent syntax for doing function calls and all that, and i can wrap it in another function trivially if I need more power so I have best of both worlds curerntly IMO
<mrvn> but the () are completly unneccessary
<det> my mind is scrambled
<orbitz> i don't really liek ()'s :)
<det> I keep making errors
<orbitz> I think that is one reason Scala is such shit to read. all teh ()'s
<orbitz> and teh type annotations ina ll the wrong places, but that's a diff problem
<det> let sum = List.fold_left (+) 0
<det> let sum list = List.fold_left (+) 0 list
<det> of those 2, I prefer the latter
<det> it is obvious
<mrvn> det: what if sum is polymorphic?
<det> then you must use the latter anyways :-)
<mrvn> like: print_int (sum f1 x); print_int (sum f2 x y z)
<orbitz> can you decouple type annotation from defintion in ocaml ilke in haskell?
<det> orbitz, sure
<orbitz> what's it look like?
<mrvn> The number of items in the tuple might be dependent on the arguments
<det> orbitz, you mean in my imaginary language ?
<orbitz> no, in Ocaml...
<det> you can not
<orbitz> ok
<orbitz> det: the latter tends to not be a problem for me as I am usually just looking at the type of a function when pokign around code, nto reading teh source
<det> mrvn, you can do the same tricks with nested tuples
<mrvn> det: that would be inconsistent
<det> it would not
<orbitz> example?
<det> not if , was a pair operator :-)
<mrvn> ah, you mean you only have tuples instead of n-tupls
<det> mrvn, I think you once posted a curried printf and I converted it to nested pairs
<det> yes
<mrvn> ineficient
<det> nope
<mrvn> yes
<det> if you have a monomorphizing compiler, you can flatten it
<mrvn> .oO(Yeah, lets design something bad into the language so the compiler can optimize it away again. :)
<det> that is not designing something bad
<det> it is designing something simple
<det> you could say the same about closures
<mrvn> det: In ocaml the args are flattened by default.
<det> yes
<det> that is the _real_ reason for currying in Ocaml, IMO
<det> not because it is expressibe
<det> expressive*
<det> but because it aids the compiler (tuples always allocate in Ocaml)
<mrvn> no, that is because you have n-tupels.
<det> n-tuples doesnt help in ocaml
<mrvn> they give you O(1) access to arguments.
<det> flattened pairs offer the same
<det> but are also consistent throughout the whole language
<det> and let you return multiple values with allocating
<det> without*
<mrvn> how do you eliminate the allocation?
<det> in my imaginary language ...
<det> tuples would be stack allocated, and passed by copying
<mrvn> and how do you flatten the return tuples?
<det> much like a struct in C
<det> if you want heap allocation, you enclose in {}
<mrvn> det: then you have n-tuples just like ocaml.
<det> yes, after monomorphization
<orbitz> wiat s you have to care about heap vs stack?
<mrvn> and with stack alocation you get problems with values escaping their scope.
<det> not before
<det> orbitz, try writing a competitive performance complex number library in Ocaml
<det> def swap(a, b): b, a
<det> something like that in Ocaml always causes an allocation
<mrvn> allocation is cheap
<thelema> det: you can't do that in ocaml, as it doesn't have references of the kind you want.
<det> you can certainly write:
<det> let swap (a, b) = b, a
<thelema> mrvn: is cheap compared to some things, not cheap compared to high-performance math code.
<mrvn> The only way you can remove the allocation is if you can proof that the input tuple can't be referenced by anything else so it can be reused.
<thelema> det: yes, but this won't change the original values passed in
<thelema> of course this is a good thing in the functional world.
<det> thelema, neither would my version
<mrvn> det: The expensive part in complex numbers is not the allocation but the boxing.
<thelema> but for really high performance, that's what you want to do.
<det> mrvn, yes, when I say allocation, I mean boxing
<det> thelema, a = swap(a)
<det> thelema, with my version, the compiler can generate fast code
<mrvn> det: then write an optimizer for ocaml that does a better job of unboxing floats, preferably across functions or even modules.
<det> it doesnt even have to be the same variable name
<det> mrvn, I dont beleive that is the right approach
<det> mrvn, I think monomorphization is the right approach
<det> combined with the programmer ability to choose stack/heap representation
<mrvn> det: that is a different problem
<thelema> and that's what you have to do in order to get what you want. And with ocaml's limited representation list, monomorphization is almost practical.
<thelema> stack/heap representation should be exposed? huh?
<mrvn> det: programmers will choose stack/heap representation wrong and all the iteresting cases you can't proof.
<det> so better to just make everything heap ?
<mrvn> det: that is the trivial and safe way.
<mrvn> Then you can optimize things onto the heap where you can proof it is safe.
<orbitz> isn't thsi what HLVM is tryign to solve?
<thelema> That's the only way to do it without 1) codesize explosion in the general case or 2) runtime generation of the needed code
<thelema> not runtime...
<thelema> whole-program generation of needed code
<det> Yes, whole program generation
<det> but
<det> that doesnt preclude incremental compilation
<mrvn> That is basically what c++ templates do and g++ needs a ton of memory and time to compile anything
<det> templates arent the same thing
<mrvn> The get compiler for every type they are used for. that is what you are talking about
<det> monomorphization just means you must have either source or some IR for polymorphic functions
<det> and generate them on demand
<det> I mean, during compilation, based on dependencies
<det> MLton is a special kind of whole-program compiler that must recompile the whole program every time
<mrvn> det: Where do you think monomorphization would make things faster?
<thelema> whenever a polymorphic function gets called, generate the specialized version of that function for the needed types and call that?
<det> thelema, pretty much, but only generate 1 function per set of types
<mrvn> det: you can't if you have incremental compilation
<det> you can
<mrvn> how should compiling B.ml know that A.ml already instanciated some type?
<det> implementation detail
<mrvn> det: no, impossible to do cleanly
<det> ok:
<det> a folder of object files
<det> named by hash
joewilliams has joined #ocaml
<mrvn> det: for each project? each directory?
<thelema> one could append the pre-compiled versions of a function to the .o file for the original function.
<det> mrvn, it's not a hard problem, that is just 1 way to do it
<mrvn> thelema: that would alter the timestamp and you don't have write permissions to /usr/lib/
<thelema> when you generate a specialized version of a function, put it where the original was.
<thelema> If you can't append, then you generate your own local copy.
<det> anyways
<mrvn> thelema: so we are back to generating lots of local copies
<det> mrvn, so ?
<mrvn> slow
<thelema> mrvn: in some cases. For code that's part of your project, not so much.
<det> why is it slow
<det> first compile maybe
<mrvn> det: because you do it over and over
<det> incremental compiles are fast
<thelema> For global libraries, you could pre-generate all combinations, so they're already ready.
<mrvn> for some value of "all" that includes commonly used types
<det> all combinations = infinite :-)
<det> I see no problem with slowing down the first compilation of a project a small bit
<det> and it could even be avoided with some work
<thelema> yes, using a small value of "all"
<mrvn> det: then you combine this with inlining and you get an exponential increase in time and space
<mrvn> c++ shows how bad this can go
<det> mrvn, in theory you get the same from HM
<det> MLton never had this issue
<mrvn> thelema: I actualy think the "all" could be rather small. You only need to cover the primitive types and then maybe tuples, list and arrays of them. Anything more complex I doubt monomorphizing gains you anything. just ruins the code cache.
<det> It has other issues, but not code-size blowup
<thelema> mrvn: there's room for this kind of technique just like there's room for both native and bytecode ocaml
<mrvn> thelema: not if it actualy makes things slower
<det> mrvn, I dont think it would
<thelema> this is ok if it's off by default until it's tuned to commonly make things faster
<mrvn> det: you still haven't given ann example where it would help
<det> I think it would simplify implementation and make things faster in general
<mrvn> det: simplify? never
<thelema> mrvn: the gitj people wrote a nice article about how they couldn't reach the performance of C-git in Java, partly because of boxing.
<det> mrvn, says the guys who suggested improving Ocaml's cross module float unboxing
<mrvn> thelema: boxing is expensive
<mrvn> But what will monomorphizing a function for float give you if float remains boxed?
<det> it would eliminate the need to box it!
<det> it eliminates the need for universal representation
<mrvn> det: different (though near) problem.
<det> I dont think so
<det> I think they are directly related
<mrvn> Unboxing will gain you something, monomorphizing I think will be useless unless you solved unboxing first
<det> monomorphization allows you to unbox
<thelema> mrvn: how to solve boxing while keeping polymorphism?
<mrvn> det: only extends it to polymorphic functions
<thelema> mrvn: true. Monomorphic functions also need unboxing analysis, but ocaml has that, no?
<mrvn> thelema: no
<mrvn> why do you think floats are so slow?
<thelema> because they have to be boxed in order to be passed as arguments most places
<mrvn> thelema: see
<det> because of universal representation, because of polymorphic functions
<det> it is all related
<mrvn> det: you would also still need the universal representation
<det> mrvn, why ?
<mrvn> det: for the GC for one thing
<mrvn> for cases where monomorphizing gets too expensive for another
<det> with monomorphic functions, GC is easy
<mrvn> monomorphic functions don't eliminate allocations
<mrvn> And the GC must also be able to go through the stack and registers
<det> there are a couple ways to solve that
<mrvn> Say you have "let f x y = x +. y" then the compile should generate:
<mrvn> f: put b info fp0, put b into fp1, call f_unboxed, box fp0 again
<det> that should always be inlined reguardless :x
<mrvn> f_unboxed: add fp0,fp1
<mrvn> det: in this trivial case sure. but you get the principle.
<det> that function can never allocate anyways
<mrvn> det: x +. y allocates a float.
<det> assuming boxing, yes
<det> but i say that boxes dont need to be boxed
<det> I mean floats
<mrvn> they need to be when in memory.
<det> why ?
<det> GC can be solved without boxing
<mrvn> so the GC can differentiate them from pointers.
<mrvn> You need some bit somewhere that says "this word is not a pointer"
<det> You can use the return address of the function to see what is on the stack and registers at that point
<det> you need no such thing
<det> you need a way to see what is in registers and stack
<det> universal representation is 1 way of doing that
<det> if your program is monomorphized, you can use the return address of the function
<mrvn> det: registers are easy, FP registers are always floats. :)
<det> or push something on the stack for each stack frame
<mrvn> And on stack you still need to know which word is a pointer
<det> yes, but like I say, you can figure that out in other ways
<det> without ever boxing
<mrvn> det: if you put a bitfield onto the stack that marks pointers I still call that boxing.
ski_ has quit ["Lost terminal"]
<mrvn> I don't mean that you neccessarily need to allocate on the heap.
<det> what if you use the return address
<det> btw, I dont call that boxing
<det> because it isnt boxed
<det> either of them
<mrvn> det: you mean the return address of the next stackframe to get the address of the function and then some static bitfield for that function describing the stackframe?
<mrvn> I would think that is way to expensive
<det> I mean:
<det> every function knows the address it must return to
<det> I mean
<det> it knows the address after is is called, because that address is on the top of the stack or in a register or w/e (dependent on arch)
<mrvn> sure
<det> if your program is monomorphic, then from this address you can always find out the state of the function that called you
<mrvn> And the GC can know that the function that includes the return address X will have a float, and int and a pointer on the stack.
<det> yes
<det> there are a couple of ways to lookup the types from this address
<mrvn> Which is expensive as you need to first find the function containing the address (a function can have many) and then lookup the info for that function.
<det> im not done
<mrvn> Putting an extra word on the stack costs a little ram but you have all the info directly.
<det> right, that is probably the best solution
<det> ... but
<det> you can do it with no overhead
<mrvn> Lets call that "tagged"
<det> let's say that on x86
<mrvn> det: you always have overhead. you can just choose between time and space
<det> ok, I wll admit that
<det> instead of using "call blah"
ski_ has joined #ocaml
<det> you do this
<det> sec
<Leonidas> uhm, coming back to my original question from 2h ago: how can I write this printer function that handles 'a -> string ?
<det> normal code for x86:
<det> call someFunction
<det> ... rest of code
<det> another scheme:
<mrvn> Leonidas: Like Printf.printf with a format string or functional with CPS
<det> push return_point on stack
<det> jmp someFunction
<det> jmp GC_blahpoint
<det> return_point:
<det> ... rest of code
<mrvn> det: with GC_blahpoint being the code that registers the pointers on the stack in case the GC runs?
<det> using this scheme, the function knows that it can GC by jumping to the code at 1 word less than the return point
<det> mrvn, right
<mrvn> det: nice idea. That would "box" or "tag" the values through generating code.
<det> its not my idea
<det> it is from a paper
<mrvn> det: skipp the "jmp" though. just put the address there.
<det> only problem could be if call/ret is faster than jmp
<det> which I dont know if that is the case
<thelema> Leonidas: the best that's been done for a 'a printer is: http://github.com/thelema/AAA-batteries/blob/master/src/batStd.ml#L95
<det> MLton is 100% jmp for example
<mrvn> det: call does something else that jmp on many cpus.
<det> call is simply:
<det> push next address on stack
<det> jmp
<mrvn> det: totally cpu dependent
<det> but there might be some kind of optimization in the silicon, I dont know
<mrvn> det: Alpha for example doesn't have "call" at all.
<det> I know ARM has something like call
<det> and x86/x86_64,arm are the architectures that matter most right now :-)
<mrvn> alpha only has "jmp where,when,return-addr" iirc
<det> when?
<mrvn> det: condition code in a register
<det> oh
<mrvn> jmp r0,r1,r29
<mrvn> if "r1" is true then it jumps to r0 and puts the return address into r29
<det> I think ARM let's you put conditions on all instructions, not just jumps
<Leonidas> mrvn: Hmm, I'll probably do just that.
<det> mrvn, what is r29 used for ?
<mrvn> det: return address
<mrvn> might not be r29 but there was some default register for the C ABI.
<det> "return address" means "next instruction" ?
<mrvn> det: yep
<det> oh, ok
<Leonidas> thelema: the more I use OCaml, the more I see how useful AAA is. But I'll go with Printf first.
<det> can you jump without the third operand ?
<thelema> Leonidas: as you will.
<mrvn> det: for your code every function would end with "add #8,r29; jmp r29"
* Leonidas wants AAA included into OCaml in the future, actually :)
<det> mrvn, I am thinking about loops
<mrvn> det: i.e. skip the GC_hunk and return
<thelema> Leonidas: it won't happen even if 99% of ocaml users use it.
<mrvn> thelema: not even for the modules that just extends the stdlib?
<thelema> mrvn: yes
<mrvn> thelema: is upstream so dead set to extending the stdlib?
<mrvn> s/to/against/
<thelema> Yes, because it means that INRIA maintains the code, as opposed to the community.
<Leonidas> ah, thats annoying.
<mrvn> Then I think at some point the community should just fork
<thelema> We're nowhere near ready.
<Leonidas> maybe that will happen someday. AAA paves the way by making ocaml more useful.
<thelema> yes, the community may finally step up to the plate.
<mrvn> Since we are on the topic of boxed floats. I was thinking that for a fractal programm instead of passing complex floats (26 + temp vars) around it might be better to create one float array with all the floats combined and work solely on that.
<thelema> mrvn: = manual memory managementy
<mrvn> Sure. but I know how many floats I need and it is the inner loop
<thelema> This would work, but why write in ocaml in this case?
<thelema> brb, lunch
<mrvn> thelema: I have a 3x3 grid of points and 4 points in the middle for control purposes. I do a few iterations on the grid and then check if interpolating is close enough to the control points. If not I subdivide the grid and repeat for the 4 subgrids.
<Leonidas> mrvn: but when I use Printf.sprintf I still can't use the function, because it expects int -> string and not 'a -> string.
rwmjones has quit [Read error: 60 (Operation timed out)]
<Leonidas> Apparently, Printf is typesafe and Leonidas-proof :)
<det> Leonidas, why do you need a function that is 'a -> string
ksson has quit ["leaving"]
<mrvn> Leonidas: if you give sprintf an "%d" format then obviously it wants an int
<det> If you want such a function, I can provide it to you, but I am afraid it wont be very useful
<mrvn> Leonidas: a true "'a -> string" can only work with the memory representation of 'a. Not the real type.
<det> let f x = "Im a string!"
<mrvn> det: that does verry little with the representation. :)
<det> I am trying to figure out why he needs such a function
<Leonidas> det: because I want my test case to actually print the variable. And the type signature of the printer function I have to hook in is 'a -> string
<Leonidas> Maybe I just rip off part of the AAA code :)
<det> Leonidas, where are you hooking this in ?
<mrvn> Leonidas: so the printer is ('a -> string) -> 'a -> string?
<Leonidas> det: ounit
<det> Leonidas, what call
<Leonidas> mrvn: no, just 'a -> string
<Leonidas> det: assert_equal
<mrvn> Leonidas: you need to use a different one for each 'a you use
<det> Leonidas, what mrvn said
<Leonidas> mrvn: but I just need one for int
<mrvn> If you use it with ints then you pass an int_printer. If you use it woith floats then a float_printer
<mrvn> Leonidas: so write an "int -> string" and pass it along.
<det> if you dont know the type at the point in the code where you are using it, then you need to make that function accept the printer as an argument
<mrvn> e.g. (Printf.sprintf "%d")
<mrvn> or what det said
<Leonidas> mrvn: http://paste.pocoo.org/show/164667/ so I have this.
<det> Leonidas, what is the problem
<mrvn> looks OK to me too
<Leonidas> Error: This expression has type int -> string
<Leonidas> but an expression was expected of type ('a -> string) option
<det> why are you using and ?
<mrvn> So you are missing a "Some"
<mrvn> The error is the "option" part, not the int vs 'a.
<det> also, why not this: http://paste.pocoo.org/show/164668/
<Leonidas> Error: This expression has type int -> string option
<Leonidas> but an expression was expected of type ('a -> string) option
<Leonidas> After wrapping in a "Some"
<orbitz> use ()
<mrvn> int -> string option != (int -> string) option
<Leonidas> uh. Where does the option type come from? Because it is an optional argument?
<mrvn> yep
<orbitz> are you saking the meaning of option or where it is defiend? (Pervasives)
<det> Leonidas, Some is a constructor for an option
ikaros has joined #ocaml
<det> Leonidas, what does your code look like now
<det> and this works ?
<Leonidas> Dumped the Printf, because it wasn't doing anything useful
<Leonidas> det: no, because the type still misses the ( )
<orbitz> Leonidas: it watns Some string_of_int
<det> yes
<det> you are passing a function that returns an option
<det> rather than an option of a function
<det> and why are you using "and" ?
<Leonidas> ohhhhhh! Now I get it.
<orbitz> det: is there soemthing wrong with and?
<Leonidas> det: wanted to try it. Is anything wrong with it?
<Leonidas> and, well, it works now
rwmjones_lptp has joined #ocaml
rwmjones_lptp is now known as rwmjones
<det> and is confusing
<det> and lead to errors if you are shadowing a variable later on
<orbitz> why is it confusing?
<orbitz> hrm
* orbitz has alwaysf ound and quite fine
<det> because you expect the value to be used recursively
<orbitz> less typing too
<orbitz> who is 'you?
<det> the reader
<orbitz> I don't expect that since i read what 'and' means in the documetnation
<det> also, it is harder to read because things dont line up
<det> and harder to refactor
<orbitz> det: Leonidas formated hsi code poroly for and. i just put 'and' below teh let, code lines up perfectly fine
<det> and is for mutually recursive values and functions
<Leonidas> ah, I see
<mrvn> I also don't like and without rec
<orbitz> I use and for when i don't need what i'm binding to rely on anything else in that let
<det> it makes it harder to edit
<det> for example
<det> now you want to delete the first line of the function
<det> since that printer is no longer needed
<det> you must add let to the second line
<orbitz> I have rarely run into this being a problem. I delete the first line and change teh 'and' to a let or i get a compiler error.
<orbitz> i put 'and' right belowt he 'let' so it is the begining of the line
<det> and possible change in the and
<det> instead of just deleting the first line
<orbitz> det: arguments for subtracting 20 milliseconds from an action i take once in a while dont' really have much weight with me
<det> change in to and*
<orbitz> why change in to and?
<det> because your convention is apprently for the first let to be and
<orbitz> yep
<det> and subsequent lets to omit the let
<orbitz> what?
<det> you have:
<Leonidas> now the next question. Why doesn't oUnit actually use the printer function to, well... print the values?
<det> let a = 1 and
<det> erm
<det> he broke my lines
<det> ill paste
yakischloba has joined #ocaml
<mrvn> det: bah
<Leonidas> sorry.
<orbitz> det: this is nwo how i describe dis tructur emy code
<mrvn> det: do you write if a = b then
<orbitz> see my codepad
<mrvn> 17 else
<mrvn> 23
<mrvn> ?
<det> mrvn, that is _not_ how I write code
<det> that is how Leonidas is formatting his code
<mrvn> det: then why put the "and" on the first line?
<orbitz> I know, and i have stated that how Leonidas does it is not hwo i do it
<det> orbitz, how do you do it
* Leonidas is going it wrong
<orbitz> "11:48 < orbitz> det: Leonidas formated hsi code poroly for and."
<orbitz> det: i just showed you, read up
<orbitz> det: i postd a codepad link
<orbitz> det: conversatiosn help when you pay attention to what other peopel say too
<det> orbitz, you just pasted a link
<det> no description
<det> and not addressed to anyone
<orbitz> right after it i said: 11:53 < orbitz> det: this is nwo how i describe dis tructur emy code
<orbitz> ack
<det> orbitz, you see the problem now? :-)
<orbitz> that 11:53 < orbitz> see my codepad
derdon has joined #ocaml
<orbitz> det: I'm sorry, you and i were having a discussion abotu code formatting, i was under the impression you'd see the causal link there, my bad.
<orbitz> det: anyways, that is how i structure my 'and'
<det> orbitz, lets not meta argue :-)
<det> orbitz, that is better, but the first line is still special
<orbitz> i realize this, i addressed this earlier in the covnersation too
<det> I guess you could do that :p
<orbitz> that's oogly
<det> I agree
<det> I prefer let in for all values
<det> or even better:
<orbitz> det: it really takes no more than a few keystrokes to make 'and' into 'let'. I have no problem with this. and it results ina compiler error if you fail to
<det> I prefer the latter the most
<orbitz> I pefer teh former, except for that damned ()
<det> well, the () is just there to make it a function
_unK has joined #ocaml
<orbitz> i know why it'st here, it's still ugly
<det> there, in reverse order of preference
<det> first one looks much uglier than the second to me
<orbitz> too much typng on the second one
<det> then we agree, the third one wins for typing :-)
<orbitz> sure
<det> orbitz, you'd probably like SML syntax
<orbitz> det: it's okay.
ulfdoz has joined #ocaml
ttamttam has quit ["Leaving."]
joewilliams has quit [Remote closed the connection]
Yoric has quit []
Submarine has joined #ocaml
joewilliams has joined #ocaml
avsm has quit [Read error: 60 (Operation timed out)]
yakischloba1 has joined #ocaml
_zack has quit ["Leaving."]
yakischloba2 has joined #ocaml
yakischloba has quit [Read error: 104 (Connection reset by peer)]
r0bby has quit [Operation timed out]
r0bby has joined #ocaml
rwmjones has quit [Success]
tmaeda0 is now known as tmaedaZ
r0bby has quit [Read error: 104 (Connection reset by peer)]
r0bby_ has joined #ocaml
rwmjones has joined #ocaml
ksson has joined #ocaml
r0bby_ has quit [Read error: 104 (Connection reset by peer)]
r0bby has joined #ocaml
ttamttam has joined #ocaml
yakischloba1 has quit [Read error: 110 (Connection timed out)]
r0bby has quit [Read error: 54 (Connection reset by peer)]
r0bby has joined #ocaml
r0bby has quit [Connection reset by peer]
r0bby has joined #ocaml
r0bby has quit [Read error: 104 (Connection reset by peer)]
r0bby has joined #ocaml
r0bby has quit [Read error: 104 (Connection reset by peer)]
r0bby_ has joined #ocaml
Yoric has joined #ocaml
r0bby_ has quit [Read error: 54 (Connection reset by peer)]
r0bby has joined #ocaml
itewsh has joined #ocaml
r0bby_ has joined #ocaml
r0bby has quit [Connection reset by peer]
yakischloba2 is now known as yakischloba
r0bby_ has quit [Read error: 54 (Connection reset by peer)]
r0bby has joined #ocaml
Amorphous has quit [Read error: 104 (Connection reset by peer)]
r0bby has quit [Read error: 104 (Connection reset by peer)]
r0bby_ has joined #ocaml
kotrin has joined #ocaml
ikaros has quit ["Leave the magic to Houdini"]
r0bby_ has quit [Read error: 54 (Connection reset by peer)]
r0bby has joined #ocaml
r0bby has quit [Read error: 104 (Connection reset by peer)]
r0bby has joined #ocaml
smimou_ has joined #ocaml
smimram has quit [Read error: 110 (Connection timed out)]
yakischloba1 has joined #ocaml
yakischloba has quit [Read error: 104 (Connection reset by peer)]
Amorphous has joined #ocaml
r0bby has quit [Connection reset by peer]
r0bby has joined #ocaml
r0bby has quit [Read error: 104 (Connection reset by peer)]
r0bby has joined #ocaml
ulfdoz has quit [Remote closed the connection]
ulfdoz has joined #ocaml
r0bby has quit [Read error: 54 (Connection reset by peer)]
r0bby has joined #ocaml
r0bby has quit [Connection reset by peer]
r0bby has joined #ocaml
yakischloba1 is now known as yakischloba
r0bby has quit [Read error: 104 (Connection reset by peer)]
r0bby has joined #ocaml
r0bby has quit [Read error: 104 (Connection reset by peer)]
r0bby has joined #ocaml
pad has joined #ocaml
avsm has joined #ocaml
r0bby has quit [Read error: 104 (Connection reset by peer)]
r0bby has joined #ocaml
r0bby has quit [Read error: 54 (Connection reset by peer)]
r0bby has joined #ocaml
Yoric has quit []
r0bby has quit [Read error: 104 (Connection reset by peer)]
r0bby has joined #ocaml
r0bby has quit [Read error: 104 (Connection reset by peer)]
ikaros has joined #ocaml
_andre has quit ["Lost terminal"]
seanmcl has joined #ocaml
maskd- has joined #ocaml
Yoric has joined #ocaml
derdon has quit []
r0bby has joined #ocaml
munga has joined #ocaml
r0bby has quit [Client Quit]
r0bby has joined #ocaml
r0bby has quit [Read error: 54 (Connection reset by peer)]
r0bby_ has joined #ocaml
r0bby has joined #ocaml
r0bby has quit [Client Quit]
maskd has quit [Read error: 110 (Connection timed out)]
r0bby_ has quit [Client Quit]
jcaose has joined #ocaml
robocop has joined #ocaml
<robocop> hello
<orbitz> hi
<robocop> I've got a stupid errir with a function
<robocop> Error: Unbound value ycolor
<robocop> do you see why ?
<orbitz> line 3 is wrong
<robocop> why ?
<orbitz> what does let foo = 5 in foo in let bar = 2 in bar;; mean?
<robocop> ho
<robocop> yes
<robocop> I'me tired
<robocop> thanks :p
<jonafan> who knows lablgtk?
<thelema> jonafan: me, a tiny bit. Some code: http://github.com/thelema/coml
<jonafan> i'm working through a tutorial
<jonafan> there's one example for the file selection dialog, which i don't like
<jonafan> i thought i'd tweak it and upgrade it to a file chooser dialog, but i can't figure out how to add cancel and open buttons
<jonafan> let me try something
r0bby has joined #ocaml
<jonafan> i see add_select_button_stock which seems to add buttons in the right place
<thelema> ok.
<jonafan> but the second argument is a mystery to me
ksson has quit [Read error: 60 (Operation timed out)]
Submarine has quit ["Leaving"]
<jonafan> i tried putting `DELETE_EVENT since b is apparently [> `DELETE_EVENT ], but that doesn't even seem to do anything
<thelema> hmm, going back to the source code, it's put into the list of signals that can be accepted, I think.
r0bby has quit [Read error: 54 (Connection reset by peer)]
<thelema> the table of final buttons?
r0bby has joined #ocaml
<thelema> when it goes to decode the response, it uses this table to ...
<thelema> hmm
Yoric has quit []
r0bby has quit [Client Quit]
yakischloba has quit ["Leaving."]
<thelema> There's a bunch of internals in gWindow.ml you (and I) should learn to do this.
<jonafan> ohh
<jonafan> okay ... i don't know what to make of this
r0bby has joined #ocaml
<jonafan> i see the table i guess
r0bby has quit [Read error: 54 (Connection reset by peer)]
rwmjones has quit [Read error: 60 (Operation timed out)]
robocop has quit [Remote closed the connection]
rwmjones has joined #ocaml
Submarine has joined #ocaml
ulfdoz has quit [Read error: 110 (Connection timed out)]
Submarine has quit [Client Quit]
yakischloba has joined #ocaml
jcaose has quit ["Leaving"]
valross has joined #ocaml
Yoric has joined #ocaml
ttamttam has quit ["Leaving."]
r0bby has joined #ocaml
ikaros has quit ["Leave the magic to Houdini"]
Yoric has quit []
yakischloba has quit [Read error: 110 (Connection timed out)]
r0bby has quit [Read error: 104 (Connection reset by peer)]
r0bby has joined #ocaml
naufraghi_ has joined #ocaml
CcSsNET has joined #ocaml
r0bby has quit [Client Quit]
yakischloba has joined #ocaml
j4ck has joined #ocaml
<j4ck> Bonk
seanmcl has quit [farmer.freenode.net irc.freenode.net]
avsm has quit [farmer.freenode.net irc.freenode.net]
_unK has quit [farmer.freenode.net irc.freenode.net]
noj has quit [farmer.freenode.net irc.freenode.net]
det has quit [farmer.freenode.net irc.freenode.net]
TaXules has quit [farmer.freenode.net irc.freenode.net]
lutter has quit [farmer.freenode.net irc.freenode.net]
lanaer has quit [farmer.freenode.net irc.freenode.net]
CcSsNET has quit [farmer.freenode.net irc.freenode.net]
naufraghi_ has quit [farmer.freenode.net irc.freenode.net]
maskd- has quit [farmer.freenode.net irc.freenode.net]
Amorphous has quit [farmer.freenode.net irc.freenode.net]
Pimm has quit [farmer.freenode.net irc.freenode.net]
demitar has quit [farmer.freenode.net irc.freenode.net]
Asmadeus has quit [farmer.freenode.net irc.freenode.net]
jimmyb2187 has quit [farmer.freenode.net irc.freenode.net]
jonafan has quit [farmer.freenode.net irc.freenode.net]
schme has quit [farmer.freenode.net irc.freenode.net]
fabjan has quit [farmer.freenode.net irc.freenode.net]
thelema has quit [farmer.freenode.net irc.freenode.net]
tmaedaZ has quit [farmer.freenode.net irc.freenode.net]
Mr_Awesome has quit [farmer.freenode.net irc.freenode.net]
CcSsNET has joined #ocaml
naufraghi_ has joined #ocaml
maskd- has joined #ocaml
Amorphous has joined #ocaml
Pimm has joined #ocaml
demitar has joined #ocaml
Asmadeus has joined #ocaml
jimmyb2187 has joined #ocaml
jonafan has joined #ocaml
schme has joined #ocaml
fabjan has joined #ocaml
thelema has joined #ocaml
tmaedaZ has joined #ocaml
Mr_Awesome has joined #ocaml
seanmcl has joined #ocaml
avsm has joined #ocaml
_unK has joined #ocaml
noj has joined #ocaml
det has joined #ocaml
TaXules has joined #ocaml
lutter has joined #ocaml
lanaer has joined #ocaml
itewsh has quit ["There are only 10 kinds of people: those who understand binary and those who don't"]
<j4ck> bonk
j4ck has quit [Read error: 104 (Connection reset by peer)]
munga has quit [Read error: 113 (No route to host)]
_unK has quit [Remote closed the connection]