ChanServ changed the topic of #crystal-lang to: The Crystal programming language | http://crystal-lang.org | Crystal 0.34.0 | Fund Crystal's development: http://is.gd/X7PRtI | GH: https://github.com/crystal-lang/crystal | Docs: http://crystal-lang.org/docs/ | API: http://crystal-lang.org/api/ | Gitter: https://gitter.im/crystal-lang/crystal
<FromGitter> <Blacksmoke16> @naqvis https://gitter.im/crystal-lang/crystal?at=5eaf166d97338850a2e5777c related to this, but for the serialization side of things
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5eb7498f5cd4fe50a3fe650a]
<FromGitter> <Blacksmoke16> or probably should just not include them in output in the first place
<FromGitter> <Blacksmoke16> but how would i know...
<FromGitter> <Blacksmoke16> would need to know if a specific value is a class/struct and doesnt include the module
deavmi has quit [Ping timeout: 256 seconds]
deavmi has joined #crystal-lang
<FromGitter> <watzon> Kinda cool way to get inputs as a hash https://asciinema.org/a/XBeErWWDxqHD4rhPsd8XHjWbM
<FromGitter> <Blacksmoke16> enat
<FromGitter> <Blacksmoke16> neat
<FromGitter> <watzon> Pretty easy API too ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5eb757353d58de7a3806c9e9]
<FromGitter> <watzon> Lol I liked "enat" better
<FromGitter> <Blacksmoke16> some fingers are faster than others
deavmi has quit [Read error: Connection reset by peer]
deavmi has joined #crystal-lang
renich has quit [Quit: renich]
deavmi has quit [Ping timeout: 256 seconds]
woodruffw has joined #crystal-lang
deavmi has joined #crystal-lang
deavmi has quit [Quit: No Ping reply in 180 seconds.]
deavmi has joined #crystal-lang
<FromGitter> <krthr> Hi
<FromGitter> <Blacksmoke16> o/
<FromGitter> <krthr> A few days ago I started writing a library to create blocks that execute a function and connect to each other. ⏎ ⏎ Block A, B ⏎ A.run(Input) ⏎ B.run(A.output) ... [https://gitter.im/crystal-lang/crystal?at=5eb76af597338850a2fb1e53]
<FromGitter> <Blacksmoke16> just use procs?
<FromGitter> <krthr> Yup. I'm using Procs... I want to make something like (simple version of) of n8n or IFTTT
<FromGitter> <Blacksmoke16> whats an example of the API you want?
<ryanprior> Sounds cool krthr. I've done similar things using channels.
<ryanprior> If you write your blocks/components to take an input channel and output channel as arguments, then you can chain things up and create all sorts of cool little pipelines.
<FromGitter> <krthr> For example, providing the posibility to build a flow (visual programming) and executing it in the back. I could use it in my company...
<FromGitter> <Blacksmoke16> i mean example code
<FromGitter> <Blacksmoke16> like what is `A`?
<FromGitter> <krthr> > *<ryanprior>* If you write your blocks/components to take an input channel and output channel as arguments, then you can chain things up and create all sorts of cool little pipelines. ⏎ ⏎ Yeah. That's the idea... And it would also be cool to publish different blocks with different functions. For example: send a mail, get a file, consume http, etc.
<FromGitter> <Blacksmoke16> cant just implement something like https://crystal-lang.org/api/master/HTTP/Handler.html
<FromGitter> <Blacksmoke16> each handler could accept some context/command object
<FromGitter> <Blacksmoke16> and be chained together like a pipeline
<FromGitter> <Blacksmoke16> ```pipeline = Pipeline.new([ ⏎ SendMail.new, ⏎ DoRequest.new ⏎ ])``` [https://gitter.im/crystal-lang/crystal?at=5eb76d5bd898fe7a3778b6fe]
<FromGitter> <krthr> > like what is `A`? ⏎ ⏎ A is a Block. A contains a proc that receives an input and when executed returns an output. ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5eb76d8a7975db7ebff65099]
<FromGitter> <krthr> > ``` ⏎ > pipeline = Pipeline.new([ ⏎ > SendMail.new, ⏎ > DoRequest.new ⏎ > ]) ... [https://gitter.im/crystal-lang/crystal?at=5eb76da05cd4fe50a3fea976]
<FromGitter> <krthr> > each handler could accept some context/command object ⏎ ⏎ Yup. That's the idea
<FromGitter> <Blacksmoke16> https://tactician.thephpleague.com/ something like this then?
<FromGitter> <Blacksmoke16> crystal version of it at least
<ryanprior> krthr: it would be cool to have a puredata-type interface to (specially prepared, probably) crystal objects.
<FromGitter> <krthr> > cant just implement something like https://crystal-lang.org/api/master/HTTP/Handler.html ⏎ ⏎ I'll keep an eye on it... thank you very much!
<FromGitter> <krthr> > https://tactician.thephpleague.com/ something like this then? ⏎ ⏎ Let me see. I was thinking in: https://n8n.io/ It is build in Nodejs
alexherbo2 has joined #crystal-lang
<FromGitter> <watzon> Sometimes it really would be helpful to have a `block_given` or be able to say `if block ... else ... end`
alexherbo2 has quit [Ping timeout: 260 seconds]
alexherbo2 has joined #crystal-lang
<oprypin> @watzon: i find that almost all of those cases are actually something else missing from the language
<oprypin> so the duality of yielding functions and arrays
<FromGitter> <damianham> Thanks everyone for taking the time to consider this and for your responses, much appreciated.
alexherbo2 has quit [Ping timeout: 264 seconds]
<FromGitter> <watzon> Really what I find coming up again and again is that occasionally I want the Opti n of having a block, without forcing the user to pass a block. Instead what I'm ending up with is a lot of duplicate code because any method I want to do that with I have to make 2 versions of. One with a block and one without.
<jhass> can you just make the without block version call the with block one with an empty block?
_ht has joined #crystal-lang
<raz> ^ that's exactly what i do every time
<raz> and agree having &block? would be nicer
<raz> that's a syntax change i would vote for
<raz> (the empty-block variant isn't terrible verbosity-wise, but i imagine it also incurs a slight runtime overhead for the empty call)
<oprypin> you can do this thru macros, but you probably know
zorp has joined #crystal-lang
<raz> yeh i never tried that. should just be a language feature imho (although not the most urgent one for me personally)
alexherbo2 has joined #crystal-lang
alexherbo2 has quit [Quit: The Lounge - https://thelounge.chat]
hightower4 has quit [Remote host closed the connection]
<FromGitter> <naqvis> Yeah make sense to mark that prop as null in output json.
<FromGitter> <naqvis> it would be neat if primitives or value types can be given default values and reference types as nil (even if they don't include ASR::Serializable) module.
<FromGitter> <naqvis> and for reference types, you can check if they implement `ASR::Serializable` module, if so then delegate the (de)serializable to that
<FromGitter> <naqvis> this is how golang handle such cases.
<FromGitter> <Blacksmoke16> sadly that would also exclude some primitive types, like `Array` or `String`
sz0 has quit [Quit: Connection closed for inactivity]
<FromGitter> <naqvis> so you think having a kind of cascading effect better here?
<FromGitter> <naqvis> in your sample case, as Bar is opted for this, so that means all objects inside Bar opt for this?
<FromGitter> <naqvis> including the Foo
<FromGitter> <naqvis> this is how Crystal deal with this, but it fails if composed child doesn't respond to `to_json` call
<FromGitter> <naqvis> and my thought is that, we shouldn't be restricting this functionality in a way current Crystal implementation is doing that
<FromGitter> <naqvis> take golang as an example
<FromGitter> <Blacksmoke16> i was doing it on a per type basis, so `Bar` opts in, `Foo` does not
<FromGitter> <naqvis> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5eb802347a24ff01b013676c]
<FromGitter> <Blacksmoke16> but i cant tell a `String` or `Foo` apart since they both inherit from `Reference`. I suppose i could add some other module/annotation to primitive types, but that seems meh
<FromGitter> <naqvis> this is because Foos is a value type, but if we change that to reference type, output will show `{"id":1,"foo":null}`
<FromGitter> <Blacksmoke16> yea i think im fine with this
<FromGitter> <naqvis> i mean, we should treat Reference types as `null` if that specific type doesn't implement `ASR::Serializable`
<FromGitter> <naqvis> but for primitives or value types, you can go with default values
<FromGitter> <Blacksmoke16> just dont have a way to know an actual class from one thats in the stdlib, like string
<FromGitter> <Blacksmoke16> but having it be null, and paired with exclusion strategies, is fine
<FromGitter> <naqvis> yeah agree
<FromGitter> <Blacksmoke16> always can iterate later
<FromGitter> <naqvis> i mean lib shouldn't be that much strict to raise exception if some obj doesn't implement (de)serializable intf
<FromGitter> <naqvis> stdlib imo is all or nothing, but we could have gone differently and output what responds to `to_json` and leave others out
<FromGitter> <naqvis> but i might not have better understanding of decision behind stdlib impl
<FromGitter> <Blacksmoke16> deserialization side of things deserializes as it builds out the obj
<FromGitter> <Blacksmoke16> which is a bit diff than how i set things up
<FromGitter> <naqvis> true and I totally understand
<FromGitter> <naqvis> during deserialization code can raise exception if something not following the contract
<FromGitter> <Blacksmoke16> yup
<FromGitter> <Blacksmoke16> next up is converters, prob use the stdlib approach with class methods on modules, then you can use generics and such
<FromGitter> <Blacksmoke16> also allower calling setters
<FromGitter> <naqvis> what if there is no setter defined, will code raise? or just ignore?
<FromGitter> <Blacksmoke16> sorry, by defaults ivars are set directly
<FromGitter> <Blacksmoke16> but plan is you can specify a setter, that would get the value if you wanted to do other stuff with it
<FromGitter> <Blacksmoke16> same idea with getters on serialization, default is use ivar directly, but could go thru getter
<FromGitter> <naqvis> so rely on init method to initialize all of them?
<FromGitter> <naqvis> and call setter later (if there are any)?
<FromGitter> <Blacksmoke16> prob something like that yea, thats how it works yea
<FromGitter> <naqvis> aah gotcha, sorry I was thinking in terms of `reflection`
<FromGitter> <naqvis> and I realize crystal doesn't support reflection
<FromGitter> <Blacksmoke16> add some if logic in there to check if the property has a setter defined in the annotation, and if so use that
<FromGitter> <naqvis> yeah, setting ivar directly might break some logic
<FromGitter> <naqvis> so believe it should be better to call setters for props which have implemented them
<FromGitter> <naqvis> as some codes might need to perform some logic in setters
<FromGitter> <naqvis> but this will add complexity to your library
<FromGitter> <Blacksmoke16> not too much i dont think
<FromGitter> <naqvis> as you can't call setters in constructor if irc
<FromGitter> <Blacksmoke16> hm, moment
<FromGitter> <naqvis> because the object isn't completely initialized and calling instance methods yields undefined behavior
<FromGitter> <Blacksmoke16> rip yea good point
<FromGitter> <naqvis> lol
<FromGitter> <Blacksmoke16> still not terrible, set ivar directly then call setter with that value :p
<FromGitter> <naqvis> yeah, and it will make deserialization two steps
<FromGitter> <naqvis> init props with no setter defined
<FromGitter> <naqvis> call setter on props
<FromGitter> <Blacksmoke16> to be clear i was imagining something like
<FromGitter> <Blacksmoke16> ``````
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5eb809b6a9de3d01b1fda32f]
<FromGitter> <Blacksmoke16> so setter stuff is opt in
<FromGitter> <Blacksmoke16> but default is set ivars directly
<FromGitter> <naqvis> 👍
<FromGitter> <Blacksmoke16> setters like that are prob not as common as the default ones made by `property` and such
<FromGitter> <naqvis> but you would have to call these setters after init is done
<FromGitter> <nothratal> is there a tendency in the development environment in crystal? What Editor are you using? Is there already something with code completion?
<FromGitter> <naqvis> yeah true, but good thing is that shard is offering them to call custom setters (if any code has some specific logic need to be run in setter)
<FromGitter> <naqvis> i mean its always good to offer functionality other than simply making the assumption or enforcing the rules on users of library
<FromGitter> <naqvis> 👍
<FromGitter> <Blacksmoke16> essentially im thinking logic in code would be like
<FromGitter> <Blacksmoke16> ```@{{ivar.id}} = value ⏎ ⏎ if setter = prop.setter ⏎ setter.call value ⏎ end``` [https://gitter.im/crystal-lang/crystal?at=5eb80af331a6d25d7cbf4687]
<FromGitter> <naqvis> yeah, but question is where will you call setter?
<FromGitter> <Blacksmoke16> gets set twice but :shrug:
<FromGitter> <Blacksmoke16> in the initializer?
<FromGitter> <naqvis> i mean, you shouldn't be calling that in constructor
<FromGitter> <Blacksmoke16> no?
<FromGitter> <naqvis> because in init, obj is not yet initialized
<FromGitter> <naqvis> so calling method might yield strange behavior
<FromGitter> <Blacksmoke16> ah true, if the setter was using another ivar
alexherbo2 has joined #crystal-lang
<FromGitter> <naqvis> yeah
<FromGitter> <naqvis> i would say it should be here
<FromGitter> <naqvis> so i said, it will be two pass process for deserialization
<FromGitter> <naqvis> 1) init
<FromGitter> <naqvis> 1) call setters
<FromGitter> <naqvis> just my thoughts
<FromGitter> <Blacksmoke16> hmm, how does the stdlib do it
<FromGitter> <naqvis> stdlib does the ivar assignment
<FromGitter> <naqvis> don't remember seeing it does call any setter
<FromGitter> <Blacksmoke16> it uses converters
<FromGitter> <naqvis> aahh
<FromGitter> <Blacksmoke16> like `.from_json` on a module that gets passes the pull parser
<FromGitter> <naqvis> that's different
<FromGitter> <naqvis> converters are class methods
<FromGitter> <Blacksmoke16> wouldnt run into this issue doing that since you dont have access to other ivars anyway
<FromGitter> <naqvis> and not instance methods
<FromGitter> <Blacksmoke16> yea, same concept tho
<FromGitter> <naqvis> so you mean `@[ASR::Accessor(setter: set_name)]` will be static methods?
<FromGitter> <naqvis> or class methods?
<FromGitter> <Blacksmoke16> no was thinking it would be instance methods
<FromGitter> <naqvis> yeah, but calling instance methods from inside init?
<FromGitter> <naqvis> i mean wouldn't that yield undefined behavior?
<FromGitter> <Blacksmoke16> i would have to i think, otherwise i lose the reference to the prop/value, esp if they aren't exposed with a getter
<FromGitter> <Blacksmoke16> i just use sublime with crystal plugin
<FromGitter> <naqvis> yeah
<FromGitter> <Blacksmoke16> i think it could, but wouldnt it also be not a good practice to set more than 1 ivar in the same setter?
<FromGitter> <naqvis> i just did a quick test and compiler won't let call instance method, until unless all ivars are initialized
<FromGitter> <Blacksmoke16> there will also me callbacks that run after deserialization is complete, so you could do stuff there as well
<FromGitter> <naqvis> that's great
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5eb80e0f7a24ff01b013822e]
<FromGitter> <naqvis> then you will drop this `Accessor` annotation?
<FromGitter> <Blacksmoke16> i think ill keep it, or at least try to
<FromGitter> <naqvis> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5eb80e3c14b48f0698c020de]
<FromGitter> <naqvis> this won't compile
<FromGitter> <naqvis> until unless all of the ivars are initialized in init
<FromGitter> <Blacksmoke16> mm yea, ill need to think about this more
<FromGitter> <naqvis> yeah sure
<FromGitter> <Blacksmoke16> well do i even need this anymore?
<FromGitter> <Blacksmoke16> given you cant even do it normally, its prob not a big deal
<FromGitter> <Blacksmoke16> esp with the post deserialize callback
<FromGitter> <naqvis> i would say no, as you are offering hooks pre/post, so it should be fine
<FromGitter> <naqvis> i mean needn't to bother with mutators at this stage
<FromGitter> <naqvis> but for sure, could be great feature left for later versions
<FromGitter> <naqvis> personally I like your thoughts on providing that mutator methods, as that give impression of kind of reflection
<FromGitter> <Blacksmoke16> new plan
<FromGitter> <naqvis> but I also understand, most of the time deserialization would just expect the obj to be created with data populated and dev can call other logics when needed
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5eb8128cf0377f16317c3f0a]
<FromGitter> <Blacksmoke16> contrived example, but it shows the point
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5eb812be9f0c955d7db7a076]
<FromGitter> <naqvis> bingo
<FromGitter> <naqvis> this is awsome
<FromGitter> <naqvis> so it does work in init call?
<FromGitter> <Blacksmoke16> yea, it would all it after https://github.com/athena-framework/serializer/blob/develop/src/athena-serializer.cr#L183-L194 this block
<FromGitter> <Blacksmoke16> might also throw in a `converter` option into the annotation, for the purpose of the module based approach
<FromGitter> <Blacksmoke16> so common logic could be shared?
<FromGitter> <naqvis> 👍
<FromGitter> <Blacksmoke16> will see how it goes
<FromGitter> <naqvis> this is already awsome
<FromGitter> <Blacksmoke16> <3
<FromGitter> <Blacksmoke16> @watzon i hope you just call the block version from the non block version?
HumanGeek has joined #crystal-lang
Human_G33k has quit [Ping timeout: 264 seconds]
<FromGitter> <nothratal> @Blacksmoke16 how is it with autocompletion? E.g. if I type: ⏎ ⏎ ```3.``` ⏎ ⏎ do I get suggestions like ```times```? [https://gitter.im/crystal-lang/crystal?at=5eb81bee7975db7ebff7c71e]
<FromGitter> <nothratal> in my experience this rocket starts the learning process
<FromGitter> <Blacksmoke16> it doesn't, would have to run something else to support it
<FromGitter> <nothratal> What is this "something else" in this case? :P
<FromGitter> <Blacksmoke16> https://crystal-lang.org/api/ is your friend in this regard
<FromGitter> <Blacksmoke16> https://github.com/crystal-lang-tools/scry however i never used it so gl :p
<FromGitter> <nothratal> ok, I tried scry already. It's really not that helpful or I just didn't configured it the right way
<FromGitter> <nothratal> I'll try again
<FromGitter> <Blacksmoke16> 👍
<FromGitter> <naqvis> @nothratal afaik till now there are no such tool/extension which offers that much autocompletion for crystal
<FromGitter> <naqvis> so as Blacksmoke16 said, `api docs` are your best friend
<FromGitter> <naqvis> at least that's the case with me, i've api docs opened and available everytime i'm coding in crystal lol
<FromGitter> <watzon> > @watzon i hope you just call the block version from the non block version? ⏎ ⏎ @Blacksmoke16 generally yes
<FromGitter> <nothratal> @naqvis isn't this very time consuming?
<FromGitter> <Blacksmoke16> not really, go to `String`, ctrl+f what you want
<FromGitter> <Blacksmoke16> usually finds it pretty quick
<FromGitter> <naqvis> in the beginning yes, but once you know api/library, its just much better than scrolling through autcompletion list 😆
<FromGitter> <naqvis> sometime I found autocompletion list most annoying
<raz> i use vim and vscode (with vim emu), they're both doing pretty well with crystal
alexherbo2 has quit [Ping timeout: 260 seconds]
alexherbo2 has joined #crystal-lang
alexherbo2 has quit [Client Quit]
<FromGitter> <alex-lairan> caddy looks promising.
<FromGitter> <alex-lairan> I just want something that works now, a PoC then change, and Caddy is on my list for now :)
<sorcus> Hi.
<sorcus> Why `Array.from_json(string_or_io, &)` implemented, but not `Set.from_json(string_or_io, &)`?
<FromGitter> <naqvis> because JSON doesn't have set
<FromGitter> <naqvis> its Array and dictionaries
<sorcus> naqvis: Ok, thank you :-)
<FromGitter> <naqvis> i would assume, that's the reason stdlib doesn't have that
<FromGitter> <Blacksmoke16> It just doesn't have the block version
<FromGitter> <Blacksmoke16> Set.from_json(string_or_io) would work
<FromGitter> <watzon> Then someone can write something better than Caddy in Crystal 😉
<sorcus> watzon: But Crystal doesn't have an actual HTTP/2 implementation...
<FromGitter> <watzon> Yet at least
<sorcus> watzon: Except this implementation - https://github.com/ysbaddaden/http2 But @ysbaddaden said `it's no longer actively developed.`
<FromGitter> <watzon> What we need is to get something merged into the standard library
<FromGitter> <naqvis> it was updated recently for Crystal 0.34, so its kind of being updated/maintained
<FromGitter> <naqvis> i would say at this moment, this would be the best bet if one want to use http2 functionality in crystal 😄
<FromGitter> <kinxer> Is there a way to run `crystal spec` without control characters in the output (e.g. waiting until all specs have run to output)?
<FromGitter> <kinxer> That is, terminal control character/sequences.
<oprypin> kinxer, `export TERM=dumb`
<FromGitter> <kinxer> Perfect. Thank you.
<FromGitter> <Blacksmoke16> `--no-color` would prob do it too
<FromGitter> <kinxer> Since I'm using it on TIO, `--no-color` is actually even better (since I understandably can't just inject env variables into a TIO run).
<FromGitter> <kinxer> For reference, this was for a code golf solution (link (https://codegolf.stackexchange.com/questions/204434/mowing-the-grass/204578#204578)). I've been occasionally making solutions in Crystal with the dual goal of short code (as usual for code golf) and exhibiting Crystal's clarity for readers.
<oprypin> 👏
<FromGitter> <j8r> @kinxer could use `&.` shortband instead of `{|s| s.`
<jhass> j8r: no, s is referenced twice
<jhass> but gsubbing first is still two shorter https://s.diaspora.software/3r
<FromGitter> <kinxer> Ooh, that's clever.
<jhass> tried finding a short application of the modulo trick the others have been using but couldn't
<jhass> the -1 kills it, otherwise it could be slightly shorter
zorp has quit [Ping timeout: 256 seconds]
<sorcus> Good night :-)
_ht has quit [Quit: _ht]
<FromGitter> <bew> jhass that tio website is gold, it has the options like footer to put spec, compiler args, etc.. that I always wanted to have on carc.in ^^ I wonder why it's only the first time I've seen it
<jhass> first for me too, just got it from the codegolf thread above
<oprypin> crystal vversion 0.31.1 tho
<oprypin> https://tio.run/ 0.31.1 ; https://repl.it/ 0.27.2 ; https://glot.io/ 0.25.0
<oprypin> all of these allow customizing command line and multiple files or inputs
<oprypin> repl.it also has persistent file system
<oprypin> alas, the versions
yxhuvud has quit [Read error: Connection reset by peer]
yxhuvud has joined #crystal-lang
<FromGitter> <Blacksmoke16> @naqvis ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5eb8947eb6dd230697bb528a]
<FromGitter> <Blacksmoke16> maybe i should pass it the property object, and data. type is kinda assumed id think
<FromGitter> <Blacksmoke16> `def self.deserialize(metadata : ASR::PropertyMetadataBase, data : ASR::Any) : String` yea thats more useful