alexashka has quit [Read error: Connection reset by peer]
gokr has joined #ponylang
acarrico has quit [Ping timeout: 248 seconds]
gokr has quit [Client Quit]
pzel has quit [Ping timeout: 252 seconds]
endformationage has quit [Quit: WeeChat 1.9.1]
acarrico has joined #ponylang
pcarrier has joined #ponylang
gokr has joined #ponylang
SenasOzys has joined #ponylang
vaninwagen has joined #ponylang
khan has quit [Quit: khan]
khan has joined #ponylang
khan has quit [Client Quit]
khan has joined #ponylang
pcarrier has quit [Quit: Connection closed for inactivity]
khan has quit [Quit: khan]
vaninwagen has quit [Ping timeout: 260 seconds]
vaninwagen has joined #ponylang
_rck has joined #ponylang
gokr has quit [Ping timeout: 256 seconds]
acarrico has quit [Ping timeout: 252 seconds]
SenasOzys has quit [Ping timeout: 252 seconds]
vaninwagen has quit [Ping timeout: 252 seconds]
jemc has joined #ponylang
SenasOzys has joined #ponylang
aturley has joined #ponylang
acarrico has joined #ponylang
<hmans>
\o/
<hmans>
Just wondering... is there a way to support the development of Pony with monies (or other resources -- I make decent cheesecakes, but live in Germany, so that'll be a bit complicated I believe)?
<SeanTAllen>
At the moment, no.
<SeanTAllen>
Best way to support now is by volunteering time
<hmans>
Noted... I wish I had more of it. (Stuck in a big client project for the next few months.)
_rck has quit [Ping timeout: 252 seconds]
_rck has joined #ponylang
aturley has quit [Quit: aturley]
<jemc>
as a corollary to that, if you're an employer, another way to support Pony is to pay one or more employees to spend some of their time on improving Pony, which helps a lot even if you're still only doing it for "selfish" reasons of improving Pony so it can be used in your product
<SeanTAllen>
indeed
<jemc>
The time that Wallaroo Labs team members spend contributing to Pony has been super valuable for the community
<SeanTAllen>
i was going to say something like that.
<SeanTAllen>
jemc is faster typer than i
<jemc>
and to think that in typing class in high school they told me I would never type quickly as a hunt-and-peck typist
<jemc>
(or maybe you're a homerow-free typist as well)
<SeanTAllen>
my only memory of typing class was when Billy threw Aaron through the window
<dave24>
Whenever I make statemachines to parse messages incoming from the network I find myself wanting switch statements. I always add the data I get to a buffered Reader and incement a counter each time I read from it.
<dave24>
So that when a read fails, I can carry on where I left of when I have more data by using the counter.
<dave24>
But then I always have to check each individual read to see if the counter says I have to read that part. Is there a better way?
<jemc>
(I don't think I've fully digested/understood your situation yet, but what's missing from `match` statements in pony that you still miss from `switch` statements?)
<dave24>
fallthrough
<dave24>
I want to carry on where I left of based on the counter.
<dave24>
Unless there is some alternative way of approaching the whole problem.
<jemc>
I don't think I understand how that relates to fallthrough - maybe you can paste to a gist either a pony snippet of what you're doing, or a C pseudocode snippet for what you *want* to do with fallthrough, or both?
<SeanTAllen>
dave24 - i dont understand what it is you are trying to do there. the "step = 3" for example confuses me, is there a check for step == 3 you arent showing?
<_rck>
dave24: if you don't care for the intermediate steps, and only about having a,b and c set at the end of the parsing, you could wait until you have enough data in the buffer to read the three of them in a single call
<SeanTAllen>
dave24: yes, you can use `expect` to not have received called until you have gotten the expected amount of data.
<dave24>
jemc: yes, thats a more concise way to write it. But the problem of checking at each step is still there.
<dave24>
The gist is only an example, I don't know the length of the message until I am part way through parsing
<jemc>
hmans: don't despair, I also work at a company that does mostly Ruby work (though luckily I found a company that avoids Rails ;), but I'm trying to push my coworkers to be more polyglot (many of them already are), and I've sort of become known as somebody in the company to talk to when you want to do something interesting with distributed systems
<jemc>
dave24: I'm guessing from your answer that you do not control the protocol in question
<hmans>
jemc: for the record, I <3 Rails for what it is. But I also love many other things.
<dave24>
jemc: I do, but parts are size prefixed strings.
<jemc>
if you control the protocol, can you make the entire message be size-prefixed?
<hmans>
I have this life-long white-whale side project of a distributed social blogging thing build on top of Indieweb protocols (Webmention, microformats2 and the likes). The current incarnation is built with Crystal, but I may end up switching to Pony.
<jemc>
dave24: basically, just add a fixed-size size-prefix header to the message format you already have, then you can use `expect` as Sean suggested to ensure that your entire message will be one contiguous `Array[U8]`
<hmans>
An earlier version was built with Rails purely for development speed, but now I'm looking at making it "nano". The current version has a 1.5MB executable (half of which is baked-in frontend assets) and needs around 2MB of RAM.
<jemc>
Crystal is really cool! one of my coworkers is one of the founders and it's been fun talking shop about LLVM language compilers with him :)
<hmans>
@jemc: asterite?
<jemc>
yeah
<hmans>
<3
<dave24>
jemc: hm, pony is not the only language that decodes the message. I don't know if I can add another thing to the protocol just so it suits pony.
<jemc>
he's been great to work with - the last project we were on, we worked very closely together
<hmans>
To be honest, from the outside he's making the impression of being really burnt out with the language, which is one of the things that's currently scarying me away from Crystal :/
<dave24>
I just thought there would be some conventional way to do this state-machiney sort of thing wich often uses `switch` in C-like languages. But if not that's no big deal.
<jemc>
dave24: I would consider it to make it easier to parse in all languages, actually - it's a pretty common technique
<hmans>
One the first things that impressed me about Pony was the amount and openness of communication, which Crystal only has very little of unfortunately. Besides hanging out in #crystal-lang and chatting with some of the regulars, the development of the language often feels like a black box
<jemc>
it just puts an 8-byte header (plus 1 "magic byte" as a small sanity check) in front of all messages that tells the decoder how many bytes to wait for before trying to parse
<jemc>
it's a useful pattern in any language, because they'll all have this problem of not knowing how many TCP packets the message might be spread over
<jemc>
not only does it simplify parsing logic, but it minimizes copying of the buffer, because `expect` lets you tell `TCPConnection` itself to read it in as a contiguous byte buffer of that size, and avoiding copying is important for performance
gokr has joined #ponylang
<dave24>
jemc: that is a good point. Thanks, I will think about it.
<jemc>
hmans: to be honest, I've not had a lot of interaction with the Crystal community in general, so I don't have any special insight to share
jaro has joined #ponylang
<jemc>
I just think Crystal is a cool initiative, because I like Ruby, and like LLVM languages, and Pony has dragged me into now liking type systems :D
pzel has joined #ponylang
pzel has quit [Ping timeout: 252 seconds]
endformationage has joined #ponylang
<hmans>
@jemc Types are nasty... someone offers you one at a party and then you're hooked and can't function without them
pzel has joined #ponylang
gokr has quit [Ping timeout: 245 seconds]
jemc has quit [Ping timeout: 245 seconds]
jemc has joined #ponylang
pzel has quit [Ping timeout: 240 seconds]
pzel has joined #ponylang
<alexashka2>
good day - I have a question regarding closure variable capture - I have this: let httpHandlerF = { (s: HTTPSession)(t: Main tag = this): HTTPHandler ref^ => HTTPNotify.create(t, s) } val. It compiles but I have to specify t: Main tag. Why does the compiler assume t will be anything but a tag since Main is an actor?
<alexashka2>
if I remove the type annotation, it no longer compiles and says that t has to be a sendable type: tag, iso or val
<jemc>
you should be able to specify `t: Main` instead of `t: Main tag` and have it compile to the same thing
<jemc>
the reason it tries to choose a non-sendable type (`ref`) is probably because you are inside of a behaviour of the `Main` actor, where the type of `this` is `Main ref`
<alexashka2>
jemc: this is inside a regular function in main. Would a gist help?
<alexashka2>
jemc: removing tag does compile, which makes it even more confusing. It can't figure out the type of this without an annotation?
<jemc>
no, it's figuring out the type of `this`, but what you want is not the type of `this` - you want to downgrade the cap to `tag`, making it a different type from `this`
<jemc>
that is, if you don't specify a type there, it will use the type of `this`, which is probably either `Main ref` or `Main box`, depending on what kind of function you're in
pzel has quit [Remote host closed the connection]
pzel has joined #ponylang
<jemc>
what you want it to use is `Main tag` instead of either of this, so you need to specify that - and because it is an actor, saying `Main` is always short for saying `Main tag`
<alexashka2>
jemc: ah ok... so if I was to do this inside fun ref test(), this would be Main ref. And inside fun test(), it would be Main box?
<jemc>
yeah
pzel has quit [Ping timeout: 260 seconds]
<alexashka2>
jemc: that's very clever. What's the default for be test(), what cap is `this`?
<jemc>
`ref`
_rck has quit [Ping timeout: 245 seconds]
<alexashka2>
makes sense, very clever stuff, thank you :)
<jemc>
no problem - glad to help
SenasOzys has quit [Remote host closed the connection]
SenasOzys has joined #ponylang
<alexashka2>
ok follow up question. When I have 2 actors. I create an instance of one inside the other, so it's cap is tag. But for functions inside the actor that modify the fields, the actor cap is ref. I'm a little confused on this point. How can something be a ref for insider functions, when it was initialized as a tag?
<alexashka2>
if I create a class instance as a val for example, the class instance can't modify it's fields, because it was created as a val. With actors, it seems like the rules differ
khan has joined #ponylang
<SeanTAllen>
An actor is not "created as a tag"
khan has quit [Client Quit]
<SeanTAllen>
you can only have a tag reference to it
<SeanTAllen>
you can only send messages to it
<SeanTAllen>
that means `be` basically
<alexashka2>
SeanTAllen: right, so actors are really refs internally, but tags for anyone that can reference them? is that the right intuition?
<SeanTAllen>
i wouldnt phrase it that way
<SeanTAllen>
but i think you have the general intution down
<alexashka2>
SeanTAllen: help me bridge the gap - I can specify the new cap create() for classes. It can be a val, ref, etc. For actors, I can't do that. So they're fundamentally different it seems?
<SeanTAllen>
yes
<SeanTAllen>
they are different
<jemc>
alexashka2: one of the exercises that I think will help you with this question is thinking about which ref caps are locally compatible and globally compatible with a given ref cap
<jemc>
these are two concepts used in the formal verification of pony's ref cap system, but it's also good to get an informal grasp on them
<jemc>
locally compatible ref caps means that other references to the same object can exist with those ref caps within the same actor
<jemc>
globally compatible ref caps means that other references to the same object can exist with those ref caps in other actors
<jemc>
for example, take `iso`
<jemc>
an `iso` is read-unique and write-unique, which means no other reference can read or write to that object, either locally or globally - so the `tag` is the only locally compatible r. cap, and it's also the only globally compatible r. cap
<jemc>
as another example, take `val`
<jemc>
a `val` is guaranteed to be immutable, so no references anywhere can write to it, but by nature of that it's also safe to read from anywhere - so `val`, `box`, and `tag` are the locally compatible r. caps, and they are also globally compatible r. caps
<jemc>
as another example, take `tag`
<jemc>
it can do very little other than know the identity of an object or send it a message if its an actor (it can't actually read or write to the objects fields), so it imposes no restrictions, and is locally and globally compatible with all r. caps
<jemc>
you'll notice that all three examples I gave so far have the same set of r. caps for local and global compatibility - that is what makes them *sendable* across an actor boundary
<jemc>
as another example that does not have that property, take `ref`
<jemc>
you can read and write to a `ref` locally (within the actor it exists in), and aliases can be created to it, so it is locally compatible with `ref`, `box`, and `tag` - but you can't touch it from other actors except as a `tag`, so that's the only cap it is globally compatible with
<jemc>
I say all this just to make the point that you can have different references with different r. caps to the same object, both locally (within the same actor) and globally (across actors), but those are governed by rules of safety
<alexashka2>
jemc: I hear you. I think the distinction I'm drawing in my mind is that with a class, you can instantiate it to be iso, turn, ref, val. With an actor, it's only ever tag
khan has joined #ponylang
<jemc>
so an actor is a type that is always `ref` locally - it is a bundle of mutable state that can change with each invocation of a behaviour
<jemc>
but from *other* actors you always refer to it as `tag`, because that is the only r.cap that is globally compatible with `ref`
<alexashka2>
so with classes, you get this interplay of what you create it as, affects the inner-members. if you create a val class instance, you can't call fun ref test() on it. With an actor, you don't get that level of subtlety
<jemc>
theoretically, you could create an actor as a `val` instead of a `ref`, but Pony doesn't let you do that because it wouldn't really have any practical purpose
<alexashka2>
jemc: right, because you don't have be val test() as a possibility?
khan has quit [Client Quit]
<jemc>
no, just because an immutable actor doesn't have any advantage that you couldn't get from refactoring it into either a mutable actor, or an immutable data structure
khan has joined #ponylang
<jemc>
the important point I wanted to make was that actors are not created as `tag` - they are created as `ref` and then a `tag` reference is shared back to the caller
<alexashka2>
jemc: well if you had say a proxy actor, that forwards messages. It has no mutable state. Wouldn't it be nice to say ok, we know this actor is only a proxy, because it has val rcaps?
<alexashka2>
jemc: yes, that's what I figured - regarding created as ref, shared as tag :)
<jemc>
if it has no mutable state, why does it need to be an actor? why not just a `class val` that knows how to forward to the other actor?
<alexashka2>
jemc: I'm quite new to actors so I don't know, you may very well be right that there is no usecase for an actor without mutable inner state
PrsPrsBK has joined #ponylang
PrsPrsBK has quit [Client Quit]
<jemc>
yeah, I think it would be only extra messaging overhead with no benefit - it would be two async message hops instead of one
<jemc>
as context, I think the main reason the actor abstraction exists is because we want to have an ergonomic and sound way to deal with a chunk of mutable state in a concurrent system
<jemc>
and the actor paradigm solves that by putting a wrapper around that state, which you can only interact with via message passing to and from it
khan has quit [Remote host closed the connection]
<jemc>
dealing with immutable state in a concurrent system is trivially sound, as it can be shared and directly accessed in any way as long as everyone agrees not to ever modify it
acarrico has quit [Ping timeout: 248 seconds]
gokr has joined #ponylang
khan has joined #ponylang
acarrico has joined #ponylang
khan has quit [Client Quit]
vaninwagen has joined #ponylang
khan has joined #ponylang
khan has quit [Read error: Connection reset by peer]
khan has joined #ponylang
khan has quit [Client Quit]
khan has joined #ponylang
khan has quit [Client Quit]
khan has joined #ponylang
SenasOzys has quit [Ping timeout: 252 seconds]
_rck has joined #ponylang
khan has quit [Remote host closed the connection]
khan has joined #ponylang
khan has quit [Client Quit]
khan has joined #ponylang
SenasOzys has joined #ponylang
SenasOzys has quit [Remote host closed the connection]
SenasOzys has joined #ponylang
khan has quit [Quit: khan]
khan has joined #ponylang
<vaninwagen>
_rck you observed a bottleneck when reading in pony-kv? or was that a typo and you actually meant, that you need to wait for all writes to happen before yours can succeed?
droman has joined #ponylang
<vaninwagen>
definitely, CRDTs do have a great advantage here
<_rck>
sorry, maybe I wasn't clear, yeah, I meant the second, writes will wait
<vaninwagen>
phew, i thought i made a terrible mistakeC!
<vaninwagen>
anyways this was only intended as a small toy KV-store, nothing too serious. More serious business is going on over at: https://github.com/jemc/jylis
<_rck>
haha, no worries, if you're interested, I ran some throughput / latency tests against it: https://imgur.com/a/H8le5VY
<_rck>
(ignore the aborted/committed part, that was something from some other tests I was running against other systems)
<vaninwagen>
_rck not bad, not bad. what machine did you run that on?
<_rck>
not intended as an exhaustive benchmark anyway, this was just me doing some quick tests
<_rck>
this was on my laptop, a 2013 macbook pro
<vaninwagen>
i intended to run it against redis-benchmark, but didn't manage to do it yet
<SeanTAllen>
you'd get much better results vaninwagen if you run on linux and set aside cpus specifically for the pony application
<_rck>
I didn't use the redis interface for this, changed it to a simple binary protocol
khan has quit [Quit: khan]
<_rck>
get key, reply ok (so there's no value coming back)
khan has joined #ponylang
<vaninwagen>
SeanTAllen yeah, i'm gonna reserve a full machine for the pony app :)
<_rck>
I have some other, beefier linux box with ponyc from source and LLVM bitcode enabled that I want to do some experiments on
<vaninwagen>
_rck so, the write congestion case wasn't benchmarked here, right?
<_rck>
take all of these graphs with a big pinch of salt, though
khan has joined #ponylang
<vaninwagen>
hmmmm... dunno if i should be worried about these graphs or not. what tool did you use for benchmarking and graphing?
<_rck>
benchmark was a modified version of basho_bench, graphing was some combination of R scripts
<_rck>
we use the same tools internally for benchmarking, but like I said, these were some quick tests that I ran yesterday, maybe you'll experience something different
<vaninwagen>
_rck sure thing, thanks for sharing this :)
<alexashka2>
hi, is there an example of json parsing floating around somewhere? I haven't found it in ponyc examples
<alexashka2>
sigh is this because JsonDoc has new iso create() as it's initializer?
<vaninwagen>
yeah, it is the iso and how it sees ref fields
<alexashka2>
good god - you'd think these gotchas would be documented for newcomers to not outright quit the language in frustration
<vaninwagen>
it sees them as tag, because they could leak a reference to the outside, it would not be safe to see a ref field through an iso object...
<vaninwagen>
and the json types are not properly aligned in their refcaps
<vaninwagen>
alexashka2: would you mind open an issue for this one? so we can keep track of this
khan has quit [Client Quit]
<alexashka2>
vaninwagen: there just needs to be an example, for simple json parsing, in the docs. How is a newcomer who wants to make a url request, parse json and print it out ever going to succeed when there are 13 hoops to jump through to make that happen?
khan has joined #ponylang
<vaninwagen>
this is definitely a downer, i agree. if you could post an issue about this, that would be great.
<alexashka2>
vaninwagen: I'll do that, let me get a glass of water to stop steam from coming out of my ears :)
<vaninwagen>
alexashka2: thank you, i feel your frustration!
<alexashka2>
vaninwagen: on a lighter note - what is the purpose of JsonDoc being an iso by default? I don't grasp the logic behind making different base types be different rcaps. String is val, Json is iso, regular classes are ref. What is going on here?
khan has quit [Quit: khan]
<vaninwagen>
hmmm... iso is mostly for mutable stuff that should be sendable.
aturley has joined #ponylang
<vaninwagen>
you can recover iso classes to any other refcap, once consumed, so it is more powerful, so to say, than e.g. val, which you can't recover to a ref or iso
<alexashka2>
vaninwagen: so by that logic, shouldn't classes be iso by default?
<alexashka2>
vaninwagen: class instances are the usual pass-around objects from what I can tell
<vaninwagen>
i remember some serious limitations coming from making them iso by default... let me think
<alexashka2>
vaninwagen: well the limitation would be using it within the actor, being a pain in the ass, bc you'd have to consume every time you want to pass it to a function
<vaninwagen>
there was another one
<alexashka2>
vaninwagen: I guess I just don't get why jsonDoc is different from a regular class
<alexashka2>
vaninwagen: the most common operation would be look-ups, and iso by default prevents that very thing
<vaninwagen>
alexashka2: it prevents lookups to some field that is ref
<vaninwagen>
which is right and safe and sound
<_rck>
my guess is that a jsonDoc is something you would end up sending over the network
<vaninwagen>
the design of the json lib is just a little unfortunate
<_rck>
so for it to be sendable by default, probably makes sense
khan has joined #ponylang
<vaninwagen>
alexashka2: it is actually this very case we have here, that is the problem of making classes iso by default. you cannot access fields that are not sendable (e.g. ref or box)
<vaninwagen>
this needs to be fixed in the json package
<alexashka2>
vaninwagen: well, String is val by default, and the you can have ref if you want it
<alexashka2>
vaninwagen: to me, it makes sense to either do the same for json, or I don't know. I think consistency matters
<alexashka2>
vaninwagen: for val jsonDoc, you initialize it with a string and it's a failable initializer. For mutable json, you do the same as you would for string, and have methods to manipulate it
khan has quit [Quit: khan]
khan has joined #ponylang
<vaninwagen>
alexashka2: i can't quite follow. JsonDoc.create returns iso, but the default refcap is ref. String.create returns ref but the default refcap is val.
<alexashka2>
vaninwagen: right, I'm saying can we have consistency among datatypes?
<vaninwagen>
alexashka2: lets first have some consistency across the json package. i'd say this if the first and foremost issue.
<alexashka2>
vaninwagen: agreed :) one step at a time, hehe
<vaninwagen>
we could even make this JsonDoc consistent with String somehow, if this makes sense
khan has quit [Client Quit]
khan has joined #ponylang
<alexashka2>
vaninwagen: right, that's what I'm saying. Frankly, creating a mutable string with a default value is non-obvious currently. But I'm not sure that can be improved upon
khan has quit [Remote host closed the connection]
<alexashka2>
vaninwagen: recover ref String.>append("defaultValue") end seems strangely verbose, and undocumented :)
_rck has quit [Ping timeout: 264 seconds]
<vaninwagen>
but in the example above you don't need a recover at all
<vaninwagen>
it is already String ref
vaninwagen has quit [Quit: WeeChat 2.0]
<alexashka2>
ah agreed you don't. Ok just String.>append("defaultValue") is still not ideal I think?
<alexashka2>
in terms of aesthetics, and aesthetics matter, if you're going to be staring at them everyday I feel
vaninwagen has joined #ponylang
vaninwagen has quit [Quit: WeeChat 2.1]
droman has quit [Quit: WeeChat 2.1]
<SeanTAllen>
personally im more interested in semantics.
<alexashka2>
why not both right? :)
_rck has joined #ponylang
aturley_ has joined #ponylang
aturley has quit [Ping timeout: 245 seconds]
aturley_ has quit [Quit: aturley_]
aturley has joined #ponylang
_rck has quit [Quit: WeeChat 2.1]
pzel has joined #ponylang
endformationage has quit [Ping timeout: 260 seconds]