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
chemist69 has quit [Ping timeout: 264 seconds]
chemist69 has joined #ponylang
amclain has quit [Quit: Leaving]
chemist69 has quit [Ping timeout: 240 seconds]
jemc has quit [Ping timeout: 240 seconds]
chemist69 has joined #ponylang
smoon has joined #ponylang
<endformationage> Can traits and interfaces be generic?
jemc has joined #ponylang
papey_lap has joined #ponylang
papey_la1 has quit [Ping timeout: 268 seconds]
<SeanTAllen> yes
<SeanTAllen> endformationage: yes
chemist69 has quit [Ping timeout: 258 seconds]
chemist69 has joined #ponylang
smoon has quit [Quit: smoon]
smoon has joined #ponylang
graaff has joined #ponylang
gmcabrita has quit [Quit: Connection closed for inactivity]
jemc has quit [Ping timeout: 240 seconds]
jemc has joined #ponylang
smoon has quit [Quit: smoon]
plietar has quit [Remote host closed the connection]
plietar has joined #ponylang
plietar has quit [Ping timeout: 260 seconds]
<endformationage> I see that calling an actor's behavior at the end of its constructor does not que the message before other messages queued by behavior calls on the actor obj after construction.
<endformationage> For some reason I did not expect that.
<jemc> endformationage: it makes a little more sense when you realize the constructor is also asynchronous
<endformationage> Ah, I remember reading something like that now..
<jemc> that is, if you looked at the order of messages in Foo's mailbox after `Main.create`, it would be something like (`create`, `act("B")`, `act("C")`)
<jemc> and the `act("A")` doesn't get enqueued until the `create` executes
<jemc> and actually, if `create` was super fast to execute, it's *possible* it could enqueue the `act("A")` before the `act("B")` and `act("C")` got enqueued from the original thread executing `Main.create`
<endformationage> OK, I can see this.
<jemc> with Pony's causal message ordering, we know that: `create` happens before `act("B")`, `act("B")` happens before `act("C")`, and `create` happens before `act("A")`
<jemc> (and we also know by the transitive property that `create` must then happen before `act("C")`)
<jemc> but everything without a causal relationship is "up for grabs"
<endformationage> right
<jemc> particularly, we don't know which happens first between A or B, or between A or C
chemist69 has quit [Ping timeout: 260 seconds]
chemist69 has joined #ponylang
jemc has quit [Ping timeout: 260 seconds]
serejkus has joined #ponylang
<serejkus> hello everyone. Do you have offline docs (like pdf or html or whatever else)? I'd like to play with pony lang, but I won't have an internet connection for a couple of days
<endformationage> I had a try at something with generics at various levels, but failed to get through the ref cap details. I don't really know if what I tried is possible, but I'd like to know why it doesn't work.
<endformationage> I hope the comments made my intensions clear. Will check the log. Zzz.
serejkus has quit [Quit: Page closed]
<endformationage> Ah, too late. There's download link at that page, FYI.
endformationage has quit [Quit: WeeChat 1.7]
<doublec> endformationpage: I don't think using Fruit as a type parameter to a generic constrains the type to "Apple" or "Pair"
<doublec> endformationpage: It constrains it to (Apple|Pair) which is a single type
<doublec> endformationpage: You want Fruit to be an interface or trait
<doublec> endformationpage: Which Apple and Pair implement
<doublec> endformationpage: but I don't really understand what you are trying to do. Can you explain?
Matthias247 has joined #ponylang
gmcabrita has joined #ponylang
Matthias247 has quit [Read error: Connection reset by peer]
smoon has joined #ponylang
<SeanTAllen> Pony 0.14.0 has been released. Closes a number of high-priority bugs: https://www.ponylang.org/blog/2017/05/0.14.0-released/
<FunkyBob> congrats!
<SeanTAllen> thanks FunkyBob: it's a slow, gradual progression towards 1.0
<FunkyBob> correct, then fast :)
<FunkyBob> was just reading the hash map fix PR
<FunkyBob> interesting stuff
<FunkyBob> I t hink I need to find more reasons to use pony
smoon has quit [Quit: smoon]
<SeanTAllen> if your problem suits the language, its a great one
<FunkyBob> indeed
<SeanTAllen> its helped us immensely at Sendence. we wouldn't be as far as long as we are, with the performance we have, without it
<SeanTAllen> someone asked us the other day "but its so immature, the API is breaking all the time". "yes, but 80% of those breaking changes came out of Sendence".
<FunkyBob> I think my next move is to get a handle on good patterns to deal with actors and closing the loop
<SeanTAllen> having experience with strongly typed languages helps, having used an actor language previously also helps
<SeanTAllen> having worked with a threaded language helps
<SeanTAllen> i think those 3 are the biggest areas of "learning on your own" that give people a leg up
<SeanTAllen> so, coming from something like Python as a background is probably about the hardest path to cover
<FunkyBob> well, what I ran into in my first attempt... i had a udp socket that did some packet paring, and an actor with a hashmap
<FunkyBob> [someone helping here suggested the actor around the hashmap]
<SeanTAllen> but plenty of folks come from something like Java who are oblivious to the data-races in their code so ¯\_(ツ)_/¯
<SeanTAllen> its not a topic that gets covered much in standard learning materials. :(
<FunkyBob> and getting responses back to the udp socket so it could format and send answers.... was just not working
<FunkyBob> yah
<SeanTAllen> we need a lot more, how you do X materials
<SeanTAllen> sadly, not a lot of folks like writing documentation
<FunkyBob> I used to work in embedded microcontrollers...
<FunkyBob> so you've got a complex env with a single process [no memory protection, but many threads]
<SeanTAllen> and then the subset of that who write good, concise documentation is quite small
<FunkyBob> you feel races very hard there :)
<SeanTAllen> you are in Australia FunkyBob?
<FunkyBob> yes
<SeanTAllen> well then, I hope you enjoyed your Saturday day.
<SeanTAllen> and shit, look at the time, your evening so far as well
<FunkyBob> :)
<FunkyBob> oh, I would also be interested in your feedback on this - https://github.com/funkybob/keyster/blob/master/kt/main.pony
<SeanTAllen> couple small comments
<SeanTAllen> in your match statement, you have a lot of try...end
<SeanTAllen> with no else
<SeanTAllen> that is going to bite you in the ass
<SeanTAllen> i'd add the else's early, it will save you pain in some debugging scenario eventually
<FunkyBob> actually, in most of thoses cases the only exceptin is 'no such key' and the result would be empty string
<FunkyBob> but I was mostly trying to get the code compiling first :)
<doublec> Or do one try/else/end around the entire match so you don't need one in each clause.
<SeanTAllen> you can make hmap => _hmap as nothing outside that notifier is ever going to access it
<SeanTAllen> if you do one try/else/end though, you have no idea what the error was.
<SeanTAllen> so you know there was an error, but no idea which in the large block caused it
<SeanTAllen> from experience... try/else/end should be as small as possible to help with debugging
<FunkyBob> yeah, mine too
<FunkyBob> especially when I can't catch the exception and inspect it
<SeanTAllen> so happy to see the insert_if_absent i added in use!
<SeanTAllen> i need to go through the tutorial and remove the use of the word "exception"
<FunkyBob> is making hmap -> _hmap likely to improve performance?
<SeanTAllen> people end up thinking its going to be like C++/Java
<SeanTAllen> FunkyBob: nope
* FunkyBob is a long time python user
<SeanTAllen> do you care about performance at the moment FunkyBob ?
<FunkyBob> am interested if my code can be made faster
<FunkyBob> I have a simple benchmark, which shows this code as 20 to 25% slower than the C version
<SeanTAllen> step 1: run that with --ponythreads=1
<SeanTAllen> because the work stealing in the scheduler needs work
<SeanTAllen> its awesome for getting max performance if you have a "full workload"
<SeanTAllen> however, it is detrimental if you dont have enough work for all the threads
<SeanTAllen> and hurts performance
<SeanTAllen> i spent 2 weeks trying to get it better, but failed
<SeanTAllen> its something i need to come back to
<SeanTAllen> ----
<SeanTAllen> if the code is in a hot path, you want to avoid having `error` called
<SeanTAllen> error while faster than exceptions in something like java is fast, its still slow overall
<SeanTAllen> if you expect the "error case" a lot, then union types are a better idea and paying the cost of a match
<SeanTAllen> however if the "error case" is very infrequent, then try/end with error is a much better idea
<SeanTAllen> ----
<SeanTAllen> like any code you want to go fast, avoid memory allocations
<FunkyBob> yeah, I did look at that
<FunkyBob> well, avoiding allocs, I mean
<SeanTAllen> things like string.find can result in error, so i'd look at that as well
<FunkyBob> someone suggested making key + value into a (String | None)
<SeanTAllen> slice allocates new memory btw
<FunkyBob> ah
<SeanTAllen> how much of the incoming memory are you holding on to?
<SeanTAllen> trim and trim_in_place might be of interest to you
<SeanTAllen> one thing to note with that
<SeanTAllen> if your incoming data was 1 meg and you did a trim to get 1 byte, then the gc can't free that full 1 meg
<SeanTAllen> so, use with caution
<SeanTAllen> but it can really help with perf
<SeanTAllen> so this...
<SeanTAllen> var cmd = String.from_array(recover val src.slice(0, 1) end)
<SeanTAllen> if that was doing a trim instead of slice
<SeanTAllen> would be 0 additional allocations
<SeanTAllen> instead of the 1
<FunkyBob> oh, trim is a shared portion... swweet
smoon has joined #ponylang
<FunkyBob> so:
<FunkyBob> var cmd = String.from_array(src.trim(0, 1))
<FunkyBob> var key = try String.from_array(src.trim(1, src.find(0, 0))) else "" end
<FunkyBob> var value = try String.from_array(src.trim(2 + key.size())) else "" end
<FunkyBob> something like that?
<SeanTAllen> something like that
<FunkyBob> yep, that sped it up a little
<SeanTAllen> did you do --ponythreads=1 ?
<FunkyBob> yep
<FunkyBob> not pre-allocating the array for the response doesn't make a noticeable difference
<FunkyBob> ok, sleep time :)
<SeanTAllen> actually, how many connections are you opening?
<SeanTAllen> ponythreads of 1 was me assuming a low number
<SeanTAllen> have a good night FunkyBob
<SeanTAllen> not pre-allocating would make a large difference under load
plietar has joined #ponylang
chemist69 has quit [Ping timeout: 240 seconds]
chemist69 has joined #ponylang
<SeanTAllen> Ever wondered about Pony's origin story? Wonder no more! No your can read it all for yourself. "An Early History of Pony" => https://www.ponylang.org/blog/2017/05/an-early-history-of-pony/
endformationage has joined #ponylang
Matthias247 has joined #ponylang
<endformationage> doublec: Thanks for taking a look. An updated version: http://pony-playpen.lietar.net/?gist=8f2949d3b8291f40f6e0f3ddf2b25387
<endformationage> I realize the example it a bit convoluted, but it mirrors something I was attempting.
<endformationage> The primitives GetPear and GetApple are just an easy way to get a specific promised fruit. Idealy they'd have other helper functions defined on them.
<endformationage> When they're applied, they create an intermediary specializing on the fruit type they promise, and (hopefully) send themselves along to it.
<endformationage> The intermediary holds the primitive that made it, as well as a promise that'll be fulfilled by a processor after it's applied (or passed to the processor, seen I can't figure out how to consume itself to it).
<endformationage> The intermediary can accept promise handlers, which it just forwards to the promise it holds.
<endformationage> A PromiseProcessor just looks at the type the intermediary specializes on, and fulfills its promise with an object of that type.
<endformationage> In main, I attempt to get a pear and an apple. Each request looks like the following..
<endformationage> Apply the primitive responsible for promising the fruit, get back an intermediary specializing in that fruit.
<endformationage> Pass a fulfillment handler to the intermediary, in this case something that'll print out what kind of pear or apple was recieved.
graaff has quit [Quit: Leaving]
<endformationage> Finally, apply the intermediary with the processor (or since I couldn't get this to work, pass it to the processor) to let thing play out.
<endformationage> The error at this point ( http://pony-playpen.lietar.net/?gist=8f2949d3b8291f40f6e0f3ddf2b25387 ) I think tells me generics behave more strictly than I anticipated.
<endformationage> FruitResultIntermediary[Pear val] iso has different type arguments than FruitResultIntermediary[Fruit val] iso
<endformationage> I had thought since Pear is Fruit traited, this would be OK.
<endformationage> On a side note, with `argument not a subtype of parameter` errors, I have a difficult time easily seeing the types of the argument vs parameter.
<endformationage> I think the compiler could be more explicit in its info statements.
<endformationage> SeanTAllen: FWIW, I feel reading through Pony's Tutorial, viewing related videos, etc, has provided me a more solid base understanding of concurancy's challenges than my previous attempts in understanding it via random libs, etc that attempt to solve one of those challenges.
<endformationage> Perhaps it's the general actor/rcaps context that has made it more solid for me. They kind of bring the challenges to the forefront to be seen. Literally you cannot miss them.
<SeanTAllen> endformationage: there's a section of the website that i intend to be a guided "how to learn" pony... https://www.ponylang.org/learn/
<SeanTAllen> i'd love input from folks who have gone through the learning process lately in terms of additional content that was handy. suggestions on how to approach etc.
<SeanTAllen> if you have any, please email me.
<endformationage> SeanTAllen: OK. I did go through each suggested resource regarding rcaps after I did the tutorial and patterns, and did find them useful.
<SeanTAllen> sweet
obadz has quit [Ping timeout: 240 seconds]
obadz has joined #ponylang
smoon has quit [Quit: smoon]
<endformationage> Woo hoo! I can't believe I got it to compile!
smoon has joined #ponylang
<endformationage> My realization was that PromiseProcessor needed to work on an interface to a FruitResultIntermediary.
<endformationage> I was trying to work on a generalized FruitResultIntermediary that was at that point specialized to a Fruit.
<endformationage> I gained a bit better understanding of how/when to type a parameter as a trait/interface vs 'concrete' type.
plietar has quit [Remote host closed the connection]
plietar has joined #ponylang
<endformationage> I made the mistake of originally typing the param as FruitResultIntermediary[Fruit], thinking it was not concrete at that point.
<endformationage> Like as if it were a slightly more specialized generic.
plietar has quit [Ping timeout: 240 seconds]
plietar has joined #ponylang
papey_lap has quit [Ping timeout: 260 seconds]
Matthias247 has quit [Read error: Connection reset by peer]