ChanServ changed the topic of #crystal-lang to: The Crystal programming language | http://crystal-lang.org | Crystal 0.32.1 | 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
HumanG33k has joined #crystal-lang
Seich has quit [Remote host closed the connection]
mooe has joined #crystal-lang
f1refly has quit [Ping timeout: 248 seconds]
f1refly has joined #crystal-lang
ur5us has joined #crystal-lang
ur5us has quit [Ping timeout: 260 seconds]
<mooe> Is it possible to keep a Kemal request open without a loop? Express.js has a timeout variable you can set to infinity
<mooe> I’m trying to figure out how to implement SSE tied to redis pubsub
mooe has quit [Quit: Connection closed for inactivity]
return0e_ has joined #crystal-lang
return0e has quit [Ping timeout: 268 seconds]
mooe has joined #crystal-lang
ht_ has joined #crystal-lang
return0e_ has quit [Ping timeout: 265 seconds]
return0e has joined #crystal-lang
mooe has quit [Quit: Connection closed for inactivity]
alexherbo2 has joined #crystal-lang
<FromGitter> <Daniel-Worrall> hmm, can you have a generic class with a default?
<FromGitter> <Daniel-Worrall> Like `class Foo(T = Int32) ... Foo.new`
DTZUZO has quit [Read error: Connection reset by peer]
Human_G33k has joined #crystal-lang
DTZUZO has joined #crystal-lang
HumanG33k has quit [Ping timeout: 268 seconds]
<Yxhuvud> No
<raz> jesus freakin christ... crystal has ruined me... i can't handle javascript anymore
<FromGitter> <tenebrousedge> you could always use typescript, if sanity isn't a big priority for you
alexherbo2 has quit [Quit: The Lounge - https://thelounge.chat]
<f1refly> Honestly any other language will ruin javascript for you
<f1refly> even javascrip will ruin javascript for you
<FromGitter> <grkek> Crystal ruined me as well
<FromGitter> <grkek> and I fucking love it
<raz> yep, you're all correct. i just had to whine for a moment. sorry.
<FromGitter> <tenebrousedge> whining to a sympathetic audience is wonderfully cathartic
<FromGitter> <grkek> I went up and rewrote parts of Kemal framework to be more handler class oriented, rn the readme, specs and samples need updating but the source changed check it out if you guys have time for it :) https://github.com/grkek/grip
<FromGitter> <grkek> It is still a WIP tho
<FromGitter> <tenebrousedge> > Installation ⏎ ⏎ Add this to your application's shard.yml: ⏎ ⏎ dependencies: ... [https://gitter.im/crystal-lang/crystal?at=5dff9620e0131f50c98a1614]
<FromGitter> <Daniel-Worrall> readme should be a top priority. I have no idea what you've changed/will change or how to use or judge
<FromGitter> <tenebrousedge> ditto for that for me
<FromGitter> <grkek> Currently I am learning elixir as well with it so I don't really have time for it but I have an example
<FromGitter> <tenebrousedge> you should fix the obviously incorrect installation instructions at the very least
<FromGitter> <Daniel-Worrall> Name, installation, note of WIP
<FromGitter> <Daniel-Worrall> and logo
<FromGitter> <grkek> this is how it looks now
<FromGitter> <grkek> from sinatra like parts I only left before_all after_all and the error macro
<FromGitter> <tenebrousedge> you should definitely put that example in your readme
<FromGitter> <grkek> Do you like it ?
<FromGitter> <grkek> dependencies: ⏎ kemal: ⏎ github: grkek/grip
<FromGitter> <grkek> whopse
<FromGitter> <grkek> wait
<FromGitter> <grkek> dependencies: ⏎ grip: ⏎ github: grkek/grip
<FromGitter> <tenebrousedge> I suspect it would be better for large projects to use defined methods rather than `get 'route' do`
<FromGitter> <grkek> here is how you install it, sorry for the readme messup will fix it up later
<FromGitter> <grkek> I didnt like the sinatra way and I didnt like the monolithic amber framework I just wanted my classes to have functions like this
<FromGitter> <grkek> thank you for the feedback, I feel very happy now :D
<FromGitter> <tenebrousedge> :plus1:
<FromGitter> <Blacksmoke16> this setup is how athena works
<FromGitter> <Blacksmoke16> using methods on a controller class where each method is bound to a route
<FromGitter> <Blacksmoke16> you could use a macro to auto supply the array of handlers as well
<FromGitter> <Blacksmoke16> assuming each controller wouldn't have any arguments that the use would have to supply
<FromGitter> <grkek> I could supply the handlers using a macro but, the handlers might want some arguments
<FromGitter> <grkek> that is why I left them this way
<FromGitter> <tenebrousedge> I'm wary of athena's reliance on macros. Not that I have any relevant experience on the matter
<FromGitter> <Daniel-Worrall> macros are great and you should submit to them
<FromGitter> <Blacksmoke16> to be fair it doesnt use as many macros as you think
<FromGitter> <Blacksmoke16> is mainly just the 1 file that registers all the routes
<FromGitter> <tenebrousedge> but my not-macros 😢
<FromGitter> <tenebrousedge> I just want them to be like metaprogramming in Ruby :(
<FromGitter> <Daniel-Worrall> they're not like metaprogramming, they're more like code writing automation
<FromGitter> <Daniel-Worrall> ruby metaprogramming in crystal isn't achievable
<FromGitter> <tenebrousedge> ...that's what metaprogramming is
<FromGitter> <Daniel-Worrall> wellllll
<FromGitter> <tenebrousedge> I know it's not achievable, that's why I'm sad
<FromGitter> <tenebrousedge> macros are metaprogramming because their output is code
<FromGitter> <Daniel-Worrall> Yeah, sorry, I phrased my wording badly
<FromGitter> <Daniel-Worrall> They are metaprogramming, but they're not ruby-style metaprogramming
<FromGitter> <Daniel-Worrall> because ruby style is all runtime
<FromGitter> <Daniel-Worrall> it's like a pre-processor
<FromGitter> <tenebrousedge> I know :( there is no perfect language
_whitelogger has joined #crystal-lang
<FromGitter> <j8r> is there any compile-time safe language with meta-programing?
<FromGitter> <tenebrousedge> Crystal
<FromGitter> <grkek> https://github.com/grkek/grip
<FromGitter> <grkek> Updated the readme
<FromGitter> <grkek> still needs docs they will come soon
<FromGitter> <grkek> I also plan on changing up the websocket handlers to class oriented ones
<FromGitter> <tenebrousedge> :plus1:
<FromGitter> <grkek> <3
<FromGitter> <j8r> @tenebrousedge I mean, dynamic meta-programing?
<FromGitter> <tenebrousedge> maybe typescript
<FromGitter> <tenebrousedge> and isn't there a typed version of python ?
<raz> @Daniel-Worrall fwiw, i also missed some rubyisms early on (reflection, more flexible Hashes). but over time you discover more and more advantages in the rigidity that crystal has over ruby. the tasks for which i reach to ruby have become increasingly sparse. more often than not i'll try something out in pry. and then write it in crystal :D
<FromGitter> <tenebrousedge> `icr` is a reasonable replacement for pry for "Does this work the way I think it does?"
<raz> ah thx, i've yet to try that one out.
<FromGitter> <randiaz95> Hey guys, how are you guys feeling this holiday season
<FromGitter> <grkek> I am already ill @randiaz95 how about you :?
<FromGitter> <randiaz95> dang, lol
<FromGitter> <randiaz95> I feel bad and lethargic when I drink
<FromGitter> <randiaz95> so also ill lol
<FromGitter> <randiaz95> I am learning crystal while growing my dart programming skills
<FromGitter> <grkek> Want to see something interesting ?
<FromGitter> <randiaz95> ya
<FromGitter> <randiaz95> aslong as its not genitals
<FromGitter> <grkek> @randiaz95 https://github.com/grkek/grip its this :)
<FromGitter> <randiaz95> Wow! very nice
<FromGitter> <randiaz95> Dude that is pretty
<FromGitter> <grkek> thank you very much !
<FromGitter> <grkek> appreciated a lot
<FromGitter> <j8r> one little point: by using classes, it will puts more pressure on the GC
<FromGitter> <j8r> in this case structs may be better
<FromGitter> <grkek> Keep in mind that it is a class oriented
<FromGitter> <grkek> framework :)
<FromGitter> <randiaz95> lol
<FromGitter> <randiaz95> I think the benefits is that one can then have a controller object controlling those api objects
<FromGitter> <randiaz95> or maybe other types of patterns
<FromGitter> <Blacksmoke16> i mean it would work the same, just the memory of your controller objects would be allocated on the stack versus the heap
<FromGitter> <randiaz95> interesting to see how one can observe all the handler objects
<FromGitter> <Blacksmoke16> hm?
<FromGitter> <randiaz95> like an observer pattern
<FromGitter> <Blacksmoke16> but would you really want multiple methods listening on the same route?
<FromGitter> <grkek> @Blacksmoke16 Why not ?
<FromGitter> <randiaz95> it seems like you can track at a more detailed level
<FromGitter> <grkek> What if I want a get and a post on the same method ?
<FromGitter> <Blacksmoke16> i feel like that would be a bad practice
<FromGitter> <grkek> @Blacksmoke16 many frameworks do so, pick flask or django
<FromGitter> <grkek> for example
<FromGitter> <Blacksmoke16> is there actually a valid reason to want to do that versus "just because i can"
<FromGitter> <grkek> Readability
<FromGitter> <grkek> and also comfyness
<FromGitter> <randiaz95> no I think we are confused as to what we are talking about
<FromGitter> <randiaz95> are you saying the library itself or the observer pattern on the class
<FromGitter> <Blacksmoke16> im saying why would you want 1 method to handle both say POST and GET requests?
<FromGitter> <grkek> It is not in one method
<FromGitter> <randiaz95> Well, this library doesn't do that
<FromGitter> <grkek> it is distributed
<FromGitter> <randiaz95> exactly, there is a separate method for each type
<FromGitter> <grkek> Sorry I worded that wrongly, I meant the same route
<FromGitter> <grkek> :)
<FromGitter> <grkek> English is not my main language so it is no surprise I made a mistake
<FromGitter> <Blacksmoke16> np, that clears it up
<FromGitter> <randiaz95> ll
<FromGitter> <Blacksmoke16> mixing the logic of two separate routes in one method would be bad
<FromGitter> <grkek> You are the author of the athena framework
<FromGitter> <grkek> thats nice
<FromGitter> <randiaz95> He has Ethos
<FromGitter> <grkek> its in one class
<FromGitter> <randiaz95> and logos
<FromGitter> <grkek> not in one method
<FromGitter> <Blacksmoke16> yea for sure
<FromGitter> <Blacksmoke16> `GET /post` and `POST /post`
<FromGitter> <Blacksmoke16> as an example
<FromGitter> <grkek> If you define a post method for the /post it will execute the POST handler
<FromGitter> <grkek> I really don't understand what you mean by that
<FromGitter> <Blacksmoke16> was just finishing my thought that separate routes should be handled in separate methods, like how it works currently, versus having one method be executed on both routes
<FromGitter> <grkek> Oh nice, so far it has been slowly coming into shape, currently adding a way to handle the /:something/:someone
<FromGitter> <grkek> type of a situation with routes, how do you handle something like that ?
<FromGitter> <Blacksmoke16> in athena?
<FromGitter> <grkek> yeah
<FromGitter> <Blacksmoke16> athena uses https://github.com/amberframework/amber-router for routing
<FromGitter> <grkek> Kemal had its own but currently I am unable to implement it because of my laziness
<FromGitter> <grkek> Oh that is a nice router I must say
<FromGitter> <Blacksmoke16> athena just adds routes to amber router
<FromGitter> <Blacksmoke16> where the payload of the route is an obj that stores metadata about the route https://github.com/Blacksmoke16/athena/blob/rewrite/src/routing.cr#L70
<FromGitter> <grkek> I like the way you built it
<FromGitter> <Blacksmoke16> the route action is stored within the obj as well after being converted to a proc
<FromGitter> <Blacksmoke16> thanks :)
<FromGitter> <Blacksmoke16> amber router supports some stuff radix tree one kemal uses doesnt
<FromGitter> <Blacksmoke16> namely constraints and optional route sections
<FromGitter> <randiaz95> amber has cli stuff too that is more productive after the initial investment
<FromGitter> <Blacksmoke16> example being if you had a route `GET /user/:id`
<FromGitter> <Blacksmoke16> `GET /user/19` and `GET /user/foo` would both match
<FromGitter> <grkek> true
<FromGitter> <grkek> you want type checking with it ?
<FromGitter> <Blacksmoke16> but if you did like `GET /user/:id, constraints: {"id" => /\d+/}`
<FromGitter> <Blacksmoke16> `GET /user/19` would match while `GET /user/foo` would 404
<FromGitter> <grkek> oh that is a great idea
<FromGitter> <Blacksmoke16> i agree, is why i added it :)
<FromGitter> <Blacksmoke16> allows separate methods to "listen" on the same route, but handle diff cases
<FromGitter> <Blacksmoke16> for legacy reasons or whatever
<FromGitter> <Blacksmoke16> also supports optional segments
<FromGitter> <Blacksmoke16> so like `GET /posts(/:page)`
<FromGitter> <Blacksmoke16> would match both `GET /posts` and `GET /posts/2`
<FromGitter> <grkek> that is a bit weird
<FromGitter> <grkek> () does this even belong in the route side ?
<FromGitter> <Blacksmoke16> it just denotes that part of the route is optional in the router
<FromGitter> <grkek> oh lovely
<FromGitter> <randiaz95> do we just impeach people we don't like?
<FromGitter> <Blacksmoke16> lets not get started on that, way off topic and not the place to discuss it
<FromGitter> <Blacksmoke16> need to think how i want to handle configuration/parameters in athena
<FromGitter> <grkek> I am still stuck with the router
<FromGitter> <Blacksmoke16> going to switch from radix?
<FromGitter> <grkek> probably to amber router
<FromGitter> <grkek> what do you think ?
<FromGitter> <Blacksmoke16> prob doesnt matter either way
<FromGitter> <Blacksmoke16> if you want the extra 2 features of amber's router sure go for it
<FromGitter> <grkek> I am unable to connect the kemal router for sinatra like routes to the class router type
<FromGitter> <Blacksmoke16> would have to do something like define the route/methods in a class/instance method that can then be used to add the routes to the router
<FromGitter> <Blacksmoke16> like in your `add_handlers` thing
<FromGitter> <grkek> Thank you
<FromGitter> <Blacksmoke16> oh sorry, think i read that wrong
<FromGitter> <Blacksmoke16> you want to also support like
<FromGitter> <Blacksmoke16> ```get "/path" do ⏎ # do stuff? ⏎ end``` [https://gitter.im/crystal-lang/crystal?at=5dffdc2ac0c8ef301bf8d6e3]
<FromGitter> <grkek> No I want to get rid of that
<FromGitter> <grkek> but it has the /:id resoultion protocol
<FromGitter> <grkek> which is not present in the classed methods
<FromGitter> <Blacksmoke16> ah, radix tree should handle that for you?
<FromGitter> <Blacksmoke16> when a route gets matched there should be a like `params` obj on the payload iirc
<FromGitter> <grkek> I am currently trying to implement that
<FromGitter> <Blacksmoke16> :th\
<FromGitter> <Blacksmoke16> 👍
<FromGitter> <grkek> @Blacksmoke16 ```Which expanded to: ⏎ ⏎ > 7 | # @@routes.add class_name_method + "/", '/' + method_downcase + "/" ⏎ > 8 | ⏎ > 9 | Grip::RouteHandler::INSTANCE.add_route(method.upcase, "/", { |env| call(env) }) ... [https://gitter.im/crystal-lang/crystal?at=5dffe3dd49314a1d45c29512]
<FromGitter> <grkek> what does that even mean
<FromGitter> <grkek> sorry for the crappy formatting
ht_ has quit [Remote host closed the connection]
<FromGitter> <Blacksmoke16> maybe have an extra `}` at the end there?
<FromGitter> <Blacksmoke16> nvm thats a `)`
<FromGitter> <grkek> macro route(path, methods = ["GET"]) ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5dffe4c0c62fdf33f738a0aa]
<FromGitter> <Blacksmoke16> does `add_route` have a block?
<FromGitter> <grkek> yeah it takes in a block
<FromGitter> <grkek> it had &block before
<FromGitter> <Blacksmoke16> try like `.add_block(method.upcase, {{path}}) { |env| self.call(env) }`
<FromGitter> <grkek> def add_route(method : String, path : String, &handler : HTTP::Server::Context -> _) ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5dffe5448897197969df8fdf]
<FromGitter> <grkek> here is the add_route function itself
<FromGitter> <grkek> what am I doing wrong tho
<FromGitter> <Blacksmoke16> try what i suggested
<FromGitter> <Blacksmoke16> sorry it should be `.add_route(`
<FromGitter> <Blacksmoke16> think the issue is the comma after `{{path}}`
<FromGitter> <grkek> Are you sure ?
<FromGitter> <Blacksmoke16> no, but worth a shot :p
<FromGitter> <grkek> not working still
<FromGitter> <Blacksmoke16> what does it look like now/whats the error?
<FromGitter> <grkek> Which expanded to: ⏎ ⏎ > 2 | ["GET"].each do |method| ⏎ > 3 | @@handler_methods.push(method) ⏎ > 4 | Grip::RouteHandler::INSTANCE.add_route(method.upcase, "/", {|env| call(env)}) ... [https://gitter.im/crystal-lang/crystal?at=5dffe7c30cb24d1d44050279]
<FromGitter> <grkek> that is the error still
<FromGitter> <Blacksmoke16> doesnt look like you changed anything?
<FromGitter> <grkek> if I do what you said it just doesnt compile and throws a syntax error
<FromGitter> <Blacksmoke16> whats the error?
<FromGitter> <Blacksmoke16> `Grip::RouteHandler::INSTANCE.add_route(method.upcase, {{path}}) { |env| self.call(env) }`
<FromGitter> <grkek> Error: undefined method 'call' for IndexHandler.class
<FromGitter> <grkek> oh my now it seems to be working right ?
<FromGitter> <Blacksmoke16> the `self.call` might be not the right thing
<FromGitter> <grkek> I have a function in the class
<FromGitter> <grkek> which I want to execute
<FromGitter> <grkek> how do I do that without moving everything around ?
<FromGitter> <Blacksmoke16> when your macro expands you're not in an instance context so `self` refers to the class
<FromGitter> <grkek> Okay so when the macro expands I am out of the instance ?
<FromGitter> <grkek> oh my
<FromGitter> <Blacksmoke16> idk, im not familiar enough with how your thing works
<FromGitter> <Blacksmoke16> yes because the macro just expands into the class body
<FromGitter> <grkek> thank you for the help
<FromGitter> <Blacksmoke16> np
<FromGitter> <grkek> One quick question @Blacksmoke16 how do I access class instance variables from a macro ?
<FromGitter> <Blacksmoke16> you cant, would have to be accessed at runtime after the macro expands
<FromGitter> <grkek> oh my that sounds interesting
<FromGitter> <Blacksmoke16> to be clear in your example `@@handler_path = {{path}}` is setting a class var
<FromGitter> <Blacksmoke16> but its happening at runtime
<FromGitter> <grkek> I'll just move the add route to init that should be fine for it right ?
<FromGitter> <grkek> Oh no tons of recursions
<FromGitter> <Blacksmoke16> 😬