jemc changed the topic of #ponylang to: Welcome! Please check out our Code of Conduct => https://github.com/ponylang/ponyc/blob/master/CODE_OF_CONDUCT.md | Public IRC logs are available => http://irclog.whitequark.org/ponylang | Please consider participating in our mailing lists => https://pony.groups.io/g/pony
martinium has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<SeanTAllen> mahmudov: yes, we implemented our own messaging over tcp for wallaroo.
<SeanTAllen> there's a lot we've learned from it that would go into a pony version of distributed pony
<lisael> Hi!
<mahmudov> it is version of distributed ?
<lisael> this poped on HN yesterday, it's really interesting, it should be somewhere in Pony doc : http://habitatchronicles.com/2017/05/what-are-capabilities
<mahmudov> seantallen can you link me an example code.
<SeanTAllen> @mahmudov no. and that fork is no longer in use. when we were developing early versions of wallaroo, we were using our own pony fork as it allowed us to move quickly. we then used PRs and the RFC process to get those improvements into mainline Pony.
<SeanTAllen> mahmudov: example code of what?
<mahmudov> hm.
<mahmudov> distributed implementation of pony
<mahmudov> i cant find
<SeanTAllen> there is no distributed implementation of pony.
<SeanTAllen> i dont understand
<SeanTAllen> Wallaroo is written in Pony
<SeanTAllen> and if you use the Wallaroo Python, Pony or Go APIs, it allows for you to created distributed streaming data applications without having to code message passing or resilience
<SeanTAllen> but its not distributed pony
<mahmudov> i mean clustering, ah ok.
<mahmudov> i assumed clustering is that...
<SeanTAllen> that said, we learned a ton about edge cases, implementation details etc working on Wallaroo that should be really valuable when implementing a distributed verison of Pony.
<SeanTAllen> Nope, that clustering is how you can cluster Wallaroo binaries together.
<SeanTAllen> If you were using the Pony version of Wallaroo, it would allow you to hook up multiple copies of a Wallaroo binary into a cluster of processes.
<mahmudov> clear,i see.
<SeanTAllen> Everything we had to do for that would have to be done for distributed Pony
<SeanTAllen> and a lot of the details we've learned about how to migrate actors and state from one worker to another, how to update routing information etc will be important to distributed Pony.
<SeanTAllen> I suspect the implementation distributed Pony will follow the same lifecycle as Wallaroo did.
<SeanTAllen> The hard problems that Wallaroo had to solve are the same hard problems that distributed Pony will have to solve.
<mahmudov> Designating what to do with the next message ?
<SeanTAllen> Particularly around dynamically changing cluster size while an application is running. That's really tricky.
<mahmudov> routing information is designating .
<mahmudov> isnt it
<SeanTAllen> Distribution is relatively easy and straightforward if the cluster size is static. It gets really hard when you allow a cluster to add and remove members while its running.
<SeanTAllen> Message routing if you allow actor migration is also very difficult.
<mahmudov> hm did you read this:
<SeanTAllen> Early version of distributed Pony will, I suspect, be limited to static cluster sizes (ie fixed at startup) and not allow actor migration.
<SeanTAllen> But that's a nice start.
<SeanTAllen> mahmudov: yes, ive read it. its *very* erlang specific
<SeanTAllen> and attributes to the actor model many characteristics that are implementation specific details of erlang and dont apply to the actor model in general
<SeanTAllen> that said, its a great 10 minute into to Erlang
<mahmudov> yeb.it seems.i thought why pony not mention
<mahmudov> didnt mention*
<SeanTAllen> "Let it crash" is definitely Erlang specific.
<SeanTAllen> Although most things that are Erlang specific can be said about Akka as well, as it tries quite hard to be very Erlang right, sometimes to its benefit, sometimes to its detriment
<mahmudov> process isolating?
<mahmudov> it is also in pony ?
<SeanTAllen> Pony has no concept of a process.
<SeanTAllen> Erlang processes are implemented as green threads.
<mahmudov> he said that cuz a supervior can replace
<mahmudov> when it crashes
<mahmudov> self-healing !.
<SeanTAllen> Pony has no green threads. Pony by default will have 1 native scheduler thread per CPU and will schedule actors to run using those threads using a work stealing algo.
<mahmudov> is it true if how ?
<mahmudov> self-healing is in actor-modelling consept?
<SeanTAllen> No.
<SeanTAllen> Supervision trees are not part of the actor model of computation, they are a part of Erlang's implementation that could be implemented in other actor model implementations
<SeanTAllen> But the actor model itself doesnt call for supervision trees, nor does it specify a specific resilience or recovery model.
<mahmudov> i suspect,supervisor also acts like a main actor?
<mahmudov> to organise the actors ?
<mahmudov> if any crash so pass message other or recovery other instant?
<SeanTAllen> mahmudov: not really.
<SeanTAllen> its better to not think of "a supervisor" but rather a "supervision tree"
<SeanTAllen> where anything higher up the tree is responsible for monitoring its immediate descendents and restarting them if needed
<SeanTAllen> and supervisors arent responsible for message passing
<SeanTAllen> they are responsible for "are the actors that i am supervising still alive?"
<SeanTAllen> and if they aren't, for restarting them
<mahmudov> ok, doesnt seem useful?
<mahmudov> or whats the equaliant design in pony
<lisael> I believe this safe-healing feature has a very specific use-cases and is not something you want in most real-life scenario
<SeanTAllen> If you have a system like Erlang where actors can "crash" at runtime, yes
<SeanTAllen> Pony has no concept of a runtime crash of an actor, so a direct port of supervision trees doesn't make sense.
<SeanTAllen> mahmudov: here is an Erlang "let it crash" scenario
<SeanTAllen> by default if an erlang actor receives a message it doesn't understand, it will crash with a "bad match"
<mahmudov> i thought pony has also a shield to runtime crashes
<SeanTAllen> and that actor will lose all its state and if restarted, you are starting over
<mahmudov> :) dead loop
<SeanTAllen> if i can't/don't want to lose that state, then i need to add code to build in resilience of that state
<SeanTAllen> erlang was designed to work in telecom switches where this behavior made sense
<SeanTAllen> if that behavior doesnt make sense for your application, you have a lot of work to do to provide resilience of state.
<SeanTAllen> Pony guarantees at compile time that you cant send a message to an actor that it doesnt understand
<SeanTAllen> So that "let it crash because of unknown message" can't happen in Pony.
<SeanTAllen> There's no concept of an actor crashing in Pony.
<SeanTAllen> Now,
<SeanTAllen> actors in general are often finite state machines
<SeanTAllen> they accumulate state
<SeanTAllen> and their runtime behavior changes as a result of that state
<SeanTAllen> for example, a TCP socket, once it has been opened, can be closed, but until it is open, it cant be closed.
<mahmudov> yeb
<SeanTAllen> In Erlang, it would be common to have the reception of a "close" message result in a "bad match" and a process crash if a socket actor wasn't open.
<SeanTAllen> Is this the right thing to do?
<mahmudov> so pony coding based on possiblites scenerios
<mahmudov> possibility*
<SeanTAllen> In some scenarios it probably is, in others, probably not.
<mahmudov> i mean you should know what a actor behaves
<SeanTAllen> But how to handle that "this is a message that i expect but not when I'm in this state"
<SeanTAllen> the default there in Erlang is to crash the actor and restart from scratch
<mahmudov> or limit the actors behaves a
<SeanTAllen> In Pony, you as the application programmer are currently responsible for deciding what to do if that happens
<SeanTAllen> because in Pony, an actor can only receive "valid" messages. But it makes no guarantee about if they are correct based on the actors internal state.
<mahmudov> you should solid design if/then/else states. isnt it
<mahmudov> you should design*
<SeanTAllen> I would like to point out that when I say "is that the right thing to do", I am not question Erlang.
<SeanTAllen> Erlang is awesome.
<SeanTAllen> But, the strategy that Erlang adopts forces you to more work if you dont like the decisions it makes as the default.
<SeanTAllen> The same holds true for Pony.
<SeanTAllen> It has default actions that happen in that scenario and it may not be what you want to happen.
<SeanTAllen> And then you have more work.
<SeanTAllen> There's no right or wrong way to address.
<SeanTAllen> There are different approaches that have different benefits and drawbacks.
<mahmudov> actually "let it crash" seems pre-stress testing
<mahmudov> yes you have to do more work but result can be rock
<mahmudov> that you said in real-word it can be more fit for distributed network applications
<mahmudov> i read whatsapp use erlang in code.?
<SeanTAllen> yes, whats app using erlang
<SeanTAllen> also there are definitely problems with correctness that can arise with "let it crash" in a network under "network partition" circumstances. Erlang is far from a panacea.
<SeanTAllen> Distributed applications are hard.
inoas has quit [Quit: inoas]
<SeanTAllen> Erlang makes message passing amongst actors regardless of physical location transparent but in the end, that is one of the easy problems of writing a distributed application.
<SeanTAllen> Are you familiar with LASP mahmudov ?
<SeanTAllen> Chris has done a ton of work to build a system that allows for the creation of distributed applications on the Erlang runtime
<SeanTAllen> Its an impressive amount of work so far and there is a lot more
<SeanTAllen> The amount of work that Chris has done speaks to
<SeanTAllen> 1) how difficult the problem can be
<SeanTAllen> 2) how the basic primitives that Erlang provides aren't a magical distributed applications panacea
<SeanTAllen> Partisan (which is part of LASP) for example, replaces distributed Erlang: https://github.com/lasp-lang/partisan
<mahmudov> you're right.it has ton of work and
<mahmudov> it seems trying to make real dist. application framework
<mahmudov> partisan like a dht server
<mahmudov> acts p2p lasp nodes
jemc has quit [Ping timeout: 268 seconds]
mahmudov has quit [Ping timeout: 248 seconds]
TheNet has quit [Quit: Textual IRC Client: www.textualapp.com]
SeanTAllen has quit []
SeanTAllen has joined #ponylang
mahmudov has joined #ponylang
mahmudov has quit [Ping timeout: 265 seconds]
martinium has joined #ponylang
Praetonus has quit [Quit: Leaving]
martinium has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
martinium has joined #ponylang
martinium has quit [Quit: Textual IRC Client: www.textualapp.com]
khan has joined #ponylang
khan has quit [Quit: khan]
khan has joined #ponylang
khan has quit [Client Quit]
khan has joined #ponylang
khan has quit [Client Quit]
khan has joined #ponylang
khan has quit [Client Quit]
khan has joined #ponylang
khan has quit [Quit: khan]
khan has joined #ponylang
khan has quit [Client Quit]
khan has joined #ponylang
khan has quit [Client Quit]
khan has joined #ponylang
khan has quit [Client Quit]
khan has joined #ponylang
user10032 has joined #ponylang
confused_ has joined #ponylang
<confused_> I've been trying to understand viewpoint adaptation for a few days and have some questions
<confused_> If we have an iso to an object and read a val from it according to the table in he tutorial we get a val
<confused_> However, iso guarantees that there are no other references to the object and Val allows to create any number of read references
<confused_> So the moment we get the val WE can read the property through the val and at the same time write to it through the iso
<confused_> There has to be something wrong in my reasoning, can someone help?
khan has quit [Quit: khan]
confused_ has quit [Ping timeout: 260 seconds]
johshoff has quit [Ping timeout: 255 seconds]
johshoff has joined #ponylang
user10032 has quit [Quit: Leaving]
dipin has quit [Quit: dipin]
vaninwagen has joined #ponylang
codec1 has joined #ponylang
codec1 has quit [Quit: Leaving.]
samuell has joined #ponylang
codec1 has joined #ponylang
samuell has quit [Remote host closed the connection]
samuell has joined #ponylang
samuell has quit [Ping timeout: 240 seconds]
samuell has joined #ponylang
mahmudov has joined #ponylang
gokr has joined #ponylang
codec1 has quit [Quit: Leaving.]
martinium_ has quit [Ping timeout: 268 seconds]
samuell has quit [Ping timeout: 268 seconds]
jnyw has quit [Quit: WeeChat 2.0.1]
samuell has joined #ponylang
khan has joined #ponylang
mahmudov has quit [Quit: Leaving]
mahmudov has joined #ponylang
_andre has joined #ponylang
<doublec> confused_: That's a good point. I think it's considered safe to access a val internal to the iso because the iso can't change it and neither can anyone else.
khan has quit [Quit: khan]
khan has joined #ponylang
<doublec> confused_: And you're not aliasing the iso, or maintaining any form of read alias to it, as the val is its own object.
khan has quit [Client Quit]
khan has joined #ponylang
bimawa1 has joined #ponylang
bimawa has quit [Ping timeout: 248 seconds]
codec1 has joined #ponylang
vaninwagen has quit [Ping timeout: 265 seconds]
Praetonus has joined #ponylang
gokr has quit [Ping timeout: 252 seconds]
martinium has joined #ponylang
alxs has joined #ponylang
mahmudov has quit [Ping timeout: 248 seconds]
gokr has joined #ponylang
mahmudov has joined #ponylang
dipin has joined #ponylang
samuell has quit [Remote host closed the connection]
<mahmudov> when i compile ponyc 0.21.2
<mahmudov> collect2: fatal error: cannot find 'ld'
<mahmudov> i have /usr/bin/ld
<mahmudov> lemme try to install ld-gold
<mahmudov> i found same issue at github
gokr has quit [Ping timeout: 252 seconds]
<SeanTAllen> mahmudov: "found the same issue at github"?
<mahmudov> collect2: fatal error: cannot find 'ld
<mahmudov> sorry
<SeanTAllen> there's a ton of inofrmation you'll need to provide mahmudov
<SeanTAllen> for example, linux? which distro?
<SeanTAllen> etc etc
<SeanTAllen> is your error that ld cant be found or that ld.gold cant be found?
<mahmudov> i am using milis linux - lfs based
<mahmudov> btw i havent ld.gold
<SeanTAllen> what is the error oyu are getting?
<SeanTAllen> can you post a gist?
<SeanTAllen> transfer.sh and downloading a file is a bit of a pain
<mahmudov> i am using these instructions
<mahmudov> with llvm 4.0.0
<SeanTAllen> winksaville: have pony working on arch with llvm 5
<SeanTAllen> you need to have gold installed
<SeanTAllen> beyond that, winksaville would be your best person to talk to although i think he updated the arch instructions, im not sure though
<mahmudov> ok i am compiling gold.then i ll try with it.
<mahmudov> ugh at now : /usr/bin/ld.gold: -plugin: unknown option
<mahmudov> i am using binutils 2.26
<mahmudov> hm i think i will re compile binutils with enable-plugins
Jwashton has joined #ponylang
Amun_Ra has quit [Ping timeout: 260 seconds]
Amun_Ra has joined #ponylang
<mahmudov> ok thnks.i successfully compiled ponyc with llvm-4.0.0
<mahmudov> +1 i did its package
<mahmudov> linkings..
<mahmudov> is it possibly to compile statically a pony program?
<mahmudov> i couldnt see options
<SeanTAllen> do you mean like `go` with no shared library dependencies @mahmudov ?
<mahmudov> yeb
<mahmudov> my hello world app is 98.5kb with strip.
Jwashton has quit [Ping timeout: 260 seconds]
<mahmudov> i wonder if we compile it statically
<mahmudov> btw is anybody uses pony with musl-c
gokr has joined #ponylang
<SeanTAllen> there was been a bit of work towards working with musl-c yet but that isn't something you can do yet
Jwashton has joined #ponylang
Jwashton has quit [Read error: Connection reset by peer]
Jwashton has joined #ponylang
<mahmudov> what about statically compiling ?
<mahmudov> with no shared libs
Jwashton has quit [Remote host closed the connection]
Jwashton has joined #ponylang
Jwashton has quit [Ping timeout: 264 seconds]
<Praetonus> mahmudov: This should theoretically be possible, you just need to have a static version of the required libs installed
confused has joined #ponylang
gokr has quit [Ping timeout: 248 seconds]
<Praetonus> You can use `ldd some_compiled_pony_program` to see what libs are required
<mahmudov> i wonder if ponyc compiler has -static option
<mahmudov> yes i saw
<Praetonus> No, it doesn't have a static option
<mahmudov> ok.just curious
<confused> i asked a question yesterday night about viewpoint adaptation (https://irclog.whitequark.org/ponylang/2018-01-09#21004365) and got an answer that still left me confused
<confused> if we have an iso to an object and we read a member of the object through a val arent we breaking the guarantees provided by the iso namely that it is the only reference to the object that can read or write?
<dipin> @mahmudov compiling ponyc with musl-c works if you're using alpine linux (or at least it worked last i checked).. it hasn't been verified to be working in the general case on glibc based systems (like ubuntu) so you might run into some issues in that environment
Jwashton has joined #ponylang
<dipin> @Praetonus, @mahmudov creating functional static binaries with ponyc is not currently possible due to the use of "dlsym" in the runtime. The binaries compile/link fine but the runtime doesn't initialize properly due to the lack of being able to load symbols dynamically. Source: I tried a few weeks ago.
<mahmudov> hm i ll try to compile ponyc with musl.but good to know it.so i will compile shared also at with musl
Jwashton has quit [Remote host closed the connection]
Jwashton has joined #ponylang
<SeanTAllen> confused: question 1... how does that break guarantees around writing?
<dipin> i don't recall if musl on alpine gets linked as shared or static but i'd assume it was shared... also, the issue isn't with compiling as a static binary itself but with how some of the internal runtime serialisation related symbol resolution is done at runtime via "dlsym" that doesn't work correctly when compiled as a static binary
<confused> i dont think it breaks guarantees around writing but it breaks guarantees around reading
<SeanTAllen> confused: question 2... what do you mean by "read a member through a val"?
<confused> I probably get the terminology wrong, sorry aobut that im pretty new to pony
<SeanTAllen> its ok
<SeanTAllen> so you mean
<SeanTAllen> i have an `iso` and it has a `val` field, and i read that field?
<dipin> as praetonus said, compiling static should be relatively easy to do since you can run `ponyc` to output the linking command it normally uses `-V 3` iirc.. and also run `ponyc` to output the `.o` file before linking and then do a manual link as static
<confused> "i have an `iso` and it has a `val` field, and i read that field?" <- yes
<dipin> that's what i did when i was playing around and after some trial and error got it compiled
<SeanTAllen> iso says i only have 1 reference to the iso object
<SeanTAllen> the field is not iso, its a val
<SeanTAllen> there can be many references to a val
<confused> so a reference to a field inside the object is not considered a reference to the object?
<SeanTAllen> its a reference to the object in the field, not a reference to the object
<mahmudov> +1 dipin.
Jwashton has quit [Ping timeout: 248 seconds]
<SeanTAllen> this is why iso things can only operate on shareable things
<confused> my concern is the iso can be "cast" (im sure theres a better word) to a ref which is mutable
<SeanTAllen> like val or tag
<SeanTAllen> how would you cast an iso to a ref?
<confused> iso guarantees that its unique, if an actor has an iso isnt it safe to consume the iso and get a ref?
<SeanTAllen> yes
<SeanTAllen> that isnt casting though
* confused using the wrong terminology again
<SeanTAllen> what is your concern?
<confused> suppose i have an iso to object A and i get a val to a member m of object A
<confused> now I consume the iso to A and get a ref to A
<confused> so I'm holding a ref to A and a val to m
<SeanTAllen> ok
<confused> I can use the ref to A to mutate any members of A including m and at the same time I can send the val to m to another actor
<SeanTAllen> no
<SeanTAllen> you cant mutate m
<SeanTAllen> m is a val
<SeanTAllen> its immutable
<SeanTAllen> a ref does not say that you can mutate any member of A
<SeanTAllen> that is where the misunderstanding is
<confused> I see, so what does an iso to A allow you to do?
<confused> or a ref to A for that matter
<SeanTAllen> a `ref` can have many local write aliases, this means its not shareable, i can't send it to another actor
<SeanTAllen> `iso` can only have 1 local write alias, this means that i can consume it and send it to another actor, making it shareable.
<SeanTAllen> a `ref` to A allows me to mutate any mutable fields of A
<confused> I see, so iso to A provides no guarantees about mutability of A's internal state
nisanharamati has joined #ponylang
<SeanTAllen> i dont understand the implications of your statement
<SeanTAllen> can you rephrase?
<SeanTAllen> iso says, "i can mutate this object AND there is only 1 reference"
<confused> nm, i think in understand now
<confused> i need to revisitng the table with this new knowledge :)
<confused> thanks
<confused> (I'm sure Ill be back with more questions though)
<SeanTAllen> you're welcome
<SeanTAllen> btw, @confused have you seen the morning paper write up? some folks find it helpful... https://blog.acolyer.org/2016/02/17/deny-capabilities/
<SeanTAllen> there's also a few suggestions on the website for learning reference capabilities, have you seen that? https://www.ponylang.org/learn/#reference-capabilities
Jwashton has joined #ponylang
<confused> yes, i read the available documentation. If I follow the table blindly I can use the language without any major problems
<confused> but when I tried to understand how the table is built there were a bunch of cells i didnt understand
<SeanTAllen> that's fine. its a learning process.
<SeanTAllen> and depending on your background, the level of difficulty of the process can vary widely.
khan has quit [Quit: khan]
khan has joined #ponylang
user10032 has joined #ponylang
khan has quit [Client Quit]
khan has joined #ponylang
codec1 has quit [Read error: Connection reset by peer]
khan has quit [Quit: khan]
khan has joined #ponylang
confused has quit [Ping timeout: 260 seconds]
khan has quit [Client Quit]
khan has joined #ponylang
samuell has joined #ponylang
Jwashton has quit [Remote host closed the connection]
Jwashton has joined #ponylang
Jwashton has quit [Ping timeout: 240 seconds]
khan has quit [Quit: khan]
khan has joined #ponylang
Jwashton has joined #ponylang
khan has quit [Client Quit]
khan has joined #ponylang
khan has quit [Quit: khan]
khan has joined #ponylang
khan has quit [Client Quit]
khan has joined #ponylang
khan has quit [Client Quit]
khan has joined #ponylang
confused has joined #ponylang
<confused> im back with more questions :)
<confused> according to the viewpoint adaptation table a trn property read through an iso reference returns a tag
<confused> why can't it return a val instead?
khan has quit [Client Quit]
khan has joined #ponylang
<Praetonus> confused: Because the trn still exists. If you later consume the iso to a ref, you'll have a trn and a val to the field at the same time
<Praetonus> And that's unsafe
<confused> ill try to rephrase that: 1) I get the val from the trn and the object still has a trn internally, 2) I consume the iso to the object to a ref to the object, 3) I get the trn from the object as a trn via the ref i now have to the object
<confused> is that the scenario?
<Praetonus> Yes, exactly
<confused> so the cell in the viewpoint adaptation table are mutually dependent?
dipin has quit [Quit: dipin]
<Praetonus> I'm not sure I understand your question
<confused> i.e. i cant reason about the value in a cell based only on the origin and field refs?
<confused> s/so the cell/so the cells/
khan has quit [Quit: khan]
khan has joined #ponylang
khan has quit [Client Quit]
khan has joined #ponylang
martinium has quit [Quit: Leaving]
codec1 has joined #ponylang
gokr has joined #ponylang
jemc has joined #ponylang
amclain has joined #ponylang
<confused> fyi, I think what I'm trying to understand is the "capabilities at field read" part of this document: http://www.doc.ic.ac.uk/~scd/fast-cheap.pdf
<confused> the problem is I cant find a detailed explanation for each cell in table 3
confused has quit [Ping timeout: 260 seconds]
_andre has quit [Quit: leaving]
aturley_ has quit [Quit: aturley_]
aturley has joined #ponylang
khan has quit [Quit: khan]
khan has joined #ponylang
khan has quit [Client Quit]
khan has joined #ponylang
khan has quit [Quit: khan]
mahmudov has quit [Quit: Leaving]
mahmudov has joined #ponylang
vaninwagen has joined #ponylang
alxs has quit [Read error: Connection reset by peer]
alxs has joined #ponylang
Praetonus has quit [Ping timeout: 264 seconds]
jemc has quit [Ping timeout: 264 seconds]
jemc has joined #ponylang
Praetonus has joined #ponylang
alxs has quit [Quit: Computer's gone to sleep. ZZZzzz…]
vaninwagen has quit [Ping timeout: 260 seconds]
vaninwagen has joined #ponylang
mahmudov has quit [Ping timeout: 256 seconds]
confused has joined #ponylang
Jwashton has quit []
samuell has quit [Quit: Leaving]
mahmudov has joined #ponylang
user10032 has quit [Quit: Leaving]
mahmudov has quit [Client Quit]
mahmudov has joined #ponylang
dipin has joined #ponylang
codec1 has quit [Read error: Connection reset by peer]
jnyw has joined #ponylang
vaninwagen has quit [Ping timeout: 268 seconds]
amclain has quit [Quit: Leaving]
malthe has quit [Ping timeout: 240 seconds]
malthe has joined #ponylang