rohitpaulk has quit [Remote host closed the connection]
Renich_ has joined #crystal-lang
Renich has quit [Ping timeout: 244 seconds]
Renich_ is now known as Renich
jemc has joined #crystal-lang
sp3ncer has joined #crystal-lang
sp3ncer has quit [Read error: Connection reset by peer]
jemc has quit [Ping timeout: 244 seconds]
doziq has joined #crystal-lang
<FromGitter>
<girng> i wrote a get_argv method that lets me grab commands sent to the executable. like.. port=9300 tickrate=20 name=value etc etc
doziq has quit [Read error: error:1408F10B:SSL routines:ssl3_get_record:wrong version number]
<FromGitter>
<girng> when i was doing some testing with my tickrate value, it got annoying to compile, upload executable to server, then ./runfile. so once i added that get_argv it helps a lot. can just change the value with command line arguments!!
devil_tux has quit [Ping timeout: 246 seconds]
<FromGitter>
<alehander42> is the today AOC nice
<FromGitter>
<yxhuvud> yeah, but probably the most time consuming so far, not counting yesterdays trouble
moei has joined #crystal-lang
ashirase has quit [Ping timeout: 244 seconds]
ashirase has joined #crystal-lang
dannyAAM has joined #crystal-lang
<jokke>
heh yesterday was really something :D
<jokke>
(AoC
<FromGitter>
<yxhuvud> it was fine if you started an hour or two late
<FromGitter>
<j8r> jokke: I've got this for why in Rust we can pass struct by reference ttps://blog.ryanlevick.com/posts/rust-pass-value-or-reference/
<FromGitter>
<ilanusse> @drujensen that solved it, thanks!
go|dfish has joined #crystal-lang
<RX14>
@j8r array cannot be a struct
lvmbdv has quit [Ping timeout: 268 seconds]
<RX14>
it has mutable state like the length
<RX14>
@j8r in swift, Array is just a wrapper for _ArrayBuffer which is a reference type
lvmbdv has joined #crystal-lang
<FromGitter>
<j8r> thanks for clarification RX14
<FromGitter>
<j8r> and why struct can only passed by value is because there is no borrow checker?
<RX14>
you can pass structs by reference in crystal
<RX14>
you just use pointerof
<RX14>
it's *unsafe* because there is no borrow checker
jemc has joined #crystal-lang
<FromGitter>
<spencerwi> This is probably a question that gets asked a lot, but I didn't see a FAQ or anything about it, but:
<FromGitter>
<spencerwi> I know there's the `&.method` syntax for using a method call on an object as a closure (e.g. `numbers.select(&.even?)`), but is there a way to shorthand "I just want to pass each of these into this other function" (e.g. `numbers.map {|num| Foo.do_crazy_math(num)}`)?
<FromGitter>
<asterite> No
<z64>
no, the shorthand only applies the yielded argument as the implicit receiver of whatever call you make. if something else is the receiver (Foo in this case), you must write out the block with `{..}` or `do..end`
<FromGitter>
<alehander42> I guess one can write his own mapFun tho?
<FromGitter>
<spencerwi> Bummer. Is that something where there's a conscientious reason for not having the shorthand?
<FromGitter>
<spencerwi> I tried something like this:
<FromGitter>
<spencerwi> and that'd be really nice...but no dice :\
<FromGitter>
<alehander42> extending Array with mapFun ?
<FromGitter>
<alehander42> i know its possible in ruby, I am not sure about crystal tho
<z64>
yes, you could reopen array and add methods if you wanted
<FromGitter>
<spencerwi> I'm guessing that wouldn't even be the right syntax though, given unified-call-syntax
<FromGitter>
<spencerwi> is there a syntax for method references?
<FromGitter>
<spencerwi> a la `StringUtils::isBlank` in Java
<jemc>
(in Ruby this would be `numbers.map(&Foo.method(:do_it))`)
<FromGitter>
<spencerwi> ah, funky
<FromGitter>
<spencerwi> I think that answers my question though. Thanks!
<jemc>
(that one works because in Ruby, `Foo.method(:do_it)` returns a Proc-like)
<FromGitter>
<spencerwi> it's not the worst thing in the world, unless I'm using really long descriptive names in my block "subjects" (the `|this_thing_here|` part)
<FromGitter>
<spencerwi> I'm not sure what the term for that bit is, but...yeah, you get the idea
<z64>
thats the block arguments
<FromGitter>
<spencerwi> Ah, cool. Anyhow, thanks for answering a question that I'm sure you're probably sick of answering by now
<z64>
no problem at all:)
<FromGitter>
<alehander42> you can also use a macro
<FromGitter>
<alehander42> but no idea if this is idiomatic
<FromGitter>
<alehander42> I am just experimenting with different lang metaprogramming caps these days
<FromGitter>
<spencerwi> Ooh, I always forget there are macros
<FromGitter>
<spencerwi> it's probably a compliment to the language to say I haven't really needed them yet
<RX14>
ideally you wouldn't ever need them :)
<FromGitter>
<ilanusse> Macros are great
<jemc>
(Elixir's sugar for concise lambdas `numbers |> Enum.map(&Foo.function(&1))` is pretty nice, but that's probably because they only have functions and not methods, so they didn't have to worry about a sugar for methods with the block argument as the receiver)
<RX14>
thats not a lambda?
<RX14>
oh nvm
<RX14>
im blind :)
<FromGitter>
<alehander42> in nim we have ufcs, so it doesnt matter if its a function or a method (but on the other hand there is no &.m stuff)
<FromGitter>
<alehander42> i think ruby added some new `>>` stuff for procs
<FromGitter>
<yxhuvud> ah, that was what rx14 pointed out above. Explicit type there seems natural to me, but perhaps some part of the compiler could be smart enough to automatically inline such a proc assuming it isn't something that has been passed around?
<RX14>
@yxhuvud yeah you can do method(&proc) when you call it
<RX14>
which is why you can do method(&->...)
<RX14>
its currently just syntax combinding
<RX14>
but it could be special cased later
<RX14>
was my poiny
<FromGitter>
<yxhuvud> and that inlining can either be super easy, hard or basically impossible depending on how the internals look.
<FromGitter>
<yxhuvud> Right.
<RX14>
the inlining is meh
<RX14>
the guessing the proc type arg is important
<RX14>
rememmber that procs need to specify the type of all arguments
<RX14>
so you need to do ->Foo.bar(String, In32)
<RX14>
allowing the compiler to desugar this to a normal block call would mean that the type args can be omitted
<FromGitter>
<yxhuvud> :shrug:. There are some other cases around procs that could also be streamlined that way, I guess this is one more case of that.
<RX14>
i feel motivated to implement this now lmao
<FromGitter>
<asterite> You mean, rewriting `foo(&->str.count)` to `foo { |*args| str.count(*args) }`?
<RX14>
yep
<RX14>
i imagine that could be done in the parser actually without *too* much trouble
<FromGitter>
<asterite> Yes, in the parser it could work, but then it's a special case for the formatter (we have too many of those special cases already T_T). Doing it in the normalizer is probably better (a separate pass that unsugars some things)
<RX14>
hmm
<FromGitter>
<asterite> It could be fun to play with it, and we could even merge it, I see no problem with it
<FromGitter>
<yxhuvud> I guess the hard part would be to decide when it can be done or not. I mean, sometimes you store away procs etc.
<RX14>
i don't think i'll get around to it any time soon
<RX14>
because i have more important things to work on :/
<RX14>
@yxhuvud *only* when it's that exact syntax
<RX14>
&-> specifically in method args would be the only case it'd work
<FromGitter>
<yxhuvud> ah
<FromGitter>
<asterite> the only problem is that it won't work well if the block is captured
<FromGitter>
<asterite> it's not working well with splats
<FromGitter>
<asterite> probably a bug
<RX14>
you mean `foo { |*args| ... }` doesn't work with splats?
<FromGitter>
<asterite> I might take a look at that later
<FromGitter>
<asterite> ^ right
<RX14>
but I could imagine it turning into a lot of code lol
<RX14>
i always got the impression that crystal didn't start off intending to be much more than a fun side project lol
<FromGitter>
<asterite> well, that's true and I'm still amazed whenever I see code written in Crystal... that I didn't write :-P
<FromGitter>
<asterite> Or code that's working well, out in the wild
<FromGitter>
<asterite> like, many of us coding in advent of code and the programs are doing what they are supposed to do
<FromGitter>
<asterite> reddit, here in gitter, everything that has formed and touches people's lifes. It's really cool (specially if you have fun with it)
<RX14>
yeha I definitely have fun with it
<RX14>
crystal is definitely something different and i'd like to see if we can work out how to get it to scale
<FromGitter>
<asterite> Absolutely
<FromGitter>
<spencerwi> For my part, Crystal is easily my favorite lang -- it scratches my "typed/compiled" itch, and has Ruby-grade (read: nearly-plain-english) readability
<FromGitter>
<spencerwi> I really *really* hope it takes off :)
<FromGitter>
<spencerwi> or, well, continues to
<FromGitter>
<proyb6> Someone AOC in Crystal really surprise me with a trick and less LOC
<FromGitter>
<spencerwi> I mean, so far my AoC solutions have had some really nice results that read like I'm just typing up an explanation of the problem
<FromGitter>
<spencerwi> which is basically just the problem statement ("find the biggest finite area") translated to code
<FromGitter>
<spencerwi> previous years I used my former-favorite-language, OCaml, which had similar benefits in terms of modeling types and having nice patterns for list processing and stuff, but was *way* less batteries-included and wasn't as enthusiastic about having its stdlib method names be descriptive
<RX14>
what's the point of each_with_object when we have closures?
<RX14>
i guess it'd be useful with &-> lol
<Yxhuvud>
it helps making certain the right thing is returned on later changes to the method
<FromGitter>
<j8r> @spencerwi you can use `#values` instead of map
<FromGitter>
<asterite> `each_with_object` is nice to pass a new object that gets returned by the method. It's succinct. By the way, it would be nice to have something like `Enumerable#to_a` but where you can pass an object and the elements get copied there. I'm thinking `collect`, but that exists in Ruby as a synonym of `map`
<RX14>
The thing is that Enumberable#map returns an array by default where ideally it'd return the same type
<RX14>
the return type of #map on objects is a bit inconsistent
<FromGitter>
<asterite> Yeah, that's true. It makes sense in Ruby because `Array` is mostly the thing you work with all the time. Well, in Crystal it's also true but we have `Slice`, `StaticArray`, `Deque`, although they are less used
<RX14>
i think Typle map returns tuple
<RX14>
so it's just we need to make #map return self all the time
<RX14>
and then add #to_a
<RX14>
with block
hexreel has left #crystal-lang ["WeeChat 1.6"]
<RX14>
(which maybe means moving #map off enumerable :O)
<Yxhuvud>
map_into ?
<Yxhuvud>
or just `map into: Array(T).new`
<FromGitter>
<kinxer> Why does making #map return self mean moving it off of enumerable?
<FromGitter>
<alehander42> returning the same type by default wouldn't be nice
<FromGitter>
<elorest> > *<oprypin>* @elorest, this is actually legit https://carc.in/#/r/5po7 ⏎ ⏎ Thanks a lot. That looks great.
<FromGitter>
<spencerwi> @j8r true, but I liked the readability of being explicit that I was grabbing the area in each case
Renich_ has joined #crystal-lang
Renich has quit [Ping timeout: 268 seconds]
Renich_ is now known as Renich
rohitpaulk has joined #crystal-lang
<FromGitter>
<j8r> @asterite have you an example where `each_with_object` is *better* than `each`?
<FromGitter>
<asterite> `e.each_with_object(Set(Int32).new) { |e, o| o << e }`
<FromGitter>
<spencerwi> that's assuming that `e` doesn't have `.to_set`
<FromGitter>
<spencerwi> whenever collections (or at least arrays) get involved, the compiler needs more help
<FromGitter>
<asterite> @ilanusse the array type not matching thing is all over the place in our github repo. It's because the array types are incompatible. It's not a bug, but it's something many stumble upon. Just do `speakers.map &.as(Speaker)`
<FromGitter>
<ilanusse> 👌 Great, thanks. @kinxer was the one who had the problem tho'
<FromGitter>
<kinxer> Thanks, @asterite. I've seen it around and run into it before, but I wanted to see what the usual workaround is.
<FromGitter>
<spencerwi> @asterite that's a pretty neat trick, though not a particularly intuitive one. Good to know for the future though
<FromGitter>
<spencerwi> admittedly, that kind of "flow-sensitive typechecking" can be a hard problem
<FromGitter>
<asterite> I know, `select` + `is_a?` would be more intuitive, but there's no way to implement that without adding a super hack
<FromGitter>
<spencerwi> yeah, you'd have to have `select` know to "look into" the contents of the block, see if it's an `is_a?` check, and then try to figure out what type to narrow to
<FromGitter>
<ilanusse> Couldn't there be
<FromGitter>
<ilanusse> A separate select method
<FromGitter>
<spencerwi> well, or else have the compiler be *super* aggressive about narrowing types, but I don't know if you could even do that at design/compile-time
<FromGitter>
<ilanusse> row.select_class(Space)
<FromGitter>
<asterite> yes, something like that exists in C# I think
<FromGitter>
<ilanusse> That'd be pretty nice to have
<FromGitter>
<asterite> yeah, it's called `OfType<T>` in c#
<FromGitter>
<ilanusse> I've used C# sparingly for Unity and it was pretty nic
<FromGitter>
<ilanusse> I liked it more than Java
<FromGitter>
<asterite> Yeah, C# is way nicer than Java, specially with all the `yield` magic, lambdas, linq, etc.
<FromGitter>
<alehander42> @asterite but what is stopping the type system from detecting `baseClassArray <- subclassArray`
<FromGitter>
<alehander42> it seems you have all the type info needed, and a safe transform always possible
<FromGitter>
<asterite> no, the safe transformation is not possible
<FromGitter>
<alehander42> so if there was a way to prove that the rvalue is temp/being owned only by the target of =, then it would be safe
<jemc>
it's mainly an issue with covariance / contravariance / bivariance
<FromGitter>
<asterite> exactly
<jemc>
we struggle with similar usability issues in pony, and I have a pending RFC about some usability support around those: https://github.com/ponylang/rfcs/pull/123
<jemc>
but because Array can both accept and emit elements of type T, it is bivariant, and you can't safely substitute sub or supertypes of the type argument
<FromGitter>
<asterite> interesting, first time I hear about bivariant, but it makes sense for Array
<jemc>
the pony RFC I linked to above would let you do something like say "give me a reference with the subset of the interface of Array that only emits elements rather than letting me insert them" or vice versa, and then you can talk about using type arguments that are a subtype or supertype of the original type argument
<FromGitter>
<alehander42> @jemc I see: however my idea was that if you e.g. pass a temp array ⏎ `initialize([..])` ⏎ you can prove transform safely this array, because nothing else will refer to it, so it wouldn't be able to accept any other invalid items
<FromGitter>
<alehander42> (except if you assign it to other fields/vars of course)
<FromGitter>
<asterite> that would be similar to what we have for "automatic" casting, and I thought about it but it's not trivial to implement
<jemc>
yeah, and I'm saying the way that you prove it is safe is by it only being exposed to the interface that can read (or delete) elements, but not insert
<FromGitter>
<alehander42> jemc but your RFC is pretty interesting indeed, have to read more pony before being able to assess it well
<FromGitter>
<alehander42> @asterite yeah, you're right, and it doesn't provide much value
<FromGitter>
<alehander42> if it's fixed for one situation
<FromGitter>
<girng> it just feels weird doing [0], and [1]
<FromGitter>
<j8r> use each
<FromGitter>
<girng> screw it. i'll just use the [0] and [1] idc no biggie :D i just have code in gdscript that looks similar to bottom and wanted the same skill tree code to be the same on the server. but it doesn't matter. cause once i get the skill id and dependency, i can just use the rest of the code and it should be fine. just a different way of grabbing the values. more aesthetic issue i guess, doesn't hurt functionality so
<FromGitter>
... i'll be fine
<FromGitter>
<j8r> @girng if you are iterating in an hash, you probably want to `#each |key, value|`
<FromGitter>
<girng> @j8r hmm i thought i tried that and it didn't work one second'
<FromGitter>
<girng> oh wow, fail. the second parameter must be there
<FromGitter>
<girng> i kept trying .each do |obj| 😆
<FromGitter>
<Blacksmoke16> the name of the var doesnt matter, it could be |dog, cat| instead of |key, value|
<FromGitter>
<Blacksmoke16> but ofc the latter is more readable
Harzilein has joined #crystal-lang
<Harzilein>
hi
<FromGitter>
<girng> hi
<Harzilein>
is there an scm with the debian source package?
<Harzilein>
(i guess i could also work with released debian source package (i.e. a working deb-src sources.list entry along with the deb one) but i thought i'd ask about the more convenient one first ;)
<Harzilein>
oh, it's fpm based... bummer...
DTZUZO has quit [Ping timeout: 250 seconds]
<FromGitter>
<swissChili> Hi folks, I had a question about crystal's type system, is this the place to ask it?
<FromGitter>
<elorest> @swissChili What is the question?
<FromGitter>
<swissChili> What I'm trying to do, is do a `<=` comparison on a variable of type `Int32 | String | Symbol`. Of course this gives a compile error, as it should, but how could I make it so I could manually handle the case the variable is of a different type?
<FromGitter>
<swissChili> I tried using an if statement and check the type but the compiler doesn't seem quite smart enough for that to compile