ChanServ changed the topic of #crystal-lang to: The Crystal programming language | https://crystal-lang.org | 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
ua_ has joined #crystal-lang
<SamantazFox> Hello!
<FromGitter> <Blacksmoke16> o/
<SamantazFox> How is it possible to clean the temporary object files?
<SamantazFox> I.e, is there some `make distclean` equivalent?
<FromGitter> <Blacksmoke16> not sure i follow, where do you see those?
<SamantazFox> Codegen (bc+obj):
<SamantazFox> - 618/1531 .o files were reused
<FromGitter> <Blacksmoke16> ah, probably want to clear cache then
<SamantazFox> where is it?
<SamantazFox> I don't see any .lob or .obj dir
<FromGitter> <Blacksmoke16> `crystal env`
<FromGitter> <Blacksmoke16> usually `$HOME/.cache/crystal` at least for me on Arch
<SamantazFox> ok, thanks, that's it :)
<FromGitter> <Blacksmoke16> `crystal env CRYSTAL_CACHE_DIR` even better
<SamantazFox> that would be cool if that could be a CLI option
<FromGitter> <Blacksmoke16> to clear cache? or to set the location of the cache?
<SamantazFox> to clear the cache
<SamantazFox> because having to find the cache folder, then the right subfolder for the project is not so intuitive
<FromGitter> <Blacksmoke16> is there a reason you need to clear it? I only had to a handful of times, and that was just for benchmarking stuff
<SamantazFox> benchmarking compile times is one thing, yeah
<FromGitter> <Blacksmoke16> could go bump that issue. would be trivial to add and provide a system agnostic way to do it
<SamantazFox> Also, there should be, like with any other language, a way to start in a clean state
<SamantazFox> because very odd bugs can appear after a few version jumps (especially when developping) and switching refs in git
<FromGitter> <Blacksmoke16> also related: https://github.com/crystal-lang/crystal/issues/9314
<SamantazFox> Lengthy discussion, lol
ur5us__ has quit [Ping timeout: 248 seconds]
SamantazFox has quit [Killed (NickServ (GHOST command used by SamantazFox_))]
SamantazFox_ has joined #crystal-lang
HumanG33k has quit [Ping timeout: 272 seconds]
human_g33k has joined #crystal-lang
ur5us__ has joined #crystal-lang
ur5us__ is now known as ur5us
ua_ has quit [Read error: Connection reset by peer]
brokkoli_origin has joined #crystal-lang
brokkoli_origin has quit [Quit: Leaving]
ua_ has joined #crystal-lang
ur5us has quit [Ping timeout: 272 seconds]
ua_ has quit [Excess Flood]
ua_ has joined #crystal-lang
ua_ has quit [Excess Flood]
ua_ has joined #crystal-lang
hightower4 has joined #crystal-lang
<hightower4> Hey do I see/remember it right that when capturing &blocks in method defs, the proc can't be optional? Like, in `def x(&bl : Proc(Nil))`, the Proc(Nil) can't be made optional with Proc(Nil)? ?
debayer has joined #crystal-lang
debayer has quit [Quit: Textual IRC Client: www.textualapp.com]
notzmv has quit [Ping timeout: 256 seconds]
ur5us has joined #crystal-lang
<straight-shoota> hightower4, yes that is correct. A method with a block always needs to be called with a block.
<straight-shoota> You can add a second overload without a block parameter
<hightower4> danke schoen
<straight-shoota> bitte
<straight-shoota> The non-block overload can have a nilable proc parameter and you just pass the captured block from the other overload
<straight-shoota> >> def foo(&block : Proc(Nil); foo(block); end; foo(proc : Proc(Nil)? = nil); proc.try &.call; end; foo; foo { "hello" }
<DeBot> straight-shoota: Error: expecting token ')', not ';' - https://carc.in/#/r/bqkt
<straight-shoota> >> def foo(&block : Proc(Nil)); foo(block); end; foo(proc : Proc(Nil)? = nil); proc.try &.call; end; foo; foo { "hello" }
<DeBot> straight-shoota: Error: expecting token 'EOF', not 'end' - https://carc.in/#/r/bqku
<straight-shoota> >> def foo(&block : Proc(Nil); foo(block); end; def foo(proc : Proc(Nil)? = nil); proc.try &.call; end; foo; foo { "hello" }
<DeBot> straight-shoota: Error: expecting token ')', not ';' - https://carc.in/#/r/bqkv
<straight-shoota> >> def foo(&block : Proc(Nil)); foo(block); end; def foo(proc : Proc(Nil)? = nil); proc.try &.call; end; foo; foo { "hello" }
<DeBot> straight-shoota: # => nil - https://carc.in/#/r/bqkw
notzmv has joined #crystal-lang
ur5us has quit [Quit: Leaving]
ur5us has joined #crystal-lang
ur5us has quit [Ping timeout: 256 seconds]
straight-shoota has quit [*.net *.split]
yxhuvud has quit [*.net *.split]
fifr[m] has quit [*.net *.split]
mookie has quit [*.net *.split]
kevinsjoberg has quit [*.net *.split]
FromGitter has quit [*.net *.split]
repo has quit [*.net *.split]
dostoyevsky2 has quit [*.net *.split]
cfebs has quit [*.net *.split]
jrayhawk has quit [*.net *.split]
DeBot has quit [*.net *.split]
Welog has quit [*.net *.split]
oz has quit [*.net *.split]
Stephie has quit [*.net *.split]
frojnd has quit [*.net *.split]
straight-shoota has joined #crystal-lang
yxhuvud has joined #crystal-lang
jhass[m] has quit [Ping timeout: 240 seconds]
Stephie has joined #crystal-lang
frojnd has joined #crystal-lang
fifr[m] has joined #crystal-lang
mookie has joined #crystal-lang
kevinsjoberg has joined #crystal-lang
FromGitter has joined #crystal-lang
oz has joined #crystal-lang
Welog has joined #crystal-lang
repo has joined #crystal-lang
dostoyevsky2 has joined #crystal-lang
cfebs has joined #crystal-lang
jrayhawk has joined #crystal-lang
DeBot has joined #crystal-lang
dostoyevsky2 has quit [Max SendQ exceeded]
dostoyevsky2 has joined #crystal-lang
fifr[m] has quit [Ping timeout: 256 seconds]
jhass[m] has joined #crystal-lang
SamantazFox_ is now known as SamantazFox
fifr[m] has joined #crystal-lang
<raz> man, clear orm & crystal are a joy to work with. takes some time to rattle things into place, but then nested transactions, jsonb, pg arrays, custom pg func's, squeaky clean specs with rollback etc. all works flawlessly. having implemented this stuff in a bunch of languages the crystal impl is by far my fav now.
<FromGitter> <Blacksmoke16> now just pair that with athena and get magically (de)serialization/validation of your models 😉
<raz> https://carc.in/#/r/bqlk <- spec helper for debug-logging-only-on-error and tx rollback
<raz> I::Wanted::To::Like::Athena::I::Really::Tried :P
<raz> If::Only::It::Wasnt::So::Damn::Verbose
<FromGitter> <Blacksmoke16> i'm open to feedback but you actually have to bring things up
<raz> well it's not bad, for big apps/teams that can be just right.
<FromGitter> <Blacksmoke16> the aliases should help with the verbosity of the types, but thats moreso a product of Crystal
<raz> yea, verbosity was more an alias for all the contextual knowledge you need to get started beyond the basics
<raz> i don't think there's really a way to "fix" that easily. there's just a new class/abstraction to learn at every step.
<FromGitter> <Blacksmoke16> every framework is going to have that to a degree
<raz> yup. grip = small degree. athena = full degree ;)
<raz> each has its place
<raz> it's great that crystal has both
<FromGitter> <Blacksmoke16> also prob doesnt help it doesnt follow the `HTTP::Handler` middleware approach all the others do
<FromGitter> <Blacksmoke16> i imagine thats the main area thats takes some learning
<raz> yup, and arguably something like lucky is even more opaque / magical
<raz> at least in athena all the springs and cogs are out in plain sight
<FromGitter> <Blacksmoke16> lucky really likes their macros
<raz> yup, guess it counts as a third philosophy. athena makes you write like java. lucky like lucky. and well, grip is pretty much just crystal with some helpers.
<FromGitter> <Blacksmoke16> ehh i wouldnt directly compare it to java just because it makes you use interfaces
<FromGitter> <Blacksmoke16> thats a good design principle regardless ;P
<raz> well, if someone comes from java-spring i'd send them straight to athena. approach is pretty similar i think, not in a bad way :)
<raz> inject all them dependencies! ;)
<FromGitter> <Blacksmoke16> im still curious how lucky handles that kind of stuff
<FromGitter> <Blacksmoke16> grip just doesnt afaik, which is probably fine given its purpose
<raz> i've never used lucky enough to really know. it's probably great when you want to build your app exactly the lucky-way. but custom-everything down to the orm always makes me feel a bit uneasy (there's always some detail that i want different, and usually the claim "works with any orm" only means that in principle it does - but hardly anyone ever tries it ;))
<FromGitter> <eliasjpr> Question: Ruby has `Raise` and `Fail` keywords, Crystal has `raise`. While ruby makes no distinctive difference between raise and fail implementation. I wonder if there is an opportunity to implement fail in Crystal as in Panic in go? @straight-shoota @asterite
<FromGitter> <Blacksmoke16> there was a forum thread about that iirc
Guest79 has joined #crystal-lang
<straight-shoota> fail != throw
<FromGitter> <Blacksmoke16> oh, but `throw` is also a thing in Ruby?
<straight-shoota> yes
<straight-shoota> throw and catch is about passing control without an error status
Guest79 has quit [Client Quit]
<straight-shoota> that's similar to goto I guess
<straight-shoota> raise/fail and rescue are about signaling errors
<straight-shoota> The implementation of raise and fail is identical, so the only difference is implied semantics
hightower4 has quit [Ping timeout: 268 seconds]
<straight-shoota> @eliasjpr As far as I understand, Go's panic is actually pretty similar to raise. Recovery is just very weird.
<straight-shoota> What would you want to have in Crystal? IMO Crystal's raise/rescue is like Go's panic/recover just better.
<FromGitter> <djberg96> Crystal's [insert whatever] is like Go's [anything] just better
<FromGitter> <eliasjpr> @straight-shoota basically Panic errors are not expected to be handled/recover from and should exit the program
<FromGitter> <eliasjpr> while raise is used in the same context it is used as error handling (flow)
<straight-shoota> Go has raise?
<FromGitter> <eliasjpr> I was wondering if having a Panic like (fail) is worth for language semantics
<FromGitter> <eliasjpr> Go has error instead of raise
<FromGitter> <eliasjpr> https://gobyexample.com/panic
<FromGitter> <eliasjpr> https://gobyexample.com/errors
<straight-shoota> error is just a return value. There's nothing special about it in the language.
<straight-shoota> And panic is just like raise. And it's possible to recover from a panic, using the recover keyword. So that's like rescue in Crystal/Ruby
<FromGitter> <eliasjpr> Go’s approach makes it easy to see which functions return errors and to handle them using the same language constructs employed for any other, non-error tasks
<straight-shoota> Yeah. You can actually do the same in Crystal if you want.
<straight-shoota> Maybe it could even be better with union types *shrug*
<FromGitter> <eliasjpr> I guess one can have a Error struct that does not inherit from Exception and raise it
<straight-shoota> If you want a struct, yes. If you're happy with a class, you can just return an Exception instance
<FromGitter> <eliasjpr> Exception builds stack traces, while the Error struct/class does not. Am I assuming correct?
<FromGitter> <eliasjpr> I guess raise always builds a stack trace
<FromGitter> <eliasjpr> In regards to Panic it is very similar to Raise
<straight-shoota> A callstack is only created when raised
<straight-shoota> You can even disable that by assigning an empty callstack before that
<FromGitter> <eliasjpr> Really!!!
<FromGitter> <eliasjpr> thats neat
<FromGitter> <eliasjpr> should that be an overload `raise` method?
<straight-shoota> yeah, either a custom raise method or a custom exception class that assigns an empty array on initialization
<FromGitter> <eliasjpr> maybe would be good to add an overload raise(exception : Exception, callstack = true)
<FromGitter> <eliasjpr> for usability/visibility
<straight-shoota> I don't think this is really a great idea though
<straight-shoota> You gain a little speed but lose debug information
<FromGitter> <eliasjpr> well this can be something that probable should be turned on at the process level
<straight-shoota> For signalling expected application errors this might be fine, but everything that's out of a normal state, you'd be happy to have a callstack when debugging
<FromGitter> <eliasjpr> like we do with logging
<FromGitter> <eliasjpr> DEBUG=true
<straight-shoota> yes, that should work
hightower2 has joined #crystal-lang
<FromGitter> <eliasjpr> also wouldn't be more safe for the program to not default to print/build callstack traces for prod apps
<straight-shoota> But if you really want to skip that for performance reasons, I would go the entire way and not use raise at all
hexology- is now known as hexology
<FromGitter> <eliasjpr> I think security is a good reason
<straight-shoota> What kind of security?
<FromGitter> <eliasjpr> a lot of hacks happens because exposure of the call stack
<FromGitter> <eliasjpr> Error values do not expose the call stack
<straight-shoota> But where/how is the call stack exposed?
<FromGitter> <eliasjpr> in the logs, io etc no?
<straight-shoota> But that could be handled at that point: don't print the callstack to the logs if you don't want that
<FromGitter> <eliasjpr> maybe I don't understand enough 😅
<straight-shoota> Raising the exception just collects the callstack. It doesn't publish it anywhere, it's just attached to the exception object.
<straight-shoota> Of course, you can't accidentally disclose something that isn't even there. And if you don't use the callstack at all, it's probably useful to just skip creating it.
<straight-shoota> But callstacks are just so important for hunting bugs.
<straight-shoota> If something goes wrong, you need to know where and how the program got there
<FromGitter> <eliasjpr> Would you agree then maybe is worth to have `raise(exception : Exception, callstack: true)`?
<straight-shoota> I don't see a use case for that in stdlib
<FromGitter> <eliasjpr> Agree about the bugs and callstack, but only then is needed
<straight-shoota> If you want that behaviour, you can just add the method in your codebase
<FromGitter> <eliasjpr> Got it. I was just wondering if it was worth to have and explore the thought
<FromGitter> <eliasjpr> Thanks it is always good to cross check. Thank you for the clarification
<straight-shoota> Sure =)
<straight-shoota> Exploring thoughts is always helpful
<straight-shoota> I'm just stating my opinion, maybe others would want to have that in stdlib...
<FromGitter> <eliasjpr> yeah, hopefully it will inspire a conversation at the least
<raz> stdlib needs `@[NoRaise]`. that's what stdlib needs, yup yup. for full error control bliss. i'd love for it to be called "@[GoLangMode]" but that probably violates some trademark.
yxhuvud has quit [Read error: Connection reset by peer]
yxhuvud has joined #crystal-lang
avane has joined #crystal-lang
notzmv has quit [Ping timeout: 248 seconds]
notzmv has joined #crystal-lang
<FromGitter> <asterite> There's abort and exit in Crystal. I'm not sure non recoverable exceptions are desireable
<yxhuvud> I could see a use for a methodthat kill the current fiber, in a controlled way. It could be nice for implementing cancellation.
<yxhuvud> regardless of discussion on if outside forceful cancellation should be a thing.
<yxhuvud> And that is basically a nonrecoverable exception, even if it perhaps doesn't take the same code paths.
<yxhuvud> But that is a topic for #6468 :)
<DeBot> https://github.com/crystal-lang/crystal/issues/6468 ([RFC] Structured Concurrency)
<raz> shouldn't it be Fiber#raise (to raise an exception inside the fiber)? hard stopping a fiber from the outside at a random point without allowing it to cleanup sounds like a last-resort kinda thing
<yxhuvud> shrug. It doesn't need to come from the outside.
hightower2 has quit [Remote host closed the connection]
<raz> hm, but if a fiber wants to stop itself, it could just do the same - raise an exception?
* raz scratches head
ur5us has joined #crystal-lang
<straight-shoota> @asterite I don't think we need non-recoverable exceptions either. But exception that are not rescued by a default `rescue` might be nice (i.e. you can recover but you need to explicitly ask for that).
<FromGitter> <Blacksmoke16> couldn't that just be another type
<FromGitter> <Blacksmoke16> like `MyError < Error` wouldn't be caught by `rescue e : Exception` but would if you did `rescue e : Error` or `rescue e : Raisable`
<FromGitter> <riffraff169> say, i have an expression where a = b or c, like the c trinary: `a = (x < 0) ? b : c`
<FromGitter> <riffraff169> is there an idiom for that? you can do an if/else, so i was doing a = if b.....
<FromGitter> <riffraff169> or is there a better way....like this:
<FromGitter> <Blacksmoke16> whats wrong with `a = (x < 0) ? b : c`?
<straight-shoota> @Blacksmoke16 Yes, exactly. It would just need an exception type above the one that's the default for an untyped `raise`
<FromGitter> <riffraff169> ah so crystal does have the trinary, ill use that
<FromGitter> <riffraff169> must have missed it
<FromGitter> <Blacksmoke16> ternary but yes ;P
<FromGitter> <riffraff169> ah yes that too
<FromGitter> <riffraff169> cool, that reads better to me than assigning the result of an if/else to a var
<FromGitter> <Blacksmoke16> @straight-shoota thats exactly what PHP did as well
<FromGitter> <Blacksmoke16> `Throwable` is implemented by `Error` and `Exception`
<FromGitter> <riffraff169> which worked, but playground indents it wrong
<straight-shoota> Yeah, that's in part modeled after the Java exception hierarchy IIRC
<FromGitter> <Blacksmoke16> looks like its exactly the same ha
<FromGitter> <Blacksmoke16> least the top most ones
ua_ has quit [Ping timeout: 248 seconds]
<SamantazFox> Hello!
<SamantazFox> I'm playing with annotations (expecially JSON::Field() and YAML::Field() converters) and I've been looking around for hours at that problem
<SamantazFox> is there a way to handle nicely the conversion of JSON/YAML to enums (so {"theme": "Dark"} gives Theme::Dark), without having to re-define a full converter each time to handle bad data (e.g {"theme": "invalid"})?
ua_ has joined #crystal-lang
<FromGitter> <Blacksmoke16> im pretty sure you can just type that field as the enum and it should just work
<SamantazFox> Blacksmoke16, ok, so it works fine with JSON, but not YAML
<FromGitter> <Blacksmoke16> Oh?
<SamantazFox> https://bpa.st/6YRA
ua_ has quit [Ping timeout: 248 seconds]
<SamantazFox> if you ever want to eval, you'll need to set MAX_ITEMS_PER_PAGE = 40 at the top of the file
<SamantazFox> (or whatever value, that's not important)
<FromGitter> <Blacksmoke16> I think your yaml is just invalid
<SamantazFox> (forgot to force push, oops)
<SamantazFox> better
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/bqpl
<FromGitter> <Blacksmoke16> YAML is just invalid
ua_ has joined #crystal-lang
<FromGitter> <Blacksmoke16> you prob want `---\ntheme: toto\n` not `---\theme: toto\n`
<SamantazFox> Yeah, just realized that
<SamantazFox> thanks :D
<FromGitter> <Blacksmoke16> np
<SamantazFox> I wasted what, 6h on that? xDDD
<FromGitter> <Blacksmoke16> f
<SamantazFox> wait
<SamantazFox> Haaaaa
<SamantazFox> it's not theme, it's dark_mode (I reverted that)
<SamantazFox> So here is the proper error message: https://bpa.st/QVUA
<SamantazFox> Dark/Light/Auto works, anything else is Unhandled exception: Unknown enum Settings::Themes value
<FromGitter> <Blacksmoke16> so?
<FromGitter> <Blacksmoke16> that's not a valid enum member
ur5us has quit [Ping timeout: 252 seconds]
<SamantazFox> yes, and the error is not caught, except by making a converter per enum
<FromGitter> <Blacksmoke16> caught by what?
<FromGitter> <Blacksmoke16> you'd have to catch it wherever you're deserializing the data
<SamantazFox> oof :c
<SamantazFox> I was hoping that it could be ignored, kinda like it's done with unknown fields
<FromGitter> <Blacksmoke16> you could prob user a converter, but make it generic
jcs has left #crystal-lang [#crystal-lang]