teardown has quit [Remote host closed the connection]
teardown has joined #crystal-lang
teardown has quit [Ping timeout: 240 seconds]
teardown_ has joined #crystal-lang
sorcus has quit [Ping timeout: 260 seconds]
sorcus has joined #crystal-lang
sagax has quit [Ping timeout: 260 seconds]
postmodern has joined #crystal-lang
<FromGitter>
<bew> @hightower4 hey! It was mainly to understand better how terminfo worked, and to write a pure crystal version of unibilium for an hypothetic upcoming pure crystal terminal lib. FYI I don't do much crystal nowadays (went for rust, learning with AoC right now)
<FromGitter>
<Blacksmoke16> boo
<FromGitter>
<Daniel-Worrall> Did anyone figure out the equation for AoC day 10 part 2? Without going through `each_combination`?
<FromGitter>
<Daniel-Worrall> I spent forever trying to figure it out. Came up with half of it, gave up, found out the largest group of 1 differences was 5 which I had already calculated by hand :|
<FromGitter>
<mwlang> Thanks for the tip. Will check that out. Extending specs myself is more appealing than adopting a new shard as I've been burned a couple times with shards for test frameworks.
<FromGitter>
<anapsix> > any reason for all the complexity? versus just like having the interval be a static value like unix time? ⏎ ⏎ do you mean using second precision for the interval, and always using seconds? ⏎ I was hoping to have it resemble the syntax of creating `Time::Span` from numbers [https://gitter.im/crystal-lang/crystal?at=5fd3604f3dd3b251a4fcdc1a]
<FromGitter>
<anapsix> I suppose, another way about it making `Time::Span::Format`, and making `Time::Span.parse`
<FromGitter>
<ImAHopelessDev_gitlab> hmm composition and inheritance, perfect topic for me to join in on!
<FromGitter>
<ImAHopelessDev_gitlab> wait a minute, i'm a procedural kinda guy, is this still relevant to me ?
<FromGitter>
<naqvis> Hi Girng
<FromGitter>
<naqvis> nope
<FromGitter>
<ImAHopelessDev_gitlab> good that wikipedia article got too confusing lmao
<FromGitter>
<naqvis> but if someday you change your mind to OOP, then you might need to think about it :P
<FromGitter>
<tenebrousedge> but you may be less procedural than you want
<FromGitter>
<tenebrousedge> procedural code is sort of inherently longer and more duplicative
<Andriamanitra>
it's good to be familiar with multiple paradigms, that way you can combine them and use each to their strengths
_ht has joined #crystal-lang
<FromGitter>
<naqvis> Andriamanitra its nice to override `[]` operator, so you get a more natural look for `MyGrid` usage like `MyGrid[10,10]` instead of `MyGrid.new(10, 10)`
_ht has quit [Client Quit]
<FromGitter>
<ImAHopelessDev_gitlab> i use oop, but only the basics, like dot notation and objects? inheritance and composition seem too complex for no reason
<FromGitter>
<ImAHopelessDev_gitlab> and if i were coding in js, it would be a js object
<FromGitter>
<naqvis> Girng, i'm sure you have defined classes/structs and those contains other objects. So you have been using composition without even knowing its happening :D
<FromGitter>
<tenebrousedge> that's not very procedural in thinking
<FromGitter>
<ImAHopelessDev_gitlab> for example, a keyboard is a keyboard class/struct. then the properties are the letters
<FromGitter>
<ImAHopelessDev_gitlab> if i want to sell that keyboard to a friend, i create a method, handle_keyboard_trade()
<FromGitter>
<ImAHopelessDev_gitlab> keyboard1, keyboard2 are parameters, each one is a keyboard object
<FromGitter>
<tenebrousedge> that part is procedural
<FromGitter>
<ImAHopelessDev_gitlab> yes, so maybe i have a mix of both
<FromGitter>
<ImAHopelessDev_gitlab> but not a lot of oop just ahint of it
<FromGitter>
<naqvis> how do you call that method? `keyboard1.handle_keyboard_trade()` or `handle_keyboard_trade(keyboard)` ?
<FromGitter>
<tenebrousedge> OO would be defining Keyboard#trade, or more likely User#trade and pass keyboard
<FromGitter>
<ImAHopelessDev_gitlab> EWWWW
<FromGitter>
<ImAHopelessDev_gitlab> how can a keyboard have a trade method
<FromGitter>
<ImAHopelessDev_gitlab> that's where i leave OO alone, I guess. everyone is different
<FromGitter>
<tenebrousedge> deciding where methods live can be situational, but like, there was a reason for the second part of that sentence
<FromGitter>
<tenebrousedge> but either way
<FromGitter>
<tenebrousedge> `keyboard#trade` or `user#trade` would be OO, and `handle_keyboard_trade(k1, k2)` would be procedural
<FromGitter>
<ImAHopelessDev_gitlab> look at the human anatomy. Human is a class, property macro for brain, arm, all other parts. Now `trade` makes sense as a method
<FromGitter>
<tenebrousedge> having a lot of globally scoped methods like `handle_keyboard_trade(k1, k2)` would probably not result in good code
<Andriamanitra>
ok so now that i'm using this fancy Object#forward_missing_to how do i specifically exclude some methods? just override them with an empty method or is there a better way?
<FromGitter>
<ImAHopelessDev_gitlab> Because a human has the ability to TRADE something with another human
<FromGitter>
<tenebrousedge> yes hon
<FromGitter>
<Blacksmoke16> Andriamanitra prob not use that method and look into `delegate`
<FromGitter>
<tenebrousedge> ^
<FromGitter>
<ImAHopelessDev_gitlab> @tenebrousedge I think OOP makes more sense with living things and their inherent/intrinsic values
<FromGitter>
<Blacksmoke16> what and your code isnt a living thing
<Andriamanitra>
i can't trust myself not to use things! :p i think i'll override with a method that raises exception
<FromGitter>
<ImAHopelessDev_gitlab> i mean whatever object it is. for example a keyboard class for a Human class and a `trade` method
<FromGitter>
<Blacksmoke16> Andriamanitra thats prob not ideal but ok
<Andriamanitra>
what would be ideal then? []= specifically has potential to break all kinds of things with my grid
<FromGitter>
<Blacksmoke16> @ImAHopelessDev_gitlab thats where inheritance/composition comes in `#trade(item : Item)`
<FromGitter>
<ImAHopelessDev_gitlab> a keyboard doesn't have the ability to trade itself, so it needs a method/function to handle it. a human has the ability to trade, so a `trade` method given to the human class makes sense.
<FromGitter>
<Blacksmoke16> where `Keyboard < Item`
<FromGitter>
<naqvis> Andriamanitra if you want to proxy few methods of Array then use `delegate`, but if you want to hide very few methods then better define them in your class
<FromGitter>
<HertzDevil> the more code you write the more you realize it's less about whether oop is better than other paradigms and more about how polymorphism is implemented
<FromGitter>
<ImAHopelessDev_gitlab> is that like method overloading?
<FromGitter>
<ImAHopelessDev_gitlab> like WTF. it's just a join
<FromGitter>
<Blacksmoke16> two of those are deprecated, but i dont see your point
<FromGitter>
<HertzDevil> what about it?
<FromGitter>
<Blacksmoke16> one accepts an io, one just creates a string as is, one yields each item
<Andriamanitra>
overloading is awesome, why would you want to type str.split_by_regex(rgx) when you could just overload the short method name?
<FromGitter>
<ImAHopelessDev_gitlab> `Returns a String created by concatenating the results of passing the elements in the collection to the passed block, separated by separator (defaults to none).`
<FromGitter>
<ImAHopelessDev_gitlab> `Prints to io the concatenation of the elements, with the possibility of controlling how the printing is done via a block.`
<FromGitter>
<Blacksmoke16> right
<FromGitter>
<Blacksmoke16> two diff ways of doing the same thing, hence overloads versus `join_io` and `join` methods
<FromGitter>
<ImAHopelessDev_gitlab> so now, .join returns diff results. more confusion to the developer. 1 action, 1 method
<FromGitter>
<ImAHopelessDev_gitlab> it's that simple
<FromGitter>
<ImAHopelessDev_gitlab> simplicity is key
<FromGitter>
<Blacksmoke16> :rolls_eyes:
<Andriamanitra>
you just need to think of the type signature as part of the method name
<Andriamanitra>
there shouldn't be any confusion as long as you know what the types of your variables are, and if you don't i think you have bigger problems
<FromGitter>
<HertzDevil> that looks simple to me
<FromGitter>
<ImAHopelessDev_gitlab> now just .join, it's everywhere outside of crystal too!
<FromGitter>
<HertzDevil> an example of overloading that isn't simple is `Array#product`
<FromGitter>
<Blacksmoke16> i think he has a tendency to dislike anything and everything he doesn't understand
<FromGitter>
<ImAHopelessDev_gitlab> nope i use .join and method overloading i think
<FromGitter>
<Blacksmoke16> if it was confusing people wouldnt use/define overloads
<FromGitter>
<ImAHopelessDev_gitlab> i just think, 1 method per result is ideal
<FromGitter>
<ImAHopelessDev_gitlab> 1 method NAME
<FromGitter>
<ImAHopelessDev_gitlab> unique
<FromGitter>
<Blacksmoke16> that just sounds annoying
<FromGitter>
<HertzDevil> `1.0.float64_add_int32(5)` is ideal
<FromGitter>
<ImAHopelessDev_gitlab> sounds.. easy and less complex and figuring out what parameters to pass in
<FromGitter>
<Blacksmoke16> i dont really care about what method it is, i just want to add two numbers
<FromGitter>
<Blacksmoke16> that would get quickly verbose
<FromGitter>
<ImAHopelessDev_gitlab> what u mean verbose
<FromGitter>
<ImAHopelessDev_gitlab> about adding two numbers
<FromGitter>
<Blacksmoke16> `1.0 + 10_i64` versus `1.0.add_int64_to_float64 10_i64`
<FromGitter>
<erdnaxeli:cervoi.se> is there libraries to plot graph in crystal? I just saw this https://imgur.com/a/BnptlYq (aoc 11 spoiler) and I want to do the same :p
<FromGitter>
<ImAHopelessDev_gitlab> for numerals, i think it's fine because numerical system is complex
<FromGitter>
<ImAHopelessDev_gitlab> but for method names, nope
<FromGitter>
<Blacksmoke16> okey dokey
<FromGitter>
<ImAHopelessDev_gitlab> if you want to have the same method name, performing different things based on it's paramaeters.. fine by me. but it adds a layer of complexity and harder readability. both are detrimental
<FromGitter>
<HertzDevil> you say as though `+` isn't a method name
<FromGitter>
<Blacksmoke16> ^
<FromGitter>
<ImAHopelessDev_gitlab> for math, or operators it's fine
<FromGitter>
<HertzDevil> it indeed isn't in a language like java
<FromGitter>
<HertzDevil> and tbf that's somehow worse than languages where `+` is redefinable
<FromGitter>
<ImAHopelessDev_gitlab> @Blacksmoke16 not everything in programming is good, u know
<FromGitter>
<Blacksmoke16> no, but overloads arent one of them
<FromGitter>
<ImAHopelessDev_gitlab> u seem to vehemently defend all the conventional use cases in programming
<FromGitter>
<Blacksmoke16> i didnt invent them, i just embrace the tools that are available
<FromGitter>
<ImAHopelessDev_gitlab> u don't need to embrace, though
<FromGitter>
<Blacksmoke16> that allows me to write more readable code to others who also know about those concepts
<FromGitter>
<ImAHopelessDev_gitlab> be free
<FromGitter>
<Blacksmoke16> then id end up with code that looks like yours :shrug:
<FromGitter>
<tenebrousedge> well we have learned the hard way the value of these things
<FromGitter>
<Blacksmoke16> i like 🍝 but not with my code :P
<FromGitter>
<tenebrousedge> no one starts out being a vehement defender of OO
<FromGitter>
<ImAHopelessDev_gitlab> it's like art
<FromGitter>
<tenebrousedge> and we're probably not super sold on, say, OO vs FP
<FromGitter>
<Blacksmoke16> sure, your approach is abstract and mine is realism xD
<FromGitter>
<tenebrousedge> but OO vs procedural is a lot easier to find strong arguments for one side
<FromGitter>
<ImAHopelessDev_gitlab> bad example on art, i take that back
<FromGitter>
<ImAHopelessDev_gitlab> let me get a better analogy
<FromGitter>
<Blacksmoke16> im also not bashing functional programming as i dont really know anything about it
<FromGitter>
<Blacksmoke16> at least never used it
<FromGitter>
<ImAHopelessDev_gitlab> i tried so many times i gave up. i even posted on elixir forum for months
<FromGitter>
<tenebrousedge> imagine no instance methods
<FromGitter>
<ImAHopelessDev_gitlab> my brain can't comprehend the functional paradigm
<Andriamanitra>
my philosophy is paradigms should serve you, you shouldn't serve paradigms :p
<FromGitter>
<ImAHopelessDev_gitlab> @tenebrousedge mind just blew up. what's encapsulating methods then???
<FromGitter>
<Blacksmoke16> to be clear, there is a difference between a method and a function
<FromGitter>
<HertzDevil> even if you need different "method names" you can still have the same method name but different required named arguments, and to this end crystal already does it better than many other languages supporting oop
<FromGitter>
<ImAHopelessDev_gitlab> i view methods in crystal as carving on a rock
<FromGitter>
<ImAHopelessDev_gitlab> that's with the parameters set in stone
<FromGitter>
<ImAHopelessDev_gitlab> if u want a method to do something different, carve a new fcking rock ffs
<FromGitter>
<HertzDevil> like `[0, 1, 4, 9, 16].each(within: 1..3)`
<FromGitter>
<ImAHopelessDev_gitlab> and go find one down at the beach
<FromGitter>
<Blacksmoke16> @ImAHopelessDev_gitlab also to be clear overloads are meant to do the *same* thing, just with diff args
<FromGitter>
<HertzDevil> the `within:` is mandatory
<FromGitter>
<HertzDevil> iirc it's popular with objective-c too
<FromGitter>
<Blacksmoke16> like with your join example, the one joins with the separator and returns a string, the other joins with the separator but writes it to the io
<FromGitter>
<HertzDevil> we should normalize that
<FromGitter>
<Blacksmoke16> they are both joining, its not like they're doing totally different things but have the same name
<FromGitter>
<HertzDevil> you could then have "overloads" that are guaranteed not to overlap because the mandatory parameter names are different
<FromGitter>
<ImAHopelessDev_gitlab> .join(seperator) that's that
<FromGitter>
<Blacksmoke16> that uses the io overload
<FromGitter>
<ImAHopelessDev_gitlab> anything else, new method
<FromGitter>
<Blacksmoke16> which uses the block version :p
<FromGitter>
<ImAHopelessDev_gitlab> rofl look at all the `joins`
<FromGitter>
<HertzDevil> that's an (unsound) argument against making these particular methods overloads of each other, not an argument against all overloaded methods
<FromGitter>
<ImAHopelessDev_gitlab> `each_with_object`, `each_with_index` is a good example
<FromGitter>
<ImAHopelessDev_gitlab> that's some good method naming
<FromGitter>
<Blacksmoke16> because they do separate things
<FromGitter>
<ImAHopelessDev_gitlab> exactly
<FromGitter>
<Blacksmoke16> i.e. they're not overloadable really
<FromGitter>
<ImAHopelessDev_gitlab> good lol
<FromGitter>
<Blacksmoke16> so whats your point?
<FromGitter>
<HertzDevil> that's not true they both have block and non-block overloads
<FromGitter>
<Blacksmoke16> fair point, forgot about that
<FromGitter>
<ImAHopelessDev_gitlab> they are uniquely named methods, that do different things
gangstacat has quit [Quit: Ĝis!]
<FromGitter>
<Blacksmoke16> but `join` does the same thing and is named the same
<Andriamanitra>
i think we all agree that methods that do different things should be named different so i don't really see your point
<FromGitter>
<ImAHopelessDev_gitlab> join does different things
<FromGitter>
<Blacksmoke16> how you figure?
<Andriamanitra>
all of overloads join things
<FromGitter>
<ImAHopelessDev_gitlab> their parameters lmao
<FromGitter>
<ImAHopelessDev_gitlab> it's all different
<FromGitter>
<Blacksmoke16> that doesnt change what the method does
<FromGitter>
<Blacksmoke16> it join things
<FromGitter>
<ImAHopelessDev_gitlab> ?
<FromGitter>
<Blacksmoke16> whether it takes just the separator, or the separator and an io
<FromGitter>
<Blacksmoke16> both are just joining each element by the separator
<FromGitter>
<ImAHopelessDev_gitlab> if it needs to take an io, should have another method
<FromGitter>
<Blacksmoke16> the former just returns a string result, while the latter writes the data to the io
<FromGitter>
<Blacksmoke16> i disagree, its a great pattern to define the io version first then just use `String.build` as the io for the string result
<FromGitter>
<Blacksmoke16> which is how join is implemented
<FromGitter>
<ImAHopelessDev_gitlab> i mean ur point makes sense, but to me it seems to make more sense ot have separate methods
<FromGitter>
<Blacksmoke16> doesnt that make it harder to remember the specific names of what exact thing you want versus just remembering "i want to join things"
<Andriamanitra>
+ it leads to java style method names that are at least two miles long
gangstacat has joined #crystal-lang
<FromGitter>
<naqvis> Girng I would say Golang suits your style more, no type hierarchy, no overloading :P
<Andriamanitra>
ok possibly really stupid question but is []= the only special case where you can write something similar to "obj.method(args) = newval"?
<FromGitter>
<tenebrousedge> special case?
deavmi has quit [Ping timeout: 264 seconds]
<Andriamanitra>
i mean that it sets the value and takes arguments on the left side of '='
<FromGitter>
<j8r> `some_method=(key)`?
<FromGitter>
<j8r> then you can call `some_method = "key"`
<FromGitter>
<Blacksmoke16> his point is `[]=` has two args, like `arr[0] = 1` `[]=(idx, value)`
<FromGitter>
<j8r> two args, don't know, can it work?
<FromGitter>
<Blacksmoke16> yes but that only has 1 arg
<FromGitter>
<Blacksmoke16> right, because i think that setter is special?
<Andriamanitra>
well the compiler does say "Error: setter method 'set=' cannot have more than one argument", but if []= can do it maybe there are others..?
<FromGitter>
<naqvis> you can have multiple args, but two args are mostly norm for index based values
<FromGitter>
<j8r> right, just tried
<FromGitter>
<Blacksmoke16> i usually switch to like `obj.set_value 1, 2`
<FromGitter>
<Blacksmoke16> :shrug:
<FromGitter>
<Blacksmoke16> `[]=` could get confusing if there isnt a key/value, or idx/value pairing
<FromGitter>
<Blacksmoke16> or something similar
<FromGitter>
<naqvis> agree, that's why compiler is declining that
<Andriamanitra>
yeah, true.. so it is the only one?
<FromGitter>
<naqvis> but it makes sense for Arrays/Hashes
<FromGitter>
<j8r> Little poll: do people here use ad blockers?
<FromGitter>
<j8r> because it collects biased stats, as you see most of us already block it
<FromGitter>
<Blacksmoke16> id be curious to see just how many actually block GA tho
<Andriamanitra>
i might very well be the only one here but i think highly of sites that don't trigger the adblocker, even if it's something relatively harmless like GA
<FromGitter>
<Blacksmoke16> i mean if they're just outright not using it at all, then sure. but idt we're in a positional to tell them that they should do something different just because
<FromGitter>
<mwlang> I use brave browser for ad blocking. I haven't seen a Youtube advertisement in so long....
<FromGitter>
<j8r> My point is, GH Pages would cost less, provides free analytics, better privacy
<FromGitter>
<j8r> @anapsix thx! as I was suspecting. I use Privacy Badger + the default in Firefox
<FromGitter>
<anapsix> GH Pages can be still have embedded GA code, if so desired
<FromGitter>
<Blacksmoke16> ^ thats how mines setup
<FromGitter>
<j8r> of course, that's just a static site
<FromGitter>
<j8r> why having GA @Blacksmoke16 ?
<FromGitter>
<Blacksmoke16> i think its neat to look at
<FromGitter>
<j8r> ...you know now that it is biased, likely less than half of your visits have it un blocked
<FromGitter>
<Blacksmoke16> so?
<FromGitter>
<Blacksmoke16> doesnt change the fact its neat to look at :p
<FromGitter>
<j8r> so you can't make decisions on it, because it does not represent the majority of your visitors. It is therefore mainly useless
<FromGitter>
<Blacksmoke16> granted idk anything about marketing really so its not like its a critical piece of tech, but having an idea that people are looking it and such is good info to know
<FromGitter>
<Blacksmoke16> i mean its not like i would be doing that anyway ha
<FromGitter>
<j8r> correction: that's likely the least tech-savvy you have stats
<FromGitter>
<j8r> (in general)
<FromGitter>
<Blacksmoke16> probably, but so what?
<FromGitter>
<j8r> as said before, you can't know the most popular pages for instances
<FromGitter>
<j8r> but no worry, there are alternatives that are not blocked
<FromGitter>
<Blacksmoke16> looking at logs? :p
<FromGitter>
<j8r> other solutions than GA, like matomo
<FromGitter>
<j8r> yes or logs or GH Pages
<FromGitter>
<anapsix> this thing is pretty neat - https://matomo.org/ - and you can serve it from whatever domain, when self-hosting.. ofcourse you'd have to host it somewhere, but a small $5/$10 per month DO instance would probably be enough
<FromGitter>
<Blacksmoke16> sure but thats a lot of work and $ compared to something i had to do essentially no work on and is free
<FromGitter>
<j8r> @Blacksmoke16 note you can already know popular pages wit GitHub
<FromGitter>
<Blacksmoke16> nor do i really intend on using
<FromGitter>
<anapsix> true, I wish there'd be a privacy minded publicly usable analytics platform
<FromGitter>
<anapsix> cloudflare provides some analytics, btw ⏎ though it's somewhat limited
<FromGitter>
<j8r> Anyway, I don't mind. Just saying it is useless, you said yourself you don't do anything, so shrug :)
<FromGitter>
<j8r> for Crystal, I'm mainly curious since a long time if it is really used to justify its presence.
<FromGitter>
<j8r> If core members look at it to improve the site, I'm 100% fine!
<FromGitter>
<anapsix> would be cool to have those stats published
<oz>
oops, forgot I had to register to watch the free crystal conf. 🤔
<yxhuvud>
apart from the f-g disconnect button, weird how?
f1reflyylmao has joined #crystal-lang
f1refly has quit [Ping timeout: 272 seconds]
o5r has joined #crystal-lang
_ht has quit [Remote host closed the connection]
<FromGitter>
<kingsleyh> Was a great conf - some really good sessions
<FromGitter>
<kingsleyh> @wontruefree great panel discussion - wish it had have been a bit longer - but being at the end is when you usually get squashed and even sometimes completely cut - so time keeping was pretty good overall
<liteyear>
Just finished catching up on Massimiliano’s tools conference presentation. Great to see the challenges getting an IDE set up were acknowledged.
<liteyear>
I’m up and running with VS Code, but do have one niggling pain remaining: when running the Build Task (⌘⇧B) VS Code complains that The task provider for "crystal" tasks unexpectedly provided a task of type "shards”.