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
chachasmooth has quit [Ping timeout: 260 seconds]
chachasmooth has joined #crystal-lang
johnny101 has quit [Quit: ZNC 1.7.5 - https://znc.in]
johnny101 has joined #crystal-lang
<FromGitter> <MapMaths> Hi! I'm just learning Crystal. How to run Crystal in VSCode?
chachasmooth_ has joined #crystal-lang
chachasmooth has quit [Ping timeout: 240 seconds]
<FromGitter> <Blacksmoke16> like via a run button?
<FromGitter> <Blacksmoke16> assuming you can open a terminal just do `crystal src/my_app.cr`
johnny101 has quit [Quit: ZNC 1.7.5 - https://znc.in]
johnny101 has joined #crystal-lang
<FromGitter> <Blacksmoke16> hm?
<FromGitter> <MapMaths> Sorry
<FromGitter> <MapMaths> No, I've installed Crystal Language in VSCode, but it said "Crystal compiler not found. Some features can throw errors."
<FromGitter> <Blacksmoke16> :shrug:
<FromGitter> <Blacksmoke16> if you installed the plugin i also assume you'll need to have crystal itself installed in your system
<FromGitter> <MapMaths> How to install Crystal in Windows?
<FromGitter> <Blacksmoke16> Oof
<FromGitter> <Blacksmoke16> Use wsl
<FromGitter> <Blacksmoke16> It doesn't 100% support windows yet
<FromGitter> <MapMaths> All right
<FromGitter> <MapMaths> Thx
<FromGitter> <3n-k1> is there a list of things that need to be implemented for windows support?
<FromGitter> <Blacksmoke16> There's an issue for it yes
<FromGitter> <3n-k1> ah, ty
f1reflyylmao has joined #crystal-lang
f1refly has quit [Ping timeout: 264 seconds]
johnny101 has quit [Quit: ZNC 1.8.1 - https://znc.in]
johnny101 has joined #crystal-lang
johnny101 has quit [Quit: ZNC 1.8.1 - https://znc.in]
johnny101 has joined #crystal-lang
avane has quit [Quit: ZNC - https://znc.in]
avane has joined #crystal-lang
Vexatoast has quit [Quit: ZNC Quit]
Vexatos has joined #crystal-lang
teardown has joined #crystal-lang
johnny101 has quit [Quit: ZNC 1.8.1 - https://znc.in]
johnny101 has joined #crystal-lang
<FromGitter> <grkek> How does one convert string literal to a symbol?
<FromGitter> <HertzDevil> you can't during runtime
<FromGitter> <HertzDevil> `ASTNode` has `#symbolize` though
<FromGitter> <grkek> Hm
<FromGitter> <grkek> how would one use that
<FromGitter> <grkek> Haha
<FromGitter> <grkek> I was able to do it runtime
<FromGitter> <grkek> B-)
<FromGitter> <grkek> Aren't macros runtime?
<FromGitter> <grkek> Ah it is compile time
<FromGitter> <grkek> Interesting indeed
<FromGitter> <grkek> https://carc.in/#/r/9wj9
<FromGitter> <grkek> god damn it
<FromGitter> <HertzDevil> `string` is not a string literal
<FromGitter> <HertzDevil> that's expected
<FromGitter> <grkek> It is string tho
<FromGitter> <HertzDevil> it is a variable
<FromGitter> <HertzDevil> not a string literal
<FromGitter> <grkek> Ah so it has to be in a macro thingy
<FromGitter> <grkek> understandable
<FromGitter> <grkek> have a nice day
_whitelogger has joined #crystal-lang
Liothen has quit [Read error: Connection reset by peer]
Liothen has joined #crystal-lang
masterdonx2 has joined #crystal-lang
MasterdonX has quit [Ping timeout: 272 seconds]
_whitelogger has joined #crystal-lang
louis771 has joined #crystal-lang
<FromGitter> <confact> Is it any good way to remove decimals after say three on floats? I have a Float that looks like `0.05623423432` but I just want the float to be `0.056`
<raz> do you want to round or truncate?
<raz> for rounding: 0.05623423432.round(3) => 0.056
<jhass> confact: do you want to actually remove them for calculations or just for display?
_whitelogger has joined #crystal-lang
<FromGitter> <confact> @jhazz and @raz - I found it in the API spec just after I wrote it here so I just removed my message on gitter. It was round I was looking for. Thanks!
<FromGitter> <confact> Still have hard to find things in the API spec ;(
<raz> i wonder if crystal could get ruby's safe navigation operator. `foo&.bar` is just easier on the eyes than `foo.try &.bar`
<oprypin> raz, `try` is somewhat discouraged so it's ok
<oprypin> if foo; foo.bar
<raz> well, i have plenty cases where i just want to return nil when foo is nil
<raz> `if` would add a lot of noise there
<oprypin> definitely dont program in Go i guess ¯\_(ツ)_/¯
<raz> that's like saying we shouldn't aim for heaven because hell exists ¯\_(ツ)_/¯
f1refly has joined #crystal-lang
f1reflyylmao has quit [Ping timeout: 260 seconds]
alexherbo2 has joined #crystal-lang
<FromGitter> <j8r> why `try` is discouraged? It can prevents using intermediate variables
<FromGitter> <j8r> for example, `if (value = some_method) && value.empty?`, will become `some_method.try &.empty?`
<FromGitter> <Blacksmoke16> also helps with what `if var = ...` because that cant handle `false`
<yxhuvud> I find the current way encourages me to write better code. Which is odd as that wasn't the case in ruby before the &. operator was introduced. Perhaps because the compiler finds the ugly looking code for me while writing it the first time instead of only later when it breaks
<FromGitter> <j8r> btw, for me better using `if value = met` than `met.try do |value|`
<FromGitter> <Blacksmoke16> the former doesnt work if `met` can be `false`
<FromGitter> <Blacksmoke16> or `nil`
<FromGitter> <Blacksmoke16> i.e. `Bool?`
<FromGitter> <Blacksmoke16> but yea, most of the time i use the former
alexherbo2 has quit [Ping timeout: 272 seconds]
<FromGitter> <j8r> Indeed
<FromGitter> <j8r> I meant in the case of `SomeObject | Nil`
_whitelogger has joined #crystal-lang
<yxhuvud> Yeah, but how often do you actually have Boolean? types? And how often can you avoid it? I mean a value that can be true, false and nil is a mess anyhow.
<FromGitter> <Blacksmoke16> more so was thinking when the value is arbitrary, its an easy thing to forget about and an easy bug to introduce
<FromGitter> <Blacksmoke16> i.e. "x doesn't work when the value of y is `false`"
ua has quit [Ping timeout: 256 seconds]
<FromGitter> <j8r> I prefer to keep `try` for short one liner, personally
<FromGitter> <j8r> as yxhuvud said, it is very rare to have Bool | Nil types
<FromGitter> <j8r> not uncommon on the macro-land though
<FromGitter> <Blacksmoke16> id say its more common when the value is arbitrary, i.e. a default value to something
<FromGitter> <Blacksmoke16> versus a strict `Bool?` type
<raz> oprypin: re: "try is discouraged". how would you write this? https://carc.in/#/r/9wkd
<oprypin> raz, first of all, what's even the operation precedence there
<oprypin> ok it's `(@ivar.try &.downcase) == "x"`
<oprypin> yea i'd definitely write it like you did
<raz> see why i asked about ruby safe-nav operator now? ;)
<raz> with `@ivar&.downcase` at least there wouldn't be confusion about precedence
<oprypin> true
<oprypin> i had been bitten exactly by `try` + `==`. wish i'd remember what the situation was
<raz> if there's a completely different way to write this, i'd be all ears as well. it's just a super common one for me (nil'able ivars)
<raz> yup, precedence can be tricky, esp. when procs get involved
<FromGitter> <j8r> That's can be said for Ruby/Crystal in general when we omit parenthesis
<raz> but noodling everything up with braces & brackets doesn't make it much better
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5f9d8ccaf2fd4f60fc4629c1]
<raz> blacksmoke: make a copy every time, really?
<FromGitter> <j8r> a copy?
<raz> he copies ivar to str
<oprypin> with optimization it's not any more of a copy than the other way
<raz> for the reader it's a copy
<raz> not nice, esp. when multiple vars are involved
<FromGitter> <j8r> I thought before, but it is a reference. Not need to copy if the value doesn't change
<raz> well yea, i'm about readability, not performance
<oprypin> copy of the reference anyway
<raz> s/copy/clutter/
<raz> blacksmoke: make a clutter every time, really? :p
<FromGitter> <Blacksmoke16> just pointing out that there are other ways of writing it, its not like `.try` is the only way
<FromGitter> <Blacksmoke16> depends on the actual context outside of a contrived example
<FromGitter> <j8r> raz: Ruby/Crystal is probably not for your if you like parenthesis for functions
<raz> yeh, i like try anyway. my question from earlier was just if we could get `foo&.bar` like ruby. to make it nicer
<FromGitter> <Blacksmoke16> thats a no from me
<raz> so we're gonna write `foo.try &.bar` forever?
<FromGitter> <Blacksmoke16> for how often i need to use it, sure
* raz sad keyboard noises
<FromGitter> <j8r> It could become `foo.try&.bar`
<FromGitter> <j8r> but not `foo&.bar`
<raz> hmm, is it specific about the &?
<FromGitter> <Blacksmoke16> in crystal land that the block shortcut
<raz> i'd also be happy with `foo^.bar` if that helps
<FromGitter> <Blacksmoke16> versus in ruby its `&:bar`
<FromGitter> <Blacksmoke16> 👎
<FromGitter> <Blacksmoke16> that also wouldnt work as that would be interpreted like `foo ^ bar`
<FromGitter> <Blacksmoke16> which is already an operator
<raz> well, i'm not gonna try all letters now, but surely there must be on left that we don't use?
<jhass> § should be relatively free
<oprypin> jhass, that one isnt on any of the good keyboard layouts
<jhass> hence it's available :P
<raz> how about `foo.?.bar`
<oprypin> foo⌥bar
<FromGitter> <Blacksmoke16> foo ❓ bar
<FromGitter> <Blacksmoke16> make it be emojis
<oprypin> raz, not bad actually. not that anyone's gonna mess with approving such a syntax
<raz> don't underestimate my annoyance with `.try &.`
<raz> i need it so often and it hurts every time, grr
<FromGitter> <Blacksmoke16> i think i used it like twice so far
<FromGitter> <Blacksmoke16> maybe try to make this not nilable as much?
<raz> i have a feeling you may start changing your mind when you add ORM to athena ;) (models with nil'able attrs are pretty common)
<FromGitter> <Blacksmoke16> right, so?
<raz> well, in many scenarios `try` is just the most concise way to deal with them
<raz> imho it's a perfectly fine pattern, just the current syntax isn't nice
<FromGitter> <Blacksmoke16> fair
<FromGitter> <Blacksmoke16> Athena does have an ORM, its just not public and highly WIP :P
<raz> remind me to mock you when it reaches the stage where .try starts to annoy you :P
<FromGitter> <Blacksmoke16> is pretty neat tho, granted only things you can do are save/select/update/delete stuff
<FromGitter> <Blacksmoke16> no relationships or anything fancy ha
<raz> ow, careful there. you'll need those. and then you're in the middle of inventing your own
<raz> why not go with clear/jennifer/granite or such?
<FromGitter> <Blacksmoke16> they have issues, prob coming from a Ruby approach to ORMs
<FromGitter> <Blacksmoke16> mainly just not a fan of how the model itself controls its persistence
<raz> well, yea they do. but building a new one from scratch is quite a task. i'll be looking forward to athena 1.0 in 2030 then :P
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5f9d922bc6fe0131d4c8c0de]
<FromGitter> <Blacksmoke16> is how its setup atm :shrug:
<FromGitter> <Blacksmoke16> was more of a proof of concept :p
<raz> does look nice, yup
<FromGitter> <Blacksmoke16> main benefit is the entity is just a class
<FromGitter> <Blacksmoke16> no extra ivars or anything added to it
alexherbo24 has joined #crystal-lang
<raz> yea, i suppose if you throw a whole ORM at it, you could perhaps even sidestep the try-issue :D
<FromGitter> <Blacksmoke16> i mean thats more of a thing for the user
<FromGitter> <Blacksmoke16> the orm doesnt really need to worry about that
alexherbo2 has quit [Read error: Connection reset by peer]
alexherbo24 is now known as alexherbo2
<raz> yeh, wasn't really serious about that. don't think the orm can actually remove the need for nil'able attrs.
<FromGitter> <Blacksmoke16> nope, esp if they're actually nilable in the db
<FromGitter> <Blacksmoke16> uses a separate type to keep track of the entities, and uses the repo pattern
<raz> yup, stuff just sometimes needs to be nil'able. even my favorite, the tri-state boolean.
<FromGitter> <Blacksmoke16> so if you do like `em.find User, 1` then do it again it only makes 1 db query since the entity manager already has the entity with that PK value so can return that cached obj
<FromGitter> <Blacksmoke16> also keeps track of changes so the `UPDATE` query only updates changed columns, not everyone
<FromGitter> <Blacksmoke16> every column*
<FromGitter> <Blacksmoke16> ran into some compiler bugs and implementation decisions so its on the back burner ha
<raz> yup, well, it's a huge rabbit hole
<raz> anyway, to wrap this up. i vote for `.?.` for try and `.!.` for not_nil!
<raz> then we can be the coolest language in town again
alexherbo2 has quit [Ping timeout: 264 seconds]
alexherbo2 has joined #crystal-lang
alexherbo2 has quit [Ping timeout: 260 seconds]
louis771 has quit [Quit: WeeChat 2.9]
<FromGitter> <HertzDevil> i personally wish that null pointers do not pass `try`
<FromGitter> <HertzDevil> and also that `ASTNode#try` exists (it would be called on every node except `NilLiteral` and possibly `NopLiteral`)
<jhass> null pointers is easy to fix: struct Pointer(T); def try; yield self unless null? end; end
<FromGitter> <HertzDevil> i'd argue that `try` should accept precisely the truthy values but that'd probably upset people who use `try` on booleans
alexherbo2 has joined #crystal-lang
<Andriamanitra> fwiw i think "x.try(&.downcase)" makes it a lot clearer what's going on than something like "x.?.downcase" especially if there are multiple method calls chained inside try
alexherbo21 has joined #crystal-lang
alexherbo2 has quit [Ping timeout: 246 seconds]
alexherbo21 is now known as alexherbo2
<frojnd> I have 2 crystal apps one is command line... It also has a neaty function I would like to call inside another crystal app what would be the appropriate way to use it in second app?
<FromGitter> <Blacksmoke16> separate app meaning like diff repo? or just a diff binary?
<frojnd> Currently just 2 different binaries.. each in it's repo (locally)
<FromGitter> <Blacksmoke16> if they're separate projects prob a private shard to share between them
<FromGitter> <Blacksmoke16> otherwise just extract the method to a common file to include in both
<frojnd> They are separate projects... So any recommendations on private shards
<FromGitter> <Blacksmoke16> recommendations for what?
<frojnd> Oh.. reading
<frojnd> I know how to include shard from git.. is private the same just local path?
<FromGitter> <Blacksmoke16> granted it doesnt even have to be private, esp if the end code is open source
<FromGitter> <Blacksmoke16> hold on, is this code going to be open source, or is it for a private/personal project or something?
<frojnd> Just for private personal project as I am diving into crystal lang..
<frojnd> At least for now
<FromGitter> <Blacksmoke16> are the 2 projects related? like is the one just a cli front to the other?
<frojnd> No... they are not related. One project has specific functionality (it's just a cli) that I would use in another.
<frojnd> I'm complicating things I can just call system("crystal run another-project") or just use code from first project in second
<FromGitter> <Blacksmoke16> how big is this method?
<FromGitter> <Blacksmoke16> easiest solution would just be duplicate it and call it a day, otherwise have some helper shard you can require in both projects
<frojnd> It's not that big...
<frojnd> But helper shard reads something I could learn
<FromGitter> <Blacksmoke16> i mean its not something really special
<FromGitter> <Blacksmoke16> just a shard that you add as a dependency to both other projects
<FromGitter> <j8r> Shards can be cloned with ssh, therefore they can be private
alexherbo25 has joined #crystal-lang
alexherbo2 has quit [Read error: Connection reset by peer]
alexherbo25 is now known as alexherbo2
HumanG33k has quit [Remote host closed the connection]
HumanG33k has joined #crystal-lang
<FromGitter> <j8r> raz: it will be too confusing, an actually `.!.` is already a thing
<FromGitter> <j8r> `var.!` works, and `var.?` is too close of `var?`. ⏎ The good point of the `try` method, it is a method. It does not extend the language nor complicate it
<raz> j8r: hm, what does `var.!` do? i'll admit `var?` vs `var.?` may have too much bug-potential. but i still think `.??.` would be better than `.try &.` (just need to find something unambiguous for ??. well... maybe it could literally be ?? ?) ;)
<FromGitter> <Blacksmoke16> pretty sure `var.!` is the same as `!var`
<raz> well, i find that even more confusing than using `.!.` for not_nil :P
<raz> the nice thing about ruby's save-nav is how unobtrusive it is. would just be nice to have something similar in crystal, since the workarounds all tend to be rather verbose
<FromGitter> <Blacksmoke16> prob could just define that method yourself :p
<FromGitter> <Blacksmoke16> ah nvm, cant start with `?`
deavmi has quit [Remote host closed the connection]
<raz> yeh, wouldn't want to tweak my env like that anyway. if i want to bake my own language i'll go lisp ;)
deavmi has joined #crystal-lang
<FromGitter> <j8r> raz: On my I suggested `#not(Nil)` to replace `not_nil!` ;)
<raz> well, i'm less annoyed by not_nil. it's kinda ugly, but at least there's no confusion about precedence / curly brace gymnastics
<FromGitter> <j8r> *On my side, missed a word
<raz> yup i suppose not(Nil) would at least look less scary (but also more noisy visually)
<raz> given how frequently those two are needed i'd prefer if they'd blend in more with the normal syntax. atm they feel like a wart every time. and then you try the alternative and it looks even worse ;)
<FromGitter> <j8r> Also, I think it could be defined in `Union` and not `Object`
<FromGitter> <j8r> nevermind, I just rember how it is implemented
<FromGitter> <j8r> I'm tired, gonna go
<raz> nn!
<FromGitter> <j8r> That's a downside, talking to americans from Europe can easily slip to late hours
* raz sad european noises
<raz> yup, near midnight here :D
<FromGitter> <j8r> Just tested, does not work to add instance methods to Union :(
<FromGitter> <j8r> also an issue with `not_nil!` is its the unhelpful `NilAssertionError` message
<FromGitter> <j8r> Why `hash.each` yields a tuple of key/value, and not just a key and value?
ua has joined #crystal-lang
<FromGitter> <j8r> It could also be more efficient to avoid creating a tuple on each iteration, too
ua has quit [Ping timeout: 258 seconds]
early has quit [Quit: Leaving]
alexherbo2 has quit [Read error: Connection reset by peer]
early has joined #crystal-lang
alexherbo2 has joined #crystal-lang
ua has joined #crystal-lang
oprypin has quit [Quit: Bye]
oprypin has joined #crystal-lang
_whitelogger has joined #crystal-lang
<FromGitter> <wyhaines> hash.each yielding a tuple of key/value was a fun thing for me last week. I've been working on a Splay Tree implementation that, as much as possible, conforms to the Hash ducktype, while at the same time implementing a couple niceties with #new -- it can populate a new tree from anything that implements #each, basically. ⏎ ⏎ The fact that array each yields it's value directly, but hash each yields
<FromGitter> ... Tuple(K,V) was a surprise that took some thinking and tinkering to come up with an acceptable approach that didn't have frustrating typing side effects. ⏎ ⏎ In reading all of the Hash code, I think that I see the logic behind it, but still...it wasn't what I expected when I captured the args with a splat. [https://gitter.im/crystal-lang/crystal?at=5f9dfa467cac87158f7b6c3f]