<FromGitter>
<dscottboggs_gitlab> Is there any way besides `!!` to convert to a boolean?
<FromGitter>
<Blacksmoke16> neg
<FromGitter>
<dscottboggs_gitlab> I don't like that
<FromGitter>
<Blacksmoke16> define a method on object like `to_bool` that returns `!!self`?
<FromGitter>
<dscottboggs_gitlab> I feel that `!` for `not` is pretty unintuitive to inexperienced programmers. I think there should be an `Object#to_bool` that returns true, and is overridden by `Bool` and `Nil` types.
<FromGitter>
<Blacksmoke16> was an issue about this
laaron has quit [Remote host closed the connection]
laaron has joined #crystal-lang
laaron has quit [Remote host closed the connection]
laaron has joined #crystal-lang
alexherbo2 has joined #crystal-lang
alexherbo26 has joined #crystal-lang
<FromGitter>
<watzon> Where `!` for `not` may be unintuitive to inexperienced programmers it is a pretty universal concept and definitely something that should be learned
alexherbo29509 has quit [Ping timeout: 250 seconds]
alexherbo26 has quit [Client Quit]
alexherbo26 has joined #crystal-lang
alexherbo2 has quit [Ping timeout: 246 seconds]
alexherbo268 has joined #crystal-lang
alexherbo268 has quit [Client Quit]
alexherbo268 has joined #crystal-lang
alexherbo26 has quit [Ping timeout: 250 seconds]
alexherbo2688 has joined #crystal-lang
alexherbo2688 has quit [Client Quit]
alexherbo2688 has joined #crystal-lang
alexherbo268 has quit [Ping timeout: 252 seconds]
alexherbo26886 has joined #crystal-lang
alexherbo2688 has quit [Ping timeout: 252 seconds]
alexherbo268866 has joined #crystal-lang
alexherbo26886 has quit [Ping timeout: 246 seconds]
alexherbo2688667 has joined #crystal-lang
porg has joined #crystal-lang
alexherbo268866 has quit [Ping timeout: 246 seconds]
alexherbo2688667 has quit [Ping timeout: 250 seconds]
porg has quit [Ping timeout: 250 seconds]
f1refly has quit [Ping timeout: 264 seconds]
f1refly has joined #crystal-lang
alexherbo2 has joined #crystal-lang
<FromGitter>
<watzon> Is it possible to make a value a Tuple of a known type but unknown size? Like `a : Tuple(Int32*) = {1, 2, 3, 4, 5}`
rohitpaulk has joined #crystal-lang
rohitpaulk has quit [Ping timeout: 250 seconds]
rohitpaulk has joined #crystal-lang
ian_0xF has joined #crystal-lang
ian_0xF has quit [Client Quit]
rohitpaulk has quit [Ping timeout: 248 seconds]
return0e has quit [Read error: Connection reset by peer]
return0e has joined #crystal-lang
rohitpaulk has joined #crystal-lang
rohitpaulk has quit [Ping timeout: 258 seconds]
laaron has quit [Remote host closed the connection]
laaron has joined #crystal-lang
azuri5 has joined #crystal-lang
rohitpaulk has joined #crystal-lang
return0e has quit [Read error: Connection reset by peer]
return0e_ has joined #crystal-lang
rohitpaulk has quit [Remote host closed the connection]
<FromGitter>
<vladfaust> @watzon you could define a splat method for this https://carc.in/#/r/6ued
<FromGitter>
<mwlang> struggling with my first macro definition. I'm trying to write a method that can obtain it's values from a given source which is just a getter on some class or struct for a Float64 value.
<FromGitter>
<mwlang> but it expands quite literally to: @points.prev(0).source
<FromGitter>
<mwlang> {{source}} is not interpolated.
<FromGitter>
<mwlang> a calling example would be: "weighted_average :input_value" and I would've expected "@points.prev(0).input_value" as the result of the macro on line #10 of the gist
<FromGitter>
<lsymonds> Hi all. Found and played with Crystal a few days ago and loving it. Looking forward to becoming an active member of the community.
<FromGitter>
<dscottboggs_gitlab> @mwlang sorry I was going to reply earlier but I had to go out
<FromGitter>
<dscottboggs_gitlab> Your issue is that `weighted_average` needs to be a macro as well, like this
<FromGitter>
<dscottboggs_gitlab> @lsymonds nice to meet you :)
<FromGitter>
<mwlang> @dscottboggs_gitlab Interesting resolution. would not have thought of that.
<FromGitter>
<dscottboggs_gitlab> it's ok, macros are a super tough concept
<FromGitter>
<mwlang> why does that make it work? what did I miss?
<FromGitter>
<mwlang> or maybe better question, why not just change original macro to use {{source.id}} ?
<FromGitter>
<dscottboggs_gitlab> well, in the method version of `weighted_average` you assigned a symbol to a varibale named `source`, then passed *that* into a macro. The value of the variable isn't important, it's literal text is. So the macro got a `MacroID` with the text "source" not the text defined by the symbol
<FromGitter>
<dscottboggs_gitlab> So you're just moving weighted_average into "macro-land" so that you can figure out what the `MacroID` `source` refers to is
<FromGitter>
<dscottboggs_gitlab> does that make sense?
<FromGitter>
<mwlang> absolutely!
<FromGitter>
<dscottboggs_gitlab> ok good :)
<FromGitter>
<mwlang> that was the key thing I was not grokking
<FromGitter>
<mwlang> ok, simplified the whole thing... ditched "prev_value" macro and just made it all work directly in the new weighted_average macro.
<FromGitter>
<dscottboggs_gitlab> yup that's what I would've done too
<FromGitter>
<mwlang> nice how this still feels relatively like Ruby metaprogramming.
<FromGitter>
<mwlang> converting a few more similar helper methods in Ruby over to crystal and they're all converting to macros very easily now.
<FromGitter>
<dscottboggs_gitlab> wow that's really good to hear
<FromGitter>
<dscottboggs_gitlab> it won't work in every case
<FromGitter>
<dscottboggs_gitlab> ruby metaprogramming can happen at runtime, macros cannot
<FromGitter>
<dscottboggs_gitlab> I.E. you can't take user input then call that string as a method on an object
<FromGitter>
<mwlang> yeah, I get that one. I've got a few of those to come...not quite sure how I will refactor those.
<FromGitter>
<mwlang> doing the easier stuff first to build my basic familiarity with crystal.
<FromGitter>
<dscottboggs_gitlab> There is a way to technically do it, but I would try to use a hash before resorting to that
<FromGitter>
<dscottboggs_gitlab> yeah crystal is nice but it's a bit of a "kitchen-sink" language
<FromGitter>
<mwlang> how so, kitchen-sink? I mean, I get that it has ability to expose unsafe things like pointers and interact at traditionally "C" level and it takes inspiration from a number of languages, not just Ruby, but it feels pretty cohesive and well thought out to me so far.
<FromGitter>
<dscottboggs_gitlab> I just meant that there are a lot of features in the standard library. If you're coming from Ruby, the syntax makes a lot of sense, but if you're coming from no experience there are a lot of things to learn.
<FromGitter>
<dscottboggs_gitlab> it's not a bad thing
<FromGitter>
<mwlang> oh, I see.
<FromGitter>
<j8r> That's quite right, but the learning curve isn't steep
<FromGitter>
<mwlang> I can definitely see why a Ruby background makes a transition to Crystal very easy.
<FromGitter>
<dscottboggs_gitlab> true! :)
<FromGitter>
<dscottboggs_gitlab> good morning @j8r
<FromGitter>
<j8r> good evening @dscottboggs_gitlab
<FromGitter>
<dscottboggs_gitlab> haha
<FromGitter>
<j8r> compared to Rust or C++, Crystal is definitely simpler with less features
<FromGitter>
<j8r> but C and Go are simpler
<FromGitter>
<dscottboggs_gitlab> Really? I haven't gotten the chance to play with rust too much but I got the impression that it was around the same as crystal when it came to stdlib features, maybe a little less
<FromGitter>
<dscottboggs_gitlab> or did you mean syntax edge cases?
<FromGitter>
<j8r> not really the stdlib
<FromGitter>
<j8r> I mean the borrow checker
<FromGitter>
<dscottboggs_gitlab> yeah what a syntactical clusterfuck. I love the idea and can't wait to see it iterated on but...jeeze...
<FromGitter>
<dscottboggs_gitlab> I was actually thinking the other day, it would be hypothetically possible to build a borrow checker on top of crystal using macros and Pointers
<FromGitter>
<dscottboggs_gitlab> like, as a library you could just include
<FromGitter>
<j8r> an allocator can be chosen, there is none by default
<FromGitter>
<dscottboggs_gitlab> interesting
<FromGitter>
<mwlang> ok, I'm missing something obvious. I can see PI is a constant for the Math module, but when I attempt to use it: "Math.PI" => undefined method 'PI' for Math:Module
<FromGitter>
<dscottboggs_gitlab> `Math::PI`
Welog has quit [Remote host closed the connection]
<FromGitter>
<mwlang> hmmm...so why "Math::PI", but not "Math::cos()" or "Math::tan()" I just blindly changed all the "::" to "."
<FromGitter>
<dscottboggs_gitlab> I always assumed that was just borrowed from ruby... idk
<FromGitter>
<mwlang> Ruby can go either way. Looks like in the docs, Crystal developers considered it syntax inconsistency and removed "::" notation for class level method calls.
<FromGitter>
<j8r> `::` are used to separate modules, which are CamelCase
laaron has joined #crystal-lang
<FromGitter>
<j8r> and `.` to call a method
<FromGitter>
<mwlang> Yeah, that's what I just read....I'm just saying in Ruby, Math::cos() and Math.cos() are acceptable.
<FromGitter>
<j8r> good to know...
<FromGitter>
<j8r> this syntax is accepted for every class method?
<FromGitter>
<mwlang> similar to what I did assigning "Math" to "foo" variable.
<FromGitter>
<j8r> For generics I prefer `Ab(T)` than `Ab<T>`
<FromGitter>
<mwlang> I'll just drop my own stylistic convention and adopt Crystal's. There's obviously some good reasons for doing so since the Ruby community produces pretty well-vetted style guide.
<FromGitter>
<mwlang> ugh to Ab<T> Nothing about that makes sense. :-p
<FromGitter>
<j8r> anyway, you have an Union somewhere
<FromGitter>
<alex-lairan> Yes, but I want Composant, to be able to only do `.price` on this. ⏎ ⏎ (NamedTuple or Hash is a detail, this is just for an example)
<FromGitter>
<j8r> not really
<FromGitter>
<j8r> you have to deal with union here
<FromGitter>
<j8r> that's why `Hash(Symbol, T)` isn't a good Ruby habit :P
<FromGitter>
<alex-lairan> Ok ;)
<FromGitter>
<alex-lairan> Oh, with this : https://carc.in/#/r/6ujr ⏎ I have an Hash (so I can add things later) and no Union (lower compile time)
<FromGitter>
<alex-lairan> But it's not elegant
<FromGitter>
<j8r> `NamedTuple` is a struct, more efficient than allocation a `Hash`
<FromGitter>
<alex-lairan> The problem with union is that if I have a union with 1000 elements, it will create 1000 different methods
<FromGitter>
<j8r> the best would be to create your own struct
<FromGitter>
<Blacksmoke16> why not just use an array of structs
<FromGitter>
<dscottboggs_gitlab> only if you actually call the methods
<FromGitter>
<j8r> 💯
<FromGitter>
<Blacksmoke16> with a like `type` property
<FromGitter>
<Blacksmoke16> make type an enum
<FromGitter>
<Blacksmoke16> and could do like `@components.select(&.type.screen?).sum_by { |c| c.price }`
<FromGitter>
<Blacksmoke16> with ofc `Component` being abstract struct with common fields
<FromGitter>
<alex-lairan> Because I don't want to have multiple screens :) ⏎ ⏎ I'm using an ObjectPool pattern
<FromGitter>
<Blacksmoke16> then dont push multiple to the array
<FromGitter>
<alex-lairan> If the design allow it, so one day it will be true :(
<FromGitter>
<Blacksmoke16> then why not just have like `@screen`, `@processor` properties on `Computer`
<FromGitter>
<alex-lairan> A reason why I leaved Ruby, in Crystal we have more power about what we want.
<FromGitter>
<Blacksmoke16> and new it up with instances of those types
<FromGitter>
<alex-lairan> It could be a thing too ! :)
<FromGitter>
<elankvitko> hey everyone :) sorry to be a bother but can you recommend please a good framework to use for creating api’s with jwt support? i was thinking amber or lucky. never used either one so i have a learning curve. would love to know which route i should taker
<FromGitter>
<elankvitko> take
<FromGitter>
<dscottboggs_gitlab> I have been working on Kemal + JWT auth stuff for a while and recommend it
<FromGitter>
<dscottboggs_gitlab> sec
<FromGitter>
<elankvitko> Thanks so much!
<FromGitter>
<dscottboggs_gitlab> Also, @Blacksmoke16's Athena is super powerful for JSON apis
<FromGitter>
<elankvitko> Lol thank you so much and @Blacksmoke16 thanks for all the hard work you put in to make using crystal in the future for so many a reality
<FromGitter>
<elankvitko> thanks @alex-lairan i tried amber actually once but was in a rush. i gave up after i couldn’t get associations working
<FromGitter>
<elankvitko> got frustrated lol
<FromGitter>
<Blacksmoke16> np, but thats prob more credit than i deserve :p
<FromGitter>
<elankvitko> Haha i was just at railsconf in minneapolis and was raving about crystal to everyone trying to open their eyes. harder to do than i thought
<FromGitter>
<Blacksmoke16> granite is the same ORM used in amber
<FromGitter>
<Blacksmoke16> not a super big fan of the model syntax but is what it is :shrug:
<FromGitter>
<elankvitko> oh great. i’ll try it out.
<FromGitter>
<Blacksmoke16> when using annotations*
<FromGitter>
<elankvitko> haha missing activerecord right about now
<FromGitter>
<Blacksmoke16> 😉
<FromGitter>
<elankvitko> do you have an idea as to when/if crystal will be ready for production use?
<FromGitter>
<Blacksmoke16> its already used in prod in some places
<FromGitter>
<dscottboggs_gitlab> mostly web stuff rn
<FromGitter>
<elankvitko> I see. Cool i have really high hopes for crystal. im praying every day it gets more recognized
<FromGitter>
<Blacksmoke16> we shall see
<FromGitter>
<mwlang> I don't much care for ActiveRecord generally speaking. It's a beast under the covers.
<FromGitter>
<mwlang> Love Sequel, though.
<FromGitter>
<Blacksmoke16> an orm is tricky, esp when you need to support various db
<FromGitter>
<mwlang> anything worth porting, Sequel would be the one I'd attempt.
<FromGitter>
<mwlang> yeah, an ORM in crystal seems to be like it would be the "Disney world" of a collection of macros.
<FromGitter>
<mwlang> esp. for something like an AR port which has so much meta-programming in it, it's not even funny.
<FromGitter>
<Blacksmoke16> any orm would have to use macros in some regards
<FromGitter>
<Blacksmoke16> some use them in more hacky ways than others thats for sure
<FromGitter>
<Blacksmoke16> whether those macros are used with actual `macro` defs or with annotations; either way they are still using macros
<FromGitter>
<alex-lairan> @mwlang I tried to create an ORM like ROM https://github.com/alex-lairan/azurite ⏎ ⏎ It's for mongo, it work for simple queries, but it's a POC.
<FromGitter>
<Blacksmoke16> does mongo use json for the queries?
<FromGitter>
<mwlang> @alex-lairan I was about to say "there's no code there" but the bulk of the work is in another branch other than master.
<FromGitter>
<mwlang> might want to merge that or people will not look too far into this project.
<FromGitter>
<mwlang> huh? Array doesn't have slice method? (or is that me doing something wrong): "undefined method 'slice' for Array(JSON::Any)"
<FromGitter>
<alex-lairan> @mwlang it's a POC, it should not be used ^^
<FromGitter>
<Blacksmoke16> can do `to_unsafe` then pass that to `Slice.new`
<FromGitter>
<Blacksmoke16> maybe like ` Slice.new(array.to_unsafe, array.size)`?
<FromGitter>
<mwlang> @alex-lairan I saw that. Just sayin' :-)
<FromGitter>
<elankvitko> @Blacksmoke16 in your tutorial i can’t seem to find where to put the actual sql statements
<FromGitter>
<Blacksmoke16> for what i do its just easier to run the raw sql
<FromGitter>
<Blacksmoke16> i heard good thing about the migrate one tho
<FromGitter>
<elankvitko> great. i will check it out
<FromGitter>
<Blacksmoke16> np
alexherbo2 has quit [Remote host closed the connection]
alexherbo2 has joined #crystal-lang
<FromGitter>
<mwlang> Ah...."Ruby's Array#slice really is just an alias for Array#[]. If you look at our Array#[] you'll find it already covers most, if not all, of the same usecases."
<FromGitter>
<mwlang> so, bye-bye #slice, hello using brackets everywhere.
<livcd>
Was there any Crystal talk at RubyKaigi ?
hightower2 has joined #crystal-lang
olbat[m] is now known as olbat[m][m]
olbat[m][m] is now known as olbat[m]1
olbat[m]1 is now known as olbat[m]2
<FromGitter>
<vladfaust> Nope
<FromGitter>
<vladfaust> I guess there are no applicants in our community having enough resources to both attend the conf and prepare the talk
<FromGitter>
<watzon> Hopefully soon
alexherbo29 has joined #crystal-lang
alexherbo2 has quit [Ping timeout: 252 seconds]
alexherbo291 has joined #crystal-lang
alexherbo29 has quit [Ping timeout: 248 seconds]
<FromGitter>
<malkomalko> I know of `&.method` shortcut when dealing with `map` etc, but that ends up calling the `method` on whatever type is in the Iterable. Is there any shortcut for passing a function to `map` that's in the same class it's being called from?
<FromGitter>
<malkomalko> Couldn't figure out how to have `exclaimify` in that example be a method and not a proc, but that's more along the lines of what I was talking about
<FromGitter>
<Blacksmoke16> adding custom settings to athena
<FromGitter>
<dscottboggs_gitlab> oh sweet
<FromGitter>
<Blacksmoke16> are actual objects so type safe and can have methods and stuff
<FromGitter>
<lsymonds> What's the idiomatic way for handling code dependencies in Crystal? I'm used to interfaces and IoC containers, not what is given now. Is it a case of duck-typing with base classes or using modules as pseudo-interfaces instead? ⏎ ⏎ Furthermore, when testing, and when absolutely necessary to override a third party dependency, is the standard to simply use modules to override any external code that contains
<FromGitter>
... behavior that needs to change?
<FromGitter>
<dscottboggs_gitlab> > using modules as pseudo-interfaces instead
<FromGitter>
<Blacksmoke16> have real interfaces would be cool
<FromGitter>
<Blacksmoke16> w/o having to include a module or inherit from a subclass
<FromGitter>
<dscottboggs_gitlab> > override any external code that contains behavior that needs to change ⏎ ⏎ yes, the language allows does not discourage reopening classes/structs/modules for the purpose of changing their behavoir
<FromGitter>
<lsymonds> > > override any external code that contains behavior that needs to change ⏎ > ⏎ > yes, the language allows and does not discourage reopening classes/structs/modules for the purpose of changing their behavior ⏎ ⏎ Great. Good to know I'm on the right track and not missing something entirely! Thank you. [https://gitter.im/crystal-lang/crystal?at=5ccf4a68e416b84519372886]
<FromGitter>
<lsymonds> Ignore that, the sidebar title doesn't match it anyway :D
<FromGitter>
<dscottboggs_gitlab> yes the book is more-front-to back than reference-style
<FromGitter>
<straight-shoota> > modules as pseudo-interfaces ⏎ ⏎ Drop the pseudo. Modules are interfaces. They also have different applications, but one of their intents is defining an interface that types can include.
hightower2 has quit [Ping timeout: 245 seconds]
early has quit [Quit: Leaving]
early has joined #crystal-lang
<FromGitter>
<watzon> I'm trying to make a method that gets the shape of an array, but this isn't working ⏎ ⏎ ```code paste, see link``` ⏎ ⏎ It's giving me the error `Undefinied method 'shape' for Int32`. Can anyone think of a better way to do this or figure out why my method isn't working? [https://gitter.im/crystal-lang/crystal?at=5ccf6dad1cd0b8307dcbd1e4]
<FromGitter>
<Blacksmoke16> `self[0]` is an `Int32`, you're defining `shape` on `Array`
<FromGitter>
<Blacksmoke16> what is the expected output from an array like `[1,2,3]`?
<FromGitter>
<watzon> I was trying to fix that issue by making sure that `self[0]` is an `Array`, but apparently the compiler doesn't care
<FromGitter>
<watzon> `[1, 2, 3]` should return `[3]`
<FromGitter>
<Blacksmoke16> and that isnt the same as just doing like `arr.last`?
<FromGitter>
<watzon> `[[1, 2], [1, 2]]` should return `[2, 2]`