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
<SeanTAllen> vaninwagen: it used to catch that, it did when i wrote it. can you give an example of something that isnt being caught by it
<autodidaddict> Sean - working on the PR for match iter
<SeanTAllen> nice
endformationage has quit [Quit: WeeChat 1.7]
<autodidaddict> yay, the automated builds pass! :) I honestly didn't expect that
<SeanTAllen> of?
<SeanTAllen> o!
<SeanTAllen> @autodidaddict : can you redo the commit comment and title for your PR
<SeanTAllen> what you have in the title will appear as the CHANGELOG entry so if you can shorten that down
<SeanTAllen> and add details for what it is to the body of the commit (ideally including link to RFC) that would be awesome
<SeanTAllen> you'd want to do a git amend to make the change to the commit body (as GitHub doesn't pick that up)
<SeanTAllen> title as well
<SeanTAllen> but then you'll need to also change the title in GitHub because ¯\_(ツ)_/¯
<SeanTAllen> after you do amend
<SeanTAllen> you'd want to force push
<autodidaddict> OK I'll see what I can do
<SeanTAllen> are you familiar with how to do that?
<autodidaddict> Not in the least 😀😎
<SeanTAllen> go to your repo
<SeanTAllen> get on the branch
<SeanTAllen> type
<SeanTAllen> git commit --amend
<SeanTAllen> that will change your last commit message
<SeanTAllen> when you are done with that
<SeanTAllen> git push --force-with-lease
<SeanTAllen> then update the title in the PR in GitHub because well, GitHub could do a better job with that
<SeanTAllen> Something like...
<SeanTAllen> Add regex match iterator
<SeanTAllen> or something like that
<SeanTAllen> is a good CHANGELOG entry
<SeanTAllen> I added the "CHANGELOG - added" label to your PR
<SeanTAllen> we hvae a bot that runs and will add it to the CHANGELOG when merged because of that label
<autodidaddict> Done
<SeanTAllen> autodidaddict: did you add this via GitHub or git? "Adding match iterator functionality from Issue 2093, RFC 044"
<autodidaddict> I did git amend like you said
<SeanTAllen> odd how github displays. thanks.
<SeanTAllen> autodidaddict: PR looks pretty good couple tiny comments
<autodidaddict> I've addressed them
<SeanTAllen> you are quick
<SeanTAllen> you using irc cloud now?
<autodidaddict> yes
<SeanTAllen> i see a name... "Kevin"
<autodidaddict> That's me
autodidaddict has quit [Quit: Updating details, brb]
autodidaddict has joined #ponylang
bimawa1 has quit [Read error: Connection reset by peer]
aceluck has joined #ponylang
_whitelogger has joined #ponylang
bimawa1 has joined #ponylang
m6w6 has quit [Read error: Connection reset by peer]
m6w6_ has joined #ponylang
m6w6_ is now known as m6w6
<aceluck> I hit an assertion in the compiler again - not sure if it's the same one as previously: https://playground.ponylang.org/?gist=60297f95c877c8b93532b6010b88576a
<aceluck> (the error in the code being that Int is not defined)
bitcrusher1 has quit [Ping timeout: 260 seconds]
Matthias247 has joined #ponylang
<SeanTAllen> aceluck: can you open an issue for that. you have invalid code there but its not handled correctly.
<SeanTAllen> this is the correct version aceluck: https://playground.ponylang.org/?gist=9e6876bdd00b53b7dbfd347b56600b4e
<SeanTAllen> actually i can open the issue
<SeanTAllen> also aceluck, are you aware of the the "iftype" expression. it appears you are merely checking the type, in which case, you can use "iftype"
<SeanTAllen> actually sorry those aren't subtypes wouldnt work there
Matthias247 has quit [Read error: Connection reset by peer]
<aceluck> I wasn't aware of iftype - thanks that's helpful
<SeanTAllen> it doesnt help you here though. i was tired when i suggested it could. you want the updated gist i sent.
<aceluck> It's useful for other stuff though, and I wasn't aware of it.
<aceluck> I'm wondering about this though - I have a union type T is (X | Y | Z)
<aceluck> If X, Y and Z all are HasEq , how would I check if two variables of type T are eq ?
<aceluck> I'm trying to figure out the idiomatic way to do it. So far the best I could do is pattern match each T on each of the types with capture, and then do eq on the captured variables
<SeanTAllen> well being HasEq doesn't mean that equality makes sense for them. Even being in the union type doesn't either.
<SeanTAllen> Its an interesting problem, one i haven't thought about, because its never come up for me
<SeanTAllen> I'm interested to see what you come up with.
<aceluck> I'm porting some code from Scheme, where (since it's dynamically typed) you can compare apples and oranges basically
<aceluck> Which is fine, because (= apple orange) should return false
<aceluck> But if it happens to be two apples, you want to compare for equality
<aceluck> The types aren't known statically though... so I suppose it would require some magic "cast a to the type of b so I can == them"
<aceluck> On the other hand, it's not a big deal to write a pattern match in code though, since I know what the set of X Y Z will be.
<SeanTAllen> you can do that with 2 match statements
<SeanTAllen> that is currently what i do
<SeanTAllen> but
<SeanTAllen> there are probably better way
<SeanTAllen> i think the best way would be case methods
<SeanTAllen> but they need some love
_whitelogger has joined #ponylang
Praetonus has joined #ponylang
<SeanTAllen> aceluck: what are you trying to do?
<SeanTAllen> are you trying to do an equality check between two items?
<SeanTAllen> that would be
<SeanTAllen> actually not sure what you are trying to do, so....
mdcox has joined #ponylang
Matthias247 has joined #ponylang
plietar has joined #ponylang
endformationage has joined #ponylang
amclain has joined #ponylang
dom96 has quit [Changing host]
dom96 has joined #ponylang
Praetonus has quit [Quit: Leaving]
vaninwagen has joined #ponylang
deep-book-gk_ has joined #ponylang
deep-book-gk_ has left #ponylang [#ponylang]
<aceluck> Yes, equality check between to items - but they're of union type
<autodidaddict> is there an easy syntax for taking the head and tail of an array? For example, in some languages I can do things like arr[0] and arr[1...] which will give the first and then "all remaining" elements
<autodidaddict> I know I can create a new array with a for loop iterating on the first and skipping the 0 element, but it feels like this should be a simpler syntax
<autodidaddict> for example, in Rust: `let (head, tail) = v.split_at(1);`
<SeanTAllen> aceluck: i'm unclear why being of a union type matters.
<autodidaddict> splits a vector at index 1
<aceluck> SeanTAllen: Well, if I do x == y the compiler bails, and the same if I do match x | y => ... end
<SeanTAllen> autodidaddict: no. seems like a useful addition to being able to do on a seq.
<SeanTAllen> aceluck
<SeanTAllen> so you want to know if they are of the same type and then if they are equal, correct?
<vaninwagen> autodidaddict what about Array.slice https://stdlib.ponylang.org/builtin-Array/#slice with first arg 1?
<aceluck> SeanTAllen: I can get it to work in two steps, by first matching on type, and then doing the equality check
<autodidaddict> SeanTAllen: absolutely. Head/tail split and match is a staple
<SeanTAllen> autodidaddict: you could pop the first element and then what is left is the "rest"
<SeanTAllen> but that isnt really what you want i think
<aceluck> SeanTAllen: Correct. Or if possible define equality to return true if the types aren't the same
<SeanTAllen> i'd suggest an RFC autodidaddict
<SeanTAllen> mostly to discuss when it is added to Seq, what the impact on other classes, existing methods etc should be
<SeanTAllen> aceluck: that isn't going to happen
<SeanTAllen> the compiler isnt going to let you compare a Foo and a Bar for equality
<autodidaddict> slice will do what I want for now.. but yeah, head/tail on Seq would be beneficial, especially when doing recursion
<aceluck> autodidaddict: If you use List instead of vector you have .head and .tail
<SeanTAllen> autodidaddict: there's a desire to take a look at seq, readseq et al and clean it all up. if someone who has time were to do an RFC to drive that forward, build feedback etc, they would be hailed as a hero. just sayin.
<vaninwagen> SeanTAllen nevermind about the docgen stuff from yesterday, i figured it out (i hope) :) https://github.com/ponylang/ponyc/pull/2112/files#diff-c29e57cb595d8cf1c76c256432f2e627R125
<SeanTAllen> i can see your problem, aceluck. i finally get it. this is... interesting.
<SeanTAllen> vaninwagen: awesome
<aceluck> SeanTAllen: I get why the compiler won't simply allow == as you're comparing apples and oranges. So I was wondering if there's an idiomatic way to do it.
<SeanTAllen> what you want to say is...
<SeanTAllen> if A and B things are comparable, please compare them
<aceluck> In my case the union type has 8 members so it ends up being a big match statement.
<aceluck> But again, it's not a big problem either , because I just have to write it once, and then I'm done, so
<SeanTAllen> still
<SeanTAllen> there feels like there should be a way to do this.
<SeanTAllen> i don't have a good answer.
CcxWrk has quit [Ping timeout: 240 seconds]
<autodidaddict> ugh. every. single. time. " let remainder = parts.slice(1, parts.size())" iso! is not subcap of box
<SeanTAllen> can i suggest opening an issue against the RFC repo that shows the problem?
<SeanTAllen> aceluck: ^
<aceluck> It would be nice.... Like in my gist I'm matching a with b , both being the same string, but it fails because a and b are type T is (String| something else |....)
<SeanTAllen> It took be about 5 times looking at your problem to understand what the problem was
<aceluck> SeanTAllen: Yes I can do that
<aceluck> SeanTAllen: Hehe, all right I'll write it out properly
<SeanTAllen> so if you open an issue, i'd suggest explaining the "I know its a T but not the type of T, but I should be able to compare them"...
<SeanTAllen> I dont think there is an easy to do this in Pony
<SeanTAllen> but with all the usage of Union types it feels like there should be a way
<SeanTAllen> an RFC issue is a good way to get some discussion
<SeanTAllen> that could lead to an RFC
<SeanTAllen> autodidaddict: i'm going back to practicing french. i'll pop in in a while to make sure you havent hit any more snags.
<autodidaddict> I'm already snagged
<autodidaddict> :(
<autodidaddict> I can't assign the results of a .slice() to a new variable
<aceluck> SeanTAllen: Thanks again
<vaninwagen> autodidaddict, i feel you! good-old pony-problems :)
<vaninwagen> slice will give you an array of this->A! instead of A - i guess the same will happen when calling .tail() on some Seq
<autodidaddict> but remainder is a brand new variable, so it shouldn't matter what slice gives me back
<vaninwagen> autodidaddict parts is an alias of an iso array - so it is Array[String val] tag
<vaninwagen> and slice needs parts to be a box at least
<autodidaddict> it's moments like this that actually make me _miss_ Rust's "lenient" borrow checker
<autodidaddict> with Rust, I just have to figure out "move or borrow" ... Pony has a 255x255 matrix of possibilities
<vaninwagen> yeah, sometimes it is too deep for me too - being on ballmer peak helps a lot, at least for me
<autodidaddict> so how do temporarily make parts a box so I can slice it?
<vaninwagen> autodidaddict i fear you can't if you need to keep an iso around. otherwise just consume the variable you took the alias ``parts`` from
<autodidaddict> why do I need to keep an iso around?
<autodidaddict> I just have `let parts = cmd.split_by(" ")`
<autodidaddict> and I'm going to be done with that thing once I get the head and tail
<vaninwagen> cmd is a String?
<autodidaddict> yes
<vaninwagen> autodidaddict ah yes, https://stdlib.ponylang.org/builtin-String/#split_by gives you an iso array
<autodidaddict> you say that as though that's enlightening to me :)
<autodidaddict> what do I need to do to this iso array in order to be able to slice it?
<vaninwagen> yeah, actually, still puzzles me
<autodidaddict> conversations like this will absolutely discourage newbs from this language
<vaninwagen> you could recover it to box maybe: ``let parts: Array[String val] box = recover box cmd.split_by(" ") end``
Matthias247 has quit [Read error: Connection reset by peer]
<autodidaddict> that got me past that
<autodidaddict> but now I can't pass remainder as an array to a behavior
<autodidaddict> joy
<autodidaddict> Array[String val] tag is not a subtype of Array[String val] val
<vaninwagen> autodidaddict i am sorry to disappoint, maybe you better wait for SeanTAllen to be back instead of listening to me, also just a noob
<autodidaddict> the recover trick worked.. which is good
<vaninwagen> if you would have a slightly more complete code example, maybe i could help you better
<autodidaddict> but now I can't seem to convert remainder to an Array[String] val
<vaninwagen> you could also recover to a val above when doing split_by (i guess from the info i have)
<vaninwagen> as you can pass a val when a box is expected (afaik (big fat noob-disclaimer))
<autodidaddict> a val is expected
<autodidaddict> and I have a box
<autodidaddict> so I now have:
<autodidaddict> and ch "handle_verb" is what's failing the type check on remainder... ch handle_verb is ` be handle_verb(verb: String val, params: Array[String] val)`
<autodidaddict> woops, there's an extraneous "end" in the let remainder line
<vaninwagen> you could try: let parts: Array[String val] val = recover val cmd.split_by(" ") end
<vaninwagen> as first line
<autodidaddict> and the error is:
<autodidaddict> so, it looks like my remainder variable is a ref and I need to convert it to a val
<SeanTAllen> So slice
<vaninwagen> SeanTAllen to the rescue :)
<autodidaddict> If SeanTAllen gets hit by a bus, no one will ever learn Pony
<vaninwagen> autodidaddict you can recover this as well to a val
<SeanTAllen> there's jemc and praetonus amongst others
<vaninwagen> let remainder = recover val parts.slice(1, parts.size()) end
<autodidaddict> I also cannot do `recover val remainder` when sending
<SeanTAllen> let me see if i understand
<SeanTAllen> `ch.handle_verb(verb, remainder) `
<autodidaddict> ` be handle_verb(verb: String val, params: Array[String] val)`
<SeanTAllen> verb is supposed to be an immutable array of Strings?
<SeanTAllen> ah ok
<autodidaddict> this is my head/tail
<SeanTAllen> why is parts "box"?
<autodidaddict> because I had to make it a box in order to be able to invoke slice
<SeanTAllen> no
<SeanTAllen> let parts: Array[String val] val = cmd.split_by(" ")
<SeanTAllen> try that
<autodidaddict> that's what I had before
* autodidaddict flips tables
<autodidaddict> reverting
* vaninwagen takes all the blame
<SeanTAllen> here's a good thing to remember
<SeanTAllen> you probably never ever want to type "box"
<SeanTAllen> think of box as "val or ref"
<SeanTAllen> and in code like that
<autodidaddict> this is my first error
<SeanTAllen> you probably want one of them not the other
<SeanTAllen> easy peasy autodidaddict
<SeanTAllen> let remainder = recover val parts.slice(1, parts.size()) end
<SeanTAllen> NOW you can recover that slice to a val
<SeanTAllen> because... parts is a val
<SeanTAllen> so this is safe
<autodidaddict> ok, that worked
<autodidaddict> and as usual, I have absolutely no idea why
<SeanTAllen> which part has you at "i dont know why"
<SeanTAllen> lets try talking to taht for a moment
<autodidaddict> all of it
<SeanTAllen> before i go back to french
<autodidaddict> when I'm supposed to convert crap to a val
<autodidaddict> when I'm supposed to recover things
<SeanTAllen> well, "all of it" doesnt give me much direction
<SeanTAllen> well you convert it to val when you need a val
<SeanTAllen> you need a val because you want to send to another actor
<autodidaddict> and since I can't hover over anything (I know, I know, read the damn source), I don't know what the return value of stuff is until I accidentally violate refcaps
<autodidaddict> yeah, I know because I wrote that actor
<SeanTAllen> and that flows backwards up the chain.
<autodidaddict> but asking an array for a slice ... the refcaps there are confusing AF
<SeanTAllen> i know, im not trying to talk down to you
<SeanTAllen> it straightforward, but also confusing until it clicks
<SeanTAllen> so i suspect that...
<autodidaddict> it's straightforward because you already know it
<autodidaddict> I'd bet every dollar I have it's not straightforward to _any_ new learner
<autodidaddict> I'm just trying to figure out how I would explain this to someone on my team as I'm teaching them
<autodidaddict> and I can't.
<autodidaddict> not yet
<SeanTAllen> i mean its straightforward in that...
<SeanTAllen> i need to send this to another actor so i need a sendable thing
<SeanTAllen> is straightforward
<autodidaddict> that's the easy part, and I knew that
<SeanTAllen> and what flows from that is straightforward
<SeanTAllen> but it has to click with the "how do i actually do that"
<autodidaddict> how to get from the result of split_by to the result of slice to that val is what's difficult
<SeanTAllen> im not sure i know what you mean, can you state that in other way
<vaninwagen> autodidaddict maybe i can chime in with some more confusion as i am also still a new learner - but i think i got that one (and also had tons of problems like these)
<SeanTAllen> i have a feeling if i can help answer this question it might help your understanding move forward a little
<autodidaddict> it's just super high friction. In other languages I can just take what I get from one function call and pass it to another. Having my compilation break between every two function invocations is maddening
<autodidaddict> I never thought I'd say this, but this is higher friction than Rust
<autodidaddict> and Rust's learning curve made me want to jump out a window
<autodidaddict> someday, when I can "think in Pony" this won't be much of an issue
<autodidaddict> maybe it's because I routinely work in 4 different languages so I don't "think natively" in any one of them, which might be increasing my impedance mismatch
<SeanTAllen> so the only problem you had with: let parts: Array[String val] val = cmd.split_by(" ")
<SeanTAllen> was the missing val
<SeanTAllen> to say "i want an immutable array from this"
<autodidaddict> and then `recover val` on slice
<SeanTAllen> Array[String val] means "a mutable array of immutable strings"
<autodidaddict> recover is supposed to be "lift" but "recover val" feels like it should be a consume
<SeanTAllen> because its class Array rather than class val Array
<SeanTAllen> did that part make sense so far autodidaddict ?
<autodidaddict> yeah, I already knew those parts
<SeanTAllen> ok good. i dont want to accidentally skip over anyhting
<SeanTAllen> so this...
<SeanTAllen> let remainder = recover val parts.slice(1, parts.size()) end
<SeanTAllen> that's the part you are stuck on right now yes?
<autodidaddict> "recover val" feels weird to me. Like I said, getting a val from a ref feels like it should be a consume
<SeanTAllen> im not sure what that means.
<SeanTAllen> so you understand why you can `recover val` there to get an immutable array? but think the terminology should be different?
<autodidaddict> when you read the docs, it is explained as though "recover" is to lift capability, whereas consume is to downgrade capability
<SeanTAllen> that isnt what consume is
<SeanTAllen> consume is destroying an alias
<autodidaddict> yeah, the impression I came away with after reading docs was that recover and consume are opposites, one goes "up" the other goes "down"
<SeanTAllen> hmmm
<SeanTAllen> if you arent alone in that, it sounds like that part of the tutorial needs a rewrite
<autodidaddict> the docs (if I remember right) do _not_ mention that recover is for lifting or lowering
<autodidaddict> after reading the docs, I got the impression I could recover a val to a ref, but would have to consume to go from ref to val
<autodidaddict> but that could just be my own derpiness and the docs are fine
<SeanTAllen> well
<SeanTAllen> you are an author like me
<SeanTAllen> so i think we probably both agree that a well meaning person gets the wrong impression from the docs, that the docs aren't good enough.
<SeanTAllen> and could use improvement.
<SeanTAllen> so, do you want to talk about recover for a moment?
<autodidaddict> sure
<SeanTAllen> i'm not a big fan of the "lift" explaination
<SeanTAllen> it didnt reasonate with me
<autodidaddict> I think lift is confusing
<SeanTAllen> the way i always think about recover is it is a...
<SeanTAllen> hmmm how to put this
<SeanTAllen> its a "zone" where you can do things and then get something different
<SeanTAllen> that doesnt make much sense
<SeanTAllen> lets take your recover though
<SeanTAllen> `parts.slice(1, parts.size()) `
<SeanTAllen> this returns an Array ref
<autodidaddict> I thought of recover as a "protected scope" where you could change refcaps
<SeanTAllen> recover allows me to wrap a bunch of code up as an expression and say
<SeanTAllen> "i want to change the ref cap of this expression"
<SeanTAllen> and that is ok because,
<SeanTAllen> i didnt use anyhting from outside this magic box
<SeanTAllen> so no aliases could escape
<autodidaddict> yeah, that's why I've been thinking of it as a protected scope
<SeanTAllen> and this is why
<SeanTAllen> you cant reference a "ref" from outside the scope
<SeanTAllen> but can a "val"
<SeanTAllen> because it doesnt violate that basic idea
<SeanTAllen> that is the explanation that works and reasonates for me
<autodidaddict> so if I produce something within the recover block (e.g. a ref array), I can allow that array to leave the protected block as a val
<SeanTAllen> i explained that to john mumm once when we were discussing how to explain to other people and he looked at me like i had 2 heads.
<SeanTAllen> yeah
<autodidaddict> I'll stew on that for a while and see if I don't have some potential PR suggestions for the tutorial to help clarify... or at the very least make sure people don't think of recover and consume as opposites
<autodidaddict> that really derailed me
<SeanTAllen> like i said, i think the ideas are straightforward once they click
<vaninwagen> and my (horrible) suggestion for `parts` being a box earlier lead to another error in the recover for `remainder`, as referencing a box from a recover expr is not safe
<autodidaddict> oh wow.. some of that just clicked. It's why I can't use mutable fields from an object inside a recover block to make them immutable
<autodidaddict> !
<autodidaddict> :lightbulb:
<SeanTAllen> i think the problem is we dont have good explanations that click with everyone
<SeanTAllen> or even in some places click with anyone
<SeanTAllen> for me personally, i think the ideas are easier to work with than Rust's borrow checker
<SeanTAllen> but...
<SeanTAllen> we still are really hurting for good explanations that reasonate with large numbers of people
<autodidaddict> depends on what's being checked ;) Rust's "move vs borrow" semantic is easier to follow than refcaps, but refcaps don't have the annoying 'a 'b 'c lifetime specifiers
<autodidaddict> those things annoy me
<SeanTAllen> liek i said "for me personally"
<SeanTAllen> other folks brains work differently
<autodidaddict> no way, all brains must be identical. all learning must be done the same way
<autodidaddict> ;)
<autodidaddict> good news is you can now log into the mud and type "look" and see the description of the room you're in
<autodidaddict> all without making a single blocking call
<autodidaddict> oh, here's a recover question...
<autodidaddict> why do I have to recover every time I pass a partial application to a promise.next() ?
<autodidaddict> p.next[None](recover this~exroom() end)
<autodidaddict> is it because the partially applied function needs to be passed as a val and it doesn't default to a val?
<SeanTAllen> let me go look at type signatures
<autodidaddict> :troll: if you could hover-over the function, you wouldn't have to search github
<SeanTAllen> i dont search github
<SeanTAllen> i will be very happy when someone builds a LSP server
<SeanTAllen> i have zero desire to spend my free time on that
<SeanTAllen> i know because i tried
<SeanTAllen> and decided that i did not want to do that
<autodidaddict> if I knew how to answer the questions an LSP server needs to answer, e.g. autocomplete, I would do it. LSP server sounds fun to me
<vaninwagen> autodidaddict, the tutorial says "That means partial application results in an anonymous class and returns a ref."
<SeanTAllen> i can help you if you deccide to give it a go autodidaddict
<SeanTAllen> ok so what is... `this~exroom() ` autodidaddict ?
<autodidaddict> a behavior on my actor
<SeanTAllen> me rarely uses partial application
<SeanTAllen> becuase well it makes no sense in our codebase
<SeanTAllen> anyway...
<autodidaddict> i'm using promises like a mofo ... so I'm using partial apply everywhere
<SeanTAllen> so if that returns a ref, then you need the recover to get back something from inside the magical box that you need
<SeanTAllen> in the case of next...
<SeanTAllen> it wants an `iso`
<autodidaddict> exroom is a behavior, it returns nothing
<SeanTAllen> yes
<SeanTAllen> but you arent return the behavior
<SeanTAllen> you are returning an anonymous class
<SeanTAllen> that is a ref
<autodidaddict> I'm returning an anonymous class ref... got it
<SeanTAllen> honestly i didnt know that
<SeanTAllen> thanks vaninwagen
<SeanTAllen> you saved me a lot of looking stuff up
<autodidaddict> yea that's good to know
<SeanTAllen> but once he told me that
<SeanTAllen> and i saw the signature to next() i knew
<vaninwagen> also a first for me, there's a lot to learn in this conversation :)
<SeanTAllen> unrelated but woo-hoo
<SeanTAllen> homebrew merged the 0.16.1 PR
<autodidaddict> sweet
<autodidaddict> thanks everybody in this channel for all your patience
<autodidaddict> I hate being "that guy" that's always asking dumb question
<SeanTAllen> autodidaddict: its fine and expected
<vaninwagen> it helped me a great deal :)
<SeanTAllen> you are enthuastic, polite, understanding.
<SeanTAllen> anyone who complains about helping you is an ass.
<autodidaddict> I can't wait to get into the combat system where I can try out some of the cooler parts of Pony syntax :)
<SeanTAllen> watching you run around doing stuff in the community puts a giant smile on my face and makes me feel like the work i've poured into a labor of love is worth it
<SeanTAllen> same applies to you vaninwagen
<autodidaddict> 🍺
<SeanTAllen> i get excited when new people come, i get even more excited when they stick around
<SeanTAllen> and sometimes i get sad when they float away
<vaninwagen> autodidaddict keep the math package as a special bonbon for exploring in combat mode :)
<autodidaddict> D&D style combat math is pretty low tech, and I already wrote a library that parses expressions like "3d10+5" for rolling hit dice ;)
<vaninwagen> i meant the stdlib math package
<autodidaddict> yeah, I'm just saying I probably won't exercise much more than simple add and multiply
<SeanTAllen> Pony 0.16.1 has been released. It has a couple high priority bug fixes so if you've already upgraded to 0.16.0, upgrading to 0.16.1 is highly advised: https://www.ponylang.org/blog/2017/07/0.16.1-released/. If you haven't upgraded to 0.16.0, check out the release notes for it first to make sure you know what you are getting yourself into. https://www.ponylang.org/blog/2017/07/0.16.0-released/
<autodidaddict> upgraded
<vaninwagen> ٩(ˊᗜˋ*)و
<SeanTAllen> omg
<SeanTAllen> i need a keyboard shortcut for that
<SeanTAllen> ٩(ˊᗜˋ*)و
<SeanTAllen> ٩(ˊᗜˋ*)و
<SeanTAllen> perfect
<SeanTAllen> thanks vaninwagen
<SeanTAllen> now i have ¯\_(ツ)_/¯, ᕕ( ᐛ )ᕗ, and ٩(ˊᗜˋ*)و to express my emotions
<SeanTAllen> ok
<SeanTAllen> back to the french
<autodidaddict> I'm working on Mandarin. Scratch that, I'm procrastinating working on Mandarin
<vaninwagen> i love the second one
<autodidaddict> ᕕ( ᐛ )ᕗ is awesome
<autodidaddict> I need to make my phone keyboard autocorrect that
<autodidaddict> I think I'll go do that instead of studying
<SeanTAllen> my phone autocorrect lol to https://www.youtube.com/watch?v=FdghRwWfaOQ
<SeanTAllen> so do most apps on my computer
deep-book-gk_ has joined #ponylang
<SeanTAllen> my brain my be frenched out
deep-book-gk_ has left #ponylang [#ponylang]
<autodidaddict> one might say your brain is...
<autodidaddict> french fried
<autodidaddict> (•_•) / ( •_•)>⌐■-■ / (⌐■_■)
<autodidaddict> yeaaaaah
vaninwagen has quit [Ping timeout: 240 seconds]
<SeanTAllen> that was an awful dad joke kevin. awful awful.
<autodidaddict> thank you
<SeanTAllen> you're welcome
<endformationage> kamilchm, never letting nixpkgs ponyc get more that a few hours old. :)
<SeanTAllen> woo hoo!
aceluck has quit [Remote host closed the connection]
aceluck has joined #ponylang
aceluck has quit [Ping timeout: 240 seconds]
<autodidaddict> added 2 lines of code, stuck in refcap hell again.
<autodidaddict> ugh
<autodidaddict> A recover expression let's you "lift" the reference capability of the result. A mutable reference capability (iso, trn, or ref) can become any reference capability, and an immutable reference capability (val or box) can become any immutable or opaque reference capability.
<autodidaddict> this is from the docs. This paragraph doesn't mention recovering -to- a val at all
<autodidaddict> well, it does, but it's subtext, not explicit
<SeanTAllen> what two lines have you stuck autodidaddict ?
<autodidaddict> I want to add the ability for the ActorStorage trait default implementation to expose its contents as a val array
<autodidaddict> it's stored as a mutable Array[Any tag]
<autodidaddict> and I want `allitems(): Array[Any tag] val`
<autodidaddict> right now I'm writing a for loop with .append() inside a recover block
<autodidaddict> and that feels dumb to me
<autodidaddict> none of the usual "recover val" tricks worked
<doublec> if Array[Any tag] is a ref, you can't return it as a val, alas.
<SeanTAllen> so you want to make a copy of the contents and return as immutable autodidaddict ?
<autodidaddict> yes
<autodidaddict> copying actor tags should be "cheap", I assume
<SeanTAllen> there's no "make a immutable clone of this" for reasons that jemc is better at than explaining than i
<autodidaddict> .clone() doesn't actually clone, since I get an array with references to the original elements
<SeanTAllen> you want to loop over your array and add the items to a new list
<SeanTAllen> you can use a tran or iso for that
<SeanTAllen> do you want me to do up a little bit of code to demonstrate?
<autodidaddict> I'll show you what I just tried (and failed) :)
<SeanTAllen> ok
<autodidaddict> this doesn't work because I'm looping over my Array[Any tag] ref
<SeanTAllen> right
<SeanTAllen> hold on
<autodidaddict> storage is let _storage: Array[Any tag]
<SeanTAllen> here ya go
<autodidaddict> ooookay
<autodidaddict> :think
<autodidaddict> :think:
<autodidaddict> it would never have occurred to me to use a trn (docs actually say you rarely ever need this explicitly)
<SeanTAllen> you could also use an iso
ada[m] has quit [Ping timeout: 246 seconds]
katafrakt[m] has quit [Ping timeout: 255 seconds]
srenatus[m] has quit [Ping timeout: 255 seconds]
<autodidaddict> consuming a trn always results in val ?
dtz has quit [Ping timeout: 276 seconds]
M-hrjet has quit [Ping timeout: 276 seconds]
mindB has quit [Ping timeout: 246 seconds]
irx[m] has quit [Ping timeout: 246 seconds]
<autodidaddict> also just realized why I can't iterage over storage.values() inside the recover block. Same reason I can't access the value at all
endformationage has quit [Quit: WeeChat 1.7]
<SeanTAllen> technically no "tran" isnt only limited to val
<autodidaddict> so how is `consume (something trn)` deterministic?
<autodidaddict> if it doesn't always result in a val?
<SeanTAllen> its the only useful one though
<doublec> I've always used iso in those cases. I'm not sure when trn is preferred over iso or vice versa.
<SeanTAllen> trn is preferred if you need to pass it from one method to another
<SeanTAllen> in a fashion that iso would be a pain in the ass for
<doublec> ah true
<SeanTAllen> autodidaddict: i dont understand your deterministic question...
<autodidaddict> you said consuming a trn doesn't always result in val
<doublec> autodidaddict: I assume "consume trn" results in a trn! which is then converable to whatever is needed on the lhs based on subtyping rules.
<SeanTAllen> ok let me change that
<doublec> s/trn!/trn^/
<autodidaddict> if it's not always, how do I predict
<SeanTAllen> yes
<SeanTAllen> by your return type
<SeanTAllen> the only useful one really is val
<SeanTAllen> if you made the reutrn type
<SeanTAllen> `fun allitems(): Array[Any tag] tag =>`
<SeanTAllen> it would reutrn a tag to the thing
<SeanTAllen> but in this case, thats pretty useless
<autodidaddict> hmm.. so trn doesn't become something useful until it needs to be aliased
<autodidaddict> how very quantum
<SeanTAllen> i tried to give you the "true" answer
<SeanTAllen> i think i should have stuck to the "helpful" answer for now
<doublec> autodidaddict: when you consume something, you destroy the alias. The result of a consume is an ephemeral capability (the ^ marker at the end)
<doublec> autodidaddict: there are subtyping rules for what that can be assigned to
<autodidaddict> yeah.. I've memorized the "destroy an alias" bit.. I just haven't internalized what to consume, when, and why
<autodidaddict> the plush "bloated pony" doll should come with a laminated refcaps cheat sheet card
<SeanTAllen> ha
<SeanTAllen> think of consume as "the highlander"
<SeanTAllen> there can only be 1
<autodidaddict> I thought that was iso
<SeanTAllen> this could turn out to be a very bad analogy
<doublec> Indeed. When you want another one you have to kill the other.
<SeanTAllen> ok so if i return an iso without consuming it
<SeanTAllen> it would be a iso!
<SeanTAllen> that is an alias to an iso
<autodidaddict> I didn't think you could alias an iso
<SeanTAllen> and that is bad and violates our highlander goal
<autodidaddict> I thought it by definition required 1 alias only
<SeanTAllen> yes
<SeanTAllen> that is why if you try to return an iso without consuming it
<SeanTAllen> you get a iso!
<SeanTAllen> because you just created an alias to it
<doublec> autodidaddict: if you look at https://tutorial.ponylang.org/capabilities/capability-subtyping.html you see the only thing an iso! can be assigned to is a tag.
<autodidaddict> doublec: I re-read that page every 2-3 days :(
<SeanTAllen> btw autodidaddict you are now into very deep voodoo land that you probably wont need for a long time if everr
<SeanTAllen> so, if your head spins some dont worry
<doublec> autodidaddict: I think it's better to gain an intuitive understanding of rcaps and then map that to that page/tables when you have that down.
<SeanTAllen> sylvan loves that table
<autodidaddict> SeanTAllen: what do you mean "what need for a long time" ?
<SeanTAllen> i hate it
<SeanTAllen> s/what/will/
<autodidaddict> you saying I'm wasting my learning here because you're all going to change the syntax?
<SeanTAllen> no
<doublec> autodidaddict: we talk about rcaps just clicking at some point. This is the gaining of the intuitive understanding. (ie. understanding aliases and how to convert them)
<SeanTAllen> no one is going to change the rcap syntax autodidaddict
<autodidaddict> yeah. I suspect I'll gain that at some point. In the meantime, I will continue stabbing myself in the eye with a fork
<SeanTAllen> so my early problem autodidaddict
<doublec> SeanTAllen: I love/hate it. I have an intuitive understanding and it helps me understand that page when I read it. Others probably read that page and that gives them the understanding.
<SeanTAllen> was i thought of iso as "there is just one"
<SeanTAllen> and someone it would always stay as one
<SeanTAllen> which was all well and good
<SeanTAllen> when it clicked for me was when i finally grasped that `iso` is about name bindings (aka aliases)
<SeanTAllen> i can only ever have 1 name for an iso.
<SeanTAllen> but names come and go as "the iso" moves around
<SeanTAllen> an iso that comes into a method, is bound to the parameter name
<SeanTAllen> if i want to assign it to a field, i have to consume the parameter name
<SeanTAllen> so i can assign the iso to my field
<SeanTAllen> otherwise there would be two bindings to this thing
<autodidaddict> iso is like a manual Rust move
<SeanTAllen> by the same token, when i return an iso from a method
<autodidaddict> where Rust moves the alias binding for you automatically, Pony makes you consume it to choose when it moves
<SeanTAllen> i have to consume the binding, otherwise there can be more than one binding
<SeanTAllen> my rust is errr rusty
<SeanTAllen> so i cant comment on the analogy
<SeanTAllen> i cant believe i almost typed that without catching the awful pin
<SeanTAllen> pun
<autodidaddict> ;) ok, in rust let a = bob, then let b = a
<autodidaddict> that is automatically consuming a
<autodidaddict> if I refer to a after the b=a line, it won't compile
<SeanTAllen> ah
<SeanTAllen> yes
<autodidaddict> so it's like Rust is generating consumes
<doublec> iso is like Rust 'Unique<T>' I think
<autodidaddict> Unique<T> is quite a bit more complex than just iso
<autodidaddict> it's like a steroidal iso
<autodidaddict> haven't played much with it though since it's only in the nightly toolchain, not stable
<doublec> The main point I guess is that 'iso' management is about managing aliases. If you want to alias it you need to consume it. At that point (you have an iso^) you can assign it to pretty much anything.
<autodidaddict> cool
<SeanTAllen> if i was to write a pony book
<SeanTAllen> i would start with data sharing and concurrency
<SeanTAllen> the problems there in general
<SeanTAllen> how different languages address it
<SeanTAllen> and then i would introduce pony through data sharing patterns and refcaps
<SeanTAllen> some people say that isnt a good approach
<SeanTAllen> i wish i had time to write the book so i could see if they are right or if i am
<autodidaddict> I think you'd need more fundamentals first. the tutorial spends no time on collections - creating or consuming
<doublec> autodidaddict: the problem is collectoins require knowing rcaps well.
<doublec> autodidaddict: so you need to introduce that first.
<autodidaddict> but I agree data sharing and concurrency is a) where Pony shines and b) where the hard bits are
<autodidaddict> doublec: good point
<doublec> autodidaddict: and data shraing/concurrency is why they exist
<doublec> Part of the reason the tutorial is a bit difficult is it's hard to know when to introduce the right concepts.
<SeanTAllen> autodidaddict: note i was talking about a book, not the tutorial.
<SeanTAllen> i think of the tutorial as "pony for the impatient"
<SeanTAllen> the tutorial could use some one to come in and give it lots of regular love and attention.
<SeanTAllen> a Steve Klabnik if you will
irx[m] has joined #ponylang
<autodidaddict> w00t
<autodidaddict> my room code now maintains (and properly exposes) the contents of the room:
<SeanTAllen> nice
<SeanTAllen> nice....
<SeanTAllen> can i stare into the void?
<autodidaddict> the 2 objects are connected players. I'll use the "collector" pattern to ask each of the actors for their names so I can get a pretty list, e.g. "There are 2 players: Bob and Jabober"
<autodidaddict> not yet, you can only glance at it
<SeanTAllen> I WANT TO STARE INTO THE VOID
* autodidaddict codes up the CmdStare actor
<SeanTAllen> I have not watched much sci-fi but the little that i have watched has taught me that if you want to spice up your life, stare into a void
<SeanTAllen> also
<autodidaddict> as long as it's not an abyss
<autodidaddict> because those things stare back
<SeanTAllen> spaceships are remarkably poorly designed
<SeanTAllen> ive been to enough butthole surfers shows that im prepared for any abyss
<autodidaddict> hah
M-hrjet has joined #ponylang
ada[m] has joined #ponylang
mindB has joined #ponylang
srenatus[m] has joined #ponylang
dtz has joined #ponylang
katafrakt[m] has joined #ponylang