jhass changed the topic of #crystal-lang to: The Crystal programming language | https://crystal-lang.org | Crystal 0.35.1 | Fund Crystal's development: https://crystal-lang.org/sponsors | GH: https://github.com/crystal-lang/crystal | Docs: https://crystal-lang.org/docs | Gitter: https://gitter.im/crystal-lang/crystal
<oprypin> oooooo https://crystal-lang.org/api/0.34.0/Enumerable.html#flat_map(&block:T-%3EArray(U)%7CIterator(U)%7CU)forallU-instance-method
<oprypin> >> [3, 5].flat_map { |x| (0...x) }
<DeBot> oprypin: # => [0...3, 0...5] - https://carc.in/#/r/9vx1
<oprypin> >> [3, 5].flat_map { |x| (0...x).each }
<DeBot> oprypin: # => [0, 1, 2, 0, 1, 2, 3, 4] - https://carc.in/#/r/9vx2
f1reflyylmao has joined #crystal-lang
f1refly has quit [Ping timeout: 272 seconds]
avane has quit [Quit: ZNC - https://znc.in]
avane has joined #crystal-lang
DTZUZU has quit [Read error: Connection reset by peer]
Liothen has quit [Ping timeout: 260 seconds]
Liothen has joined #crystal-lang
Liothen has quit [Read error: Connection reset by peer]
Liothen has joined #crystal-lang
Liothen has quit [Read error: Connection reset by peer]
Liothen has joined #crystal-lang
DTZUZU has joined #crystal-lang
baweaver has quit [Ping timeout: 272 seconds]
yukai has quit [Ping timeout: 240 seconds]
yxhuvud has quit [Remote host closed the connection]
Nekka has quit [Ping timeout: 260 seconds]
Nekka has joined #crystal-lang
zorp_ has joined #crystal-lang
yxhuvud has joined #crystal-lang
HumanG33k has joined #crystal-lang
f1reflyylmao is now known as f1refly
<FromGitter> <HertzDevil> does `def f(*x : *T.class) forall T end` match anything
<FromGitter> <HertzDevil> or even mean anything
<FromGitter> <HertzDevil> docs only talk about method splats but not type splats
<FromGitter> <HertzDevil> *method argument splats
<FromGitter> <j8r> what should it splats?
<FromGitter> <j8r> like `Tuple(String, Int32)` to `String, Int32`?
<jhass> just def f(*x) and go on with your life :)
<FromGitter> <christopherzimmerman> Is there a way to specify the type of data here, but not have it complain about types?
<FromGitter> <christopherzimmerman> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5f981e60631a250ab296634a]
<f1refly> I have an array users that has the type (User | Nil)
<f1refly> I then run users.reject!{|u|u.nil?} on that array
<FromGitter> <Blacksmoke16> `class Foo(T)` ... `def initialize(@data : Hash(String, T));`
<FromGitter> <Blacksmoke16> you'd have to make a new array f1refly
<f1refly> But after that, the compiler still complains that elements in users can be Nil and methods arent found because of that
<FromGitter> <Blacksmoke16> just because you remove `nil` from the array doesnt remove `Nil` from its type
<f1refly> Hmm
<f1refly> Okay
<f1refly> Thanks
<FromGitter> <HertzDevil> what do you want
<FromGitter> <HertzDevil> `Hash(String, Tensor(Bool | Int32))`?
<FromGitter> <HertzDevil> if you can't do `@data : Tensor` without the type vars (you can't with `Array`) i don't think the hash is gonna work that way
<jhass> f1refly: #compact :)
<jhass> your code would work if you'd return a new array (reject instead of reject!), compact is a shortcut to this
<f1refly> Yeah, makes sense. I'll do that
<f1refly> Looks very neat, too :)
<FromGitter> <j8r> How can I can TypeNode to NamedTupleLiteral, I tried `if Options < NamedTuple`
<FromGitter> <Blacksmoke16> hm?
<jhass> I think you accidentally a word
<FromGitter> <j8r> *cast
<FromGitter> <j8r> can => cast 😅
<FromGitter> <Blacksmoke16> got some example code/
<jhass> "How cast I cast..:" :P
<FromGitter> <j8r> haha
<FromGitter> <j8r> cast me if you can
<FromGitter> <j8r> https://carc.in/#/r/9vzh
<FromGitter> <j8r> I can iterate with for, but can't use to_a
<FromGitter> <Blacksmoke16> whats the end goal here? `NT` is a type in this context, not an actual named tuple
<FromGitter> <Blacksmoke16> you want the types that are a part of the NT?
<FromGitter> <j8r> I would like to cast `NT` to `NamedTupleLiteral`, to use its methods
<FromGitter> <Blacksmoke16> but its not a `NamedTupleLiteral`
<FromGitter> <Blacksmoke16> in the sense you're thinking
<FromGitter> <j8r> but, why can I do a for loop then?
<FromGitter> <j8r> quite strange
<FromGitter> <Blacksmoke16> like if you print it you get `NamedTuple(a: String)`, i.e. not the actual values of it
<FromGitter> <j8r> ha, go it, yes
<FromGitter> <j8r> used `.keys` then, working
<FromGitter> <Blacksmoke16> ye
<FromGitter> <Blacksmoke16> typenode is kinda odd in that it has methods that are only really useable on *some* types
<FromGitter> <Blacksmoke16> like keys for example
<hightower2> sorcus, a couple of us here work on Qt bindings (https://github.com/Papierkorb/qt5.cr)
<FromGitter> <HertzDevil> ```VALUES = {0, ""} ⏎ Hash(*VALUES) # => Hash(Int32, String)``` [https://gitter.im/crystal-lang/crystal?at=5f982b5261007f7d1b9a5ebc]
<FromGitter> <HertzDevil> the more i dig into type splats the worse they get
<FromGitter> <Blacksmoke16> that one kinda makes sense tho
<FromGitter> <HertzDevil> `Hash(*Tuple(Int32, String))` would make sense, not that one
<FromGitter> <HertzDevil> ~~that way you can never splat anything into `StaticArray`'s size param~~
v2px__ has joined #crystal-lang
zorp_ has quit [Ping timeout: 240 seconds]
teardown has joined #crystal-lang
teardown has quit [Client Quit]
teardown has joined #crystal-lang
<FromGitter> <HertzDevil> now i'm confused
<FromGitter> <HertzDevil> have integers always been allowed as type vars even outside `StaticArray`?
<FromGitter> <Blacksmoke16> yea
<FromGitter> <HertzDevil> cool
<FromGitter> <Blacksmoke16> can do some fancy (hacky) stuff with them
<FromGitter> <Blacksmoke16> `class Foo(Idx)` `@type.instance_vars[Idx]` :S
<FromGitter> <HertzDevil> i got all of this working lmao https://play.crystal-lang.org/#/r/9w1o
<FromGitter> <HertzDevil> now i can port things like mdspan to crystal
<FromGitter> <HertzDevil> so only normal type vars support integers and type var splats don't
<FromGitter> <HertzDevil> too bad, no more `std::index_sequence` in crystal
early has quit [Quit: Leaving]
early has joined #crystal-lang
<FromGitter> <HertzDevil> a thing i don't like about crystal is it's hard to tell whether something is an undocumented feature or an unintended one
<FromGitter> <Blacksmoke16> its usually 50/50 ha
<raz> accidental features :P
<hightower2> quantification helps :)
<raz> the main thing i like about crystal is how few things it has that i strongly dislike
<raz> compared to other languages it gets pretty much everything right for my tastes & preferences
<FromGitter> <Dan-Do> Can I create a Hash(String, *)?
<FromGitter> <Blacksmoke16> kinda, but prob worth thinking if you really need that
<raz> yea, sounds like that's gonna become painful
<FromGitter> <Dan-Do> hix, really painful, huh
<FromGitter> <Blacksmoke16> what are you trying to do that you need that?
<FromGitter> <Blacksmoke16> prob is a better way
<FromGitter> <Dan-Do> `Error: no overload matches 'Proc(String, (Hash(String, Array(Hash(String, Array(Hash(String, String)) | String | Nil)) | Array(Tuple(String, String)) | Int32 | String | Nil) | Hash(String, String)), Hash(String, String))#call' with types String, Hash(String, Array(Hash(String, Array(Hash(String, String)) | Bool | String | Nil)) | Array(Tuple(String, String)) | Int32 | String)`
<FromGitter> <Blacksmoke16> can you make a playground link?
<raz> being as specific/explicit with types as possible is something i had to learn coming with ruby. it felt cumbersome at first in some places (and in some it legit *is* cumbersome). but the end-result is usually very much worth it - stuff clicks into place instead of dangling around
<raz> coming from*
<raz> it takes some unlearning to kick that ol' "just throw it in a hash" habit from ruby tho
<FromGitter> <Dan-Do> > can you make a playground link? ⏎ ⏎ nope, it's really big. I want to render a web page with data
<FromGitter> <Blacksmoke16> and you're using a hash of params?
<FromGitter> <Dan-Do> The thing is data comes from anywhere: db, user input, function...
<raz> can you normalize it somewhere on the way? (e.g. wrap it in a class)
<FromGitter> <Blacksmoke16> arent there shards to help with this kinda stuff?
<FromGitter> <Blacksmoke16> e.x. https://github.com/straight-shoota/crinja
<FromGitter> <Blacksmoke16> but the problem you're running into i think is `Proc`s are not as liberal with how they handle types
<FromGitter> <Blacksmoke16> i.e. they have to be exact iirc
<FromGitter> <Blacksmoke16> like you could have the proc type be like `Proc(String, SomeWrapperType, Nil)`
<FromGitter> <Blacksmoke16> where that wrapper type is something like raz suggested, that can contain arbitrary data
<FromGitter> <Dan-Do> The Proc is used to "transform" data from Hash(String, *) -> Hash(String, String)
<FromGitter> <Blacksmoke16> does it have to be a proc? isnt that just like `hash.transform_values &.to_s`?
<FromGitter> <Blacksmoke16> plus crystal handles doing that when interloping strings and stuff so might not even need to worry about it in the first place
<FromGitter> <Blacksmoke16> im sure theres an alternate/better approach here. However without knowing the context/end goals cant help *that* much
<FromGitter> <Dan-Do> With "tranform" I mean: ⏎ ⏎ 1) conditions (to render just some parts) ⏎ 2) calculate new vars from maybe Time ⏎ 3) db return JSON::Any (I am using Nosql) ... [https://gitter.im/crystal-lang/crystal?at=5f984ad16c8d484be2b006a8]
<FromGitter> <Blacksmoke16> sounds complex :p
teardown has left #crystal-lang [#crystal-lang]
<FromGitter> <Dan-Do> :( my bad design
<FromGitter> <Blacksmoke16> making your own renderer or something?
teardown has joined #crystal-lang
<FromGitter> <Dan-Do> yep, I render on the server side
<FromGitter> <Blacksmoke16> any reason you aren't/can't leverage any shards like the one i linked?
<FromGitter> <Dan-Do> I also use a front-end framework on the client side, which is not Jinja, so I cannot use crinja (though I looked at it)
<raz> what server-side framework are you using, if any?
<FromGitter> <Blacksmoke16> sounds like a custom one
<FromGitter> <Dan-Do> yep, custom one
<raz> well, welcome to the club of "problems that frameworks need to solve" then :D
<FromGitter> <Blacksmoke16> but if you're doing server rendered HTML then whats the reasoning for using a client side framework?
<FromGitter> <Blacksmoke16> as the content is already rendered
<FromGitter> <Dan-Do> I want to use "isomorphic" design :)
<raz> perhaps he's trying to render JSON?
<raz> oh
<FromGitter> <Dan-Do> love SPA world :)
<raz> welcome to the club of "problems that no framework has properly solved before" :P
<FromGitter> <Dan-Do> the server side is used if the browser disable javascript
<raz> that sounds like a nightmare, but kudos if you can pull it off
<FromGitter> <Blacksmoke16> is that a common scenario? Sounds like a lot of complexity/overhead for something you could just say is required
<FromGitter> <Blacksmoke16> and still support 99% of people
<FromGitter> <Dan-Do> I joined 1 year ago when leaning crystal :p lol
<raz> yeh, does anyone still browse without JS?
<raz> i haven't tried, but doubt many major sites work without JS anymore
<raz> simple stuff like blogs can of course work
<FromGitter> <Dan-Do> My project needs that (support without js), I mean it's a requirement
<FromGitter> <Blacksmoke16> https://deliberatedigital.com/blockmetry/javascript-disabled this random article i found say `0.2%` of all pageviews
<FromGitter> <Blacksmoke16> fair enough
<raz> i think i would rather discuss the reasoning behind that requirement (and have it dropped) than spend ~50% of my development resources on trying to make everything work without js
<FromGitter> <Dan-Do> I used browser without js 80% and I can stand with it.
<FromGitter> <Dan-Do> No advertisement :)
<raz> hm ok, everyone chooses their own battles :D
<FromGitter> <Blacksmoke16> just install and adblock and call it a day
<FromGitter> <Dan-Do> :D
<raz> the 0.2% can't install adblock because that's js, too :p
teardown has quit [Quit: leaving]
<FromGitter> <naqvis> naah, ddd project is targeting users like ddd , so even if js disabled, server will continue render the advertisement :P
<raz> and i'd bet a large portion of those 0.2% was just measured wrong because some advanced adblocker stripped the test-js :P
<jhass> I never tried but I bet libreJS is the best adblocker out there actually
<raz> i'm happy with ublock. don't remember when i last saw an ad
<FromGitter> <Blacksmoke16> circling back, i still dont see why its an issue that your front end framework doesnt use jinja?
<FromGitter> <Blacksmoke16> you're rendering HTML on the server, it shouldnt matter what the front end is at that point as you're getting back the full HTML page no?
<FromGitter> <Dan-Do> If js is enable, SPA framework works as normal :)
<FromGitter> <Blacksmoke16> so?
<FromGitter> <Dan-Do> jinja is not SPA framework :(
<FromGitter> <Blacksmoke16> right?
<FromGitter> <Blacksmoke16> i dont see the problem here
<FromGitter> <Blacksmoke16> or are you like using the same html for both spa and non spa context?
<FromGitter> <Dan-Do> yeap, that's what I want
<FromGitter> <Blacksmoke16> so you have an SPA being powered via server rendered HTML?
<FromGitter> <Dan-Do> correct
<raz> perhaps something like unpoly (which is awesome btw)
<FromGitter> <Blacksmoke16> how does that work?
<raz> unpoly.com
<FromGitter> <Blacksmoke16> like normally the SPA handles rendering its own templates
<FromGitter> <Blacksmoke16> and if you have to do a request to the server to get them doesnt that defeat the purpose/intent of the SPA in the first place?
<raz> it only has to do the req the first time, then it's cached
<FromGitter> <Dan-Do> true :)
<FromGitter> <Blacksmoke16> sure, but then how does the SPA do anything after that? i.e what if you click a button to add another todo
<raz> think in fragments, young padawan
<FromGitter> <Blacksmoke16> would have to do another request, or does the initial server rendered html include the markup for the spa?
<FromGitter> <Dan-Do> on my design, the server will detect then just return json if the request comes from spa
<raz> did you build the client-side framework, too, or using something existing?
<FromGitter> <Blacksmoke16> i guess im still just missing the piece of why you cant use like crinja to handle the rendering of the html in the non spa context
<FromGitter> <Dan-Do> I am trying mikado and sinuous :)
<FromGitter> <Dan-Do> lol
<FromGitter> <Dan-Do> > or are you like using the same html for both spa and non spa context? ⏎ ⏎ > i guess im still just missing the piece of why you cant use like crinja to handle the rendering of the html in the non spa context ⏎ ⏎ because of this [https://gitter.im/crystal-lang/crystal?at=5f98514b955f6d78a956de81]
<FromGitter> <Blacksmoke16> i.e. your custom renderer is made to support both
<FromGitter> <Dan-Do> yes
<FromGitter> <Blacksmoke16> 👍
<raz> but then don't you have to build all templates twice? (once in js, once on server)
<FromGitter> <Blacksmoke16> i think hes saying he made a custom renderer that uses the same syntax as the front end one
<raz> ohhh
<FromGitter> <Dan-Do> No, just one. the client framework has higer priority, so the server side must adapt to
<FromGitter> <Blacksmoke16> so they can both use the same tempalte
<raz> sounds like he's inventing a full blown meteor/hyperstack there
<raz> in fact, the hyperstack guys have voiced interest in porting it to crystal
<FromGitter> <Dan-Do> > i think hes saying he made a custom renderer that uses the same syntax as the front end one ⏎ > so they can both use the same tempalte ⏎ yes, that's the point
<raz> would love to see that. but it's a ginormous undertaking...
<raz> well, same template is half of the story. but what about variable references, etc
* raz scratches head
<FromGitter> <Blacksmoke16> regardless in that case i think you're going need to use a slightly diff approach for your proc
<FromGitter> <Blacksmoke16> or does it need to be a proc?
<FromGitter> <Blacksmoke16> that kinda stuff
<FromGitter> <Dan-Do> The renderer engine must adapt to the template, user can change/modify template, so I used proc to let dev write the "transform" part themselve
<FromGitter> <Blacksmoke16> got an example of what that looks like?
<FromGitter> <Blacksmoke16> like i could also see that just being a class with some method on it versus an actual proc
<FromGitter> <Blacksmoke16> or something along those lines
<FromGitter> <Dan-Do> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5f98531ac990bb1c3935b7c9]
<FromGitter> <Blacksmoke16> wew
<FromGitter> <Dan-Do> :D
<FromGitter> <Blacksmoke16> easiest solution would be raz's first suggestion of a wrapper type that you can type on the proc
<FromGitter> <Blacksmoke16> that the data lives within
<FromGitter> <Dan-Do> ok, I will look at that.
<FromGitter> <Dan-Do> Thank you so much guys :)
<FromGitter> <Blacksmoke16> gl
<FromGitter> <Dan-Do> love & hate crystal :)
<FromGitter> <j8r> omg
<FromGitter> <j8r> I imagine those on IRC right now, :)
<FromGitter> <Blacksmoke16> poor raz, prob lost in the text
<hightower2> no on IRC it provides a link instead of full paste
<FromGitter> <Blacksmoke16> ah really? neat
<raz> yup, IRC > gitter
<hightower2> yes, if/when it's pasted as a code block
<raz> i still don't understand how ppl can stand gitter
<FromGitter> <nipinium> hi, is it possible to update zip files using Compress::Zip? I check the docs but there were nothing.
mps has joined #crystal-lang
f1reflyylmao has joined #crystal-lang
f1refly has quit [Ping timeout: 260 seconds]
f1refly has joined #crystal-lang
f1reflyylmao has quit [Ping timeout: 260 seconds]
teardown has joined #crystal-lang
teardown has quit [Client Quit]
<FromGitter> <j8r> IRC is not user friendly, each time I want to create an account, it is a mess
<FromGitter> <j8r> confirmation mail, captcha, etc
<FromGitter> <j8r> also, soo Gitter will just be a matrix frontend :D
<FromGitter> <j8r> soon
teardown has joined #crystal-lang
<sorcus> hightower2: Ok, got it :-)
teardown has quit [Quit: leaving]
teardown has joined #crystal-lang
<FromGitter> <lebogan> Is this even possible?
<FromGitter> <lebogan> Once again ⏎ ⏎ ```code paste, see link``` ⏎ ⏎ can I even do something like this? [https://gitter.im/crystal-lang/crystal?at=5f988323eb82301c1a527dae]
<FromGitter> <RespiteSage> Are you trying to call the method `Helpers#name` when you pass in `{name: "foo"}`?
teardown has quit [Quit: leaving]
<FromGitter> <lebogan> I'm trying to use the key as the method name.
<FromGitter> <lebogan> I want to process the NamedTuple info one key/value at a time. If I call .name on process_helpers(info[:name]) it works, but it seems clumbsy if I have a larger amount of items.
<FromGitter> <j8r> @lebogan you can use macros, `{{ @type.instance_vars }}` to generate a case/when
<FromGitter> <j8r> where comes the `info` namedtuple?
<FromGitter> <j8r> is it really wanted to create a new helper on each iteration?
gangstacat has quit [Ping timeout: 272 seconds]
<FromGitter> <lebogan> My use case is a snmp-get operation where I process a unique oid at a time. I'm really attempting to build a parser, I think. I admit my macro knowledge is lacking.
Andriamanitra has quit [*.net *.split]
<FromGitter> <Blacksmoke16> you'd have to do something like what @j8r said
<FromGitter> <Blacksmoke16> like an `.invoke(name : String)` that case a case on the `name` based on ivar names and returns/calls the related method
<FromGitter> <RespiteSage> https://carc.in/#/r/9w3b
<FromGitter> <RespiteSage> Example ^
<FromGitter> <Blacksmoke16> yea like that :p
<FromGitter> <RespiteSage> Perfect timing. :P
<FromGitter> <Blacksmoke16> but id sit back and think if theres not a better way
<FromGitter> <Blacksmoke16> like more specialized types
<FromGitter> <RespiteSage> A note: the case in my example accepts either a string or a symbol, and it took me a long time to realize it wasn't working with just string because the named tuple key is a symbol.
<FromGitter> <RespiteSage> I agree. This works, but it's probably not an ideal long-term solution.
teardown has joined #crystal-lang
<FromGitter> <lebogan> @RespiteSage , I tried your example but no output. I need to work on this some more. Thanks also @Blacksmoke16
<FromGitter> <Blacksmoke16> i mean theres deff output, i see it on the side
<FromGitter> <lebogan> My copy/paste noob mistake :(
teardown_ has joined #crystal-lang
teardown_ has quit [Client Quit]
teardown has quit [Quit: leaving]
teardown has joined #crystal-lang
teardown has quit [Client Quit]
teardown has joined #crystal-lang
teardown has quit [Client Quit]
teardown has joined #crystal-lang
teardown has quit [Quit: leaving]
teardown has joined #crystal-lang
teardown has quit [Client Quit]
teardown has joined #crystal-lang
gangstacat has joined #crystal-lang
teardown has quit [Ping timeout: 240 seconds]
DTZUZU has quit [Read error: Connection reset by peer]
DTZUZU has joined #crystal-lang
yukai has joined #crystal-lang
<oprypin> is there any way to explicitly instantiate a type `Generic(*T)` with an empty tuple of types? `Generic().new` is a syntax error
<FromGitter> <Blacksmoke16> type of tuple.new
<oprypin> u mean `Generic(*typeof(Tuple.new)).new` ? that does work, thanks
<oprypin> hm anything less jarring? i'm intending this for the end user, who can make use of such an instantiation, among others
<FromGitter> <Blacksmoke16> Generic.empty
<FromGitter> <Blacksmoke16> Abstract it behind that class method
teardown has joined #crystal-lang
mps has quit [Ping timeout: 260 seconds]