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> <randiaz95> For example: ⏎ Go ⏎ ⏎ ```output = [e+1 for e in a]``` [https://gitter.im/crystal-lang/crystal?at=5e9b9498d240da243382cd92]
<FromGitter> <randiaz95> or ⏎ ruby ⏎ ⏎ ```output = a.map{|e| e+1}``` [https://gitter.im/crystal-lang/crystal?at=5e9b94ae8e987f3a5e298c7a]
<FromGitter> <randiaz95> Also note the prominence in python because there are less non-alphanumeric characters
<FromGitter> <dscottboggs_gitlab> @watzon I was thinking more along the lines of being able to declare a dynamic class in crystal than a whole other language written in crystal. If you declare the types/names on the class, they get statically assigned, otherwise they get stuffed in a `Hash(String, SomeAnyType)`
<FromGitter> <tenebrousedge> ruby `a.map(&:succ)`
<FromGitter> <randiaz95> Y can't you use ruby for that purpose?
<FromGitter> <randiaz95> ruby + crystal
<FromGitter> <dscottboggs_gitlab> you could access them like in JS with `.[](String)` or with dot notation using `macro method_missing`
<FromGitter> <randiaz95> Ruby would be way better than any scripting lang you make because of the number of gems
<FromGitter> <randiaz95> OMG, would it be impossible to combine all the syntaxes of all the most popular languages into one?
<FromGitter> <randiaz95> so that they compile/interpret together?
<FromGitter> <dscottboggs_gitlab> hypothetically... it's a lot of work though
<FromGitter> <randiaz95> ```output = [e+1 for e in a] ⏎ puts output``` [https://gitter.im/crystal-lang/crystal?at=5e9b9557c7dcfc14e2cdaf50]
<FromGitter> <tenebrousedge> I was going to say yes it's impossible, but doesn't emacs and jupyter do something like that?
<FromGitter> <dscottboggs_gitlab> @randiaz95 for example, there's https://www.boost.org/doc/libs/1_66_0/libs/python/doc/html/index.html
<FromGitter> <dscottboggs_gitlab> everything can talk to each other in theory though C but you have to convert native types to C types and then into the native type of the target langauge, for each language
<FromGitter> <dscottboggs_gitlab> ☝️ April 18, 2020 8:03 PM (https://gitter.im/crystal-lang/crystal?at=5e9b9557c7dcfc14e2cdaf50) but no you can't do that 😂
<FromGitter> <tenebrousedge> you can get pretty close to that with jupyter, pretty sure
<FromGitter> <dscottboggs_gitlab> yeah but that's more like....idk what that is lol
<FromGitter> <randiaz95> lol
<FromGitter> <randiaz95> The true rosetta stone
<FromGitter> <dscottboggs_gitlab> I mean, there's the CLR and JVM
<FromGitter> <dscottboggs_gitlab> oh, and LLVM, although that's less for what you're talking about
<FromGitter> <randiaz95> Isn't assembly just that?
<FromGitter> <randiaz95> Just not within a single document
<FromGitter> <dscottboggs_gitlab> no, assembly is a (*semi*) human-readable version of machine instructions.
<FromGitter> <dscottboggs_gitlab> it's literally just "you can write XYZ instead of 0xD9
<FromGitter> <randiaz95> all we need is an AI that can read line by line to classify it into a language then create a flat-file with the correct extension then run the correct compiler.
<FromGitter> <watzon> As is most bytecode. Techincally you can write JVM bytecode by hand, it's just a pain in the ass.
<FromGitter> <randiaz95> and then connect the data with flat files also.
<FromGitter> <watzon> Golang has it's own bytecode too
<FromGitter> <dscottboggs_gitlab> JVM, CLR, and LLVM are an intermediary step that compiles to many types of machine language
<FromGitter> <dscottboggs_gitlab> @randiaz95 you're talking about a decompiler I think?
<FromGitter> <dscottboggs_gitlab> @watzon of course, golang couldn't resist yet another backwards design decision 😂
<FromGitter> <dscottboggs_gitlab> Crystal, Rust, and others all compile to LLVM bytecode and then pass that to LLVM for compilation to various architecture's machine code. That doesn't mean they can interop any more than with with C types, because that's basically what LLVM understands
<FromGitter> <dscottboggs_gitlab> so like in crystal you can do ⏎ ⏎ ```code paste, see link``` ⏎ ⏎ and then you could call func and access Strukt from C, C++, Rust, Go, etc. The hard part becomes translating from some arbitrary class (like Array or String) into the Extern struct and vice-versa on the other end [https://gitter.im/crystal-lang/crystal?at=5e9b97d48e987f3a5e29929d]
<FromGitter> <dscottboggs_gitlab> oh, and you can interop with Ruby, Python, or NodeJS in the same way
<FromGitter> <dscottboggs_gitlab> eh...python might require some C boilerplate...
<FromGitter> <dscottboggs_gitlab> fuckin `PY_DECREF` and shit....lol
<FromGitter> <randiaz95> Lol
<FromGitter> <randiaz95> Don't hate on Python
<FromGitter> <randiaz95> It's my main b^tch
<FromGitter> <dscottboggs_gitlab> same, still hate the underlying C code...
<FromGitter> <dscottboggs_gitlab> ugly AF
<FromGitter> <Blacksmoke16> but python*
* FromGitter * tenebrousedge hates on Python
* FromGitter * tenebrousedge is a hater
<FromGitter> <dscottboggs_gitlab> @watzon too haha
<FromGitter> <randiaz95> lol
* FromGitter * tenebrousedge has drunk the haterade
* FromGitter * dscottboggs_gitlab doesn't like it either
<FromGitter> <randiaz95> i can do 99% of everything in python without looking any docs r stackoverflow
<FromGitter> <randiaz95> its my pseudocode and scripting lang
<FromGitter> <dscottboggs_gitlab> still write it all the time, but only because I have limited options at work.
<FromGitter> <randiaz95> Me 2 all my jobs py
<FromGitter> <dscottboggs_gitlab> > its my pseudocode and scripting lang ⏎ ⏎ Ah, that's crystal for me
blassin has joined #crystal-lang
<blassin> hello all
<FromGitter> <randiaz95> Hi
<FromGitter> <randiaz95> Scott wut domain r u focused in?
<FromGitter> <dscottboggs_gitlab> o/
<FromGitter> <dscottboggs_gitlab> I work for a robotics company but I'm building a webapp for internal tooling
<blassin> I'm trying to create a web server with Crystal - my particular issue now is to send a reload command to the browser when one of the files on the server is changed
<FromGitter> <watzon> I don't hate Python as much as I use to, but it's still not my favorite
<FromGitter> <randiaz95> embedded coding is bad in py
<blassin> is it possible to add a WebSocketHandler to the server that receives on a channel and sends a message to the browser?
<FromGitter> <watzon> Yes, very
<FromGitter> <randiaz95> I work in data science stuff.
<FromGitter> <randiaz95> for marketing
<FromGitter> <dscottboggs_gitlab> blassin, yes
<FromGitter> <randiaz95> Essentially I know how to optimize advertizemend Media mix portfolios
<FromGitter> <tenebrousedge> @watzon when did you become a robofox?
<FromGitter> <watzon> Recently haha, my sister made it
<blassin> are there any examples? the docs on WebSocketHandler are really sparse :|
<FromGitter> <randiaz95> Blassin i recommend looking at kemal
<FromGitter> <watzon> Yeah websockets still need some work imo
<FromGitter> <dscottboggs_gitlab> what server library are you using? Stdlib or some library?
<FromGitter> <randiaz95> https://kemalcr.com/
<blassin> I'm not using Kemal. I'm writing a static site generator and I just want to serve the local Markdown files as rendered HTML
<blassin> I *almost* got it working with SSE.cr but Firefox barfs at it :(
<FromGitter> <dscottboggs_gitlab> @randiaz95 sounds like interesting work
<FromGitter> <randiaz95> Why are you using websockets then?
<blassin> it's either SSE or WS for browser notifications, right?
<FromGitter> <dscottboggs_gitlab> he wants to reload the page if it changes
<FromGitter> <randiaz95> oh..
<FromGitter> <dscottboggs_gitlab> blassin, yes
<FromGitter> <dscottboggs_gitlab> can I see a sample of what you have so far?
<blassin> not ready for consumption yet, it's a mess :D
<FromGitter> <randiaz95> Why over complicate it?
<blassin> ?
<FromGitter> <randiaz95> It doesn't need secure sockets right?
<blassin> they don't have to be secure
<blassin> just ws://
<blassin> no need for wss://
<blassin> it's a local server anyway - SSL for localhost is tricky
<FromGitter> <randiaz95> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5e9b9c4647110862054195ea]
<blassin> I'm not using Kemal
<FromGitter> <randiaz95> You can also use my template for golang for front end
<FromGitter> <randiaz95> https://github.com/randiaz95/ws
<FromGitter> <randiaz95> it has all of the client js functions
<FromGitter> <dscottboggs_gitlab> blassin, have you seen https://crystal-lang.org/api/0.34.0/HTTP/Server.html#handler-chain
<blassin> my question is if it's possible to interact with a WebSocketHandler to ping the client after the server is running
<FromGitter> <randiaz95> Sure
<FromGitter> <randiaz95> Thats what it's for
<FromGitter> <dscottboggs_gitlab> yep
<blassin> any examples?
<FromGitter> <dscottboggs_gitlab> @randiaz95 he doesn't have to use Kemal if he doesn't want haha
<FromGitter> <randiaz95> ok, so in client js you listen to messages from the server
<blassin> yes
<FromGitter> <randiaz95> you can initiate a message if you have events in your server.
<blassin> and I want to ping the client that is connected when a file on the server is changed
<blassin> what I have now is a fiber running a file checker that pings a channel when there's a change
<blassin> ideally the WSHandler would listen on a channel and ping the client
<blassin> but I'm pretty sure Handlers can' have blocking calls like `receive`
<blassin> right?
<FromGitter> <randiaz95> You can do events or just send a post request from the script that is modifying the file
<blassin> how so?
<FromGitter> <randiaz95> I did this in node once, but I haven't looked into the events code in crystal yet, let me google the docs for events.
<FromGitter> <dscottboggs_gitlab> I'm looking at the source code to figure this out, blassin. If you just add a WebSocketHandler to a
<blassin> even outside of my use case - how do we ping the client using Websockets once a web server is running?
<blassin> I can't find good examples
<FromGitter> <dscottboggs_gitlab> server it will pass the websocket session to and request/response context to the block
<blassin> that are not loops with sleep 1
<FromGitter> <dscottboggs_gitlab> there's nothing wrong with `Fiber.sleep 1`
<FromGitter> <randiaz95> (script changes file and then does http.POST to some route ) -> (post endpoint then sends websocket send to broadcast the data to all of the channels ) -> (client then receives message)
<FromGitter> <dscottboggs_gitlab> I don't see any examples, blissin, nor docs
<FromGitter> <randiaz95> Your websocket connections must be global for that to work
<blassin> randlaz95: the idea is for the client to not do anything, and just be notified of server-side file changes
<blassin> and then reload
<FromGitter> <randiaz95> yep
<blassin> so where does the POST come into?
<FromGitter> <randiaz95> from script modifying the file
<blassin> what script?
<FromGitter> <randiaz95> are you coding this modification or manually changing the files?
<blassin> the workflow is: I boot up the server which monitors markdown files. when one of them changes, it rebuilds the site and pings the browser to reload
<FromGitter> <randiaz95> ok, so you need to constantly read the files in an event loop then if file changed -> send post
<blassin> I can't post to the browser
<blassin> I can only do SSE or send a WS message
<FromGitter> <randiaz95> Nope you can't post to browser but you can post to server
<FromGitter> <dscottboggs_gitlab> so you could do something like ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5e9b9e638e987f3a5e29a60a]
<FromGitter> <dscottboggs_gitlab> shit i sent too early
<FromGitter> <randiaz95> lol
<blassin> randlaz95: what's the point of posting to the server? would the browser reload?
<FromGitter> <randiaz95> yep
<FromGitter> <dscottboggs_gitlab> so you could do something like ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5e9b9e96a412254f2197f3ff]
<FromGitter> <randiaz95> post to server -> server then sends websocket message to client
<FromGitter> <randiaz95> Scott that is listening not what we want
<FromGitter> <randiaz95> I think
<FromGitter> <dscottboggs_gitlab> so you could do something like ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5e9b9eb9a412254f2197f46a]
<blassin> my whole problem is sending WS messages to the client :D no good examples I can find
<blassin> (on demand, I mean)
<FromGitter> <dscottboggs_gitlab> ☝️
<FromGitter> <sardaukar> thanks, will try that @dscottboggs_gitlab !
<FromGitter> <randiaz95> in that code you need to store the channels into an array or hashmap
<FromGitter> <randiaz95> Omg
<FromGitter> <randiaz95> so in the when timeout 1.second then check for file change and ws.send if changed?
<FromGitter> <dscottboggs_gitlab> yep
<FromGitter> <randiaz95> You bastard, I was thinking in go syntax lol
<FromGitter> <randiaz95> I've never used built in websocket handler
<FromGitter> <randiaz95> Scott, how would you broadcast the file change in that code?
<FromGitter> <dscottboggs_gitlab> this isn't really anything you can't do in go either, there'd just be a lot of `if err != nil` sprinkled throughout 😂
<FromGitter> <randiaz95> lol\
<FromGitter> <dscottboggs_gitlab> @randiaz95 the file watcher would need access to chan, and it would send a string to it.
<FromGitter> <randiaz95> b4 loop do store chan?
<FromGitter> <dscottboggs_gitlab> in this case chan is a Channel(String)
<FromGitter> <dscottboggs_gitlab> yes, I would make it a class_property
<FromGitter> <sardaukar> got a syntax error on that example
<FromGitter> <sardaukar> `expecting token 'IDENT', not 'HTTP'`
blassin has quit [Remote host closed the connection]
<FromGitter> <sardaukar> (might as well be on gitter.im) :D
<FromGitter> <randiaz95> What line?
<FromGitter> <sardaukar> `ws_handler = ->( HTTP::Websocket, HTTP::Server::Context ) do |ws, context|`
<FromGitter> <dscottboggs_gitlab> my bad I just whipped that up and didn't try it
<FromGitter> <randiaz95> I guess it was expecting a different interface.
<FromGitter> <Blacksmoke16> are missing type declarations in the proc
<FromGitter> <randiaz95> not websocket, context function
<FromGitter> <sardaukar> `ws_handler = ->( ws : HTTP::Websocket, ctx : HTTP::Server::Context ) do |ws, ctx|`
<FromGitter> <sardaukar> still doesn't work
<FromGitter> <randiaz95> i think proc uses curly
<FromGitter> <randiaz95> from what the doc showed.
<FromGitter> <sardaukar> yep yep
<FromGitter> <dscottboggs_gitlab> ah looks like you need to drop the |s
<FromGitter> <randiaz95> I hate curlies
<FromGitter> <Blacksmoke16> try `Proc.new(HTTP::Websocket, HTTP::Server::Context).new |ws, ctx|`
<FromGitter> <dscottboggs_gitlab> you don't NEED to use the curlies, you just don't need the `|ws, ctx|`
<FromGitter> <dscottboggs_gitlab> thanks @Blacksmoke16
<FromGitter> <randiaz95> do |
<FromGitter> <randiaz95> ah u fixed it lol
<FromGitter> <randiaz95> Hey Scott, what do you recommend a person do to learn crystal if coming from a python background?
<FromGitter> <dscottboggs_gitlab> I would actually make that a class method and use the ->method syntax
<FromGitter> <dscottboggs_gitlab> @randiaz95 I read the book, front to back https://crystal-lang.org/reference/ then I would go to exercism and do a few challenges
<FromGitter> <sardaukar> now I get `can't use variable name 'ws_handler' inside assignment to variable 'ws_handler'` trying to add the lambda handler to the server
<FromGitter> <dscottboggs_gitlab> wtf haha?
<FromGitter> <Blacksmoke16> paste the code/
<FromGitter> <Blacksmoke16> ?
<FromGitter> <randiaz95> I first watched https://www.youtube.com/watch?v=DxFP-Wjqtsc then went to that reference while I started making some projects.
<FromGitter> <sardaukar> https://pastebin.com/77iYiPFH
<FromGitter> <dscottboggs_gitlab> you've got both `do` and `{` that won't work
<FromGitter> <sardaukar> argh forgot
<FromGitter> <randiaz95> do |ws, ctx|
<FromGitter> <dscottboggs_gitlab> @randiaz95 no, https://pastebin.com/yCfPhSsX
<FromGitter> <randiaz95> Wut?
<FromGitter> <dscottboggs_gitlab> the variables are named in the proc definition
<FromGitter> <randiaz95> Ah! True..
<FromGitter> <randiaz95> Procs are wierd.
<FromGitter> <tenebrousedge> you say that, but then there are python lambdas
<FromGitter> <dscottboggs_gitlab> hahahaha
<FromGitter> <randiaz95> wut? lambda x: x+1?
<FromGitter> <randiaz95> thats beautiful
<FromGitter> <dscottboggs_gitlab> yeah, until you need more than 1 line
<FromGitter> <randiaz95> increment = lambda x: x+1
<FromGitter> <tenebrousedge> as long as you only want a single expression
<FromGitter> <randiaz95> What? Why would you need more than one line in a lambda?
<FromGitter> <randiaz95> create a normal function?
* FromGitter * tenebrousedge points to the pastebin
* FromGitter * dscottboggs_gitlab points to the proc I just wrote
<FromGitter> <dscottboggs_gitlab> hahaha
<FromGitter> <randiaz95> lambda is for one line
<FromGitter> <tenebrousedge> that's just because Python hates lambdas
<FromGitter> <stronny> that's a great example of mind patterns
<FromGitter> <randiaz95> df["column"] = df["column"].apply(lambda x: x+1)
<FromGitter> <randiaz95> pandas with lambdas r not bad..
<FromGitter> <dscottboggs_gitlab> that's like saying what's the point of `do..end` expressions, we have this convenient, one line `{}` syntax
<FromGitter> <stronny> the only reason python lambdas can't have several lines is the whitespace nesting
<FromGitter> <stronny> guido said that himself
<FromGitter> <randiaz95> Sure, use def fn():
* FromGitter * dscottboggs_gitlab gives up
<FromGitter> <randiaz95> lol..
<FromGitter> <sardaukar> is there a way to pass the channel to the WS handler? https://gist.github.com/sardaukar/a8aea496cffe8750d7657992ae75548b
<FromGitter> <sardaukar> I mean, a "clean" way?
<FromGitter> <tenebrousedge> python has a lot of issues that stem from not wanting to have proper anonymous functions / higher-order methods
<FromGitter> <stronny> closure it up?
<FromGitter> <dscottboggs_gitlab> not without subclassing websocket handler, or closing over it
<FromGitter> <randiaz95> ah lol you are trying to be a functional language
<FromGitter> <randiaz95> use scala or something
<FromGitter> <randiaz95> scala is going to have tabbed syntax soon
<FromGitter> <randiaz95> in scala3
<FromGitter> <tenebrousedge> Ruby and Crystal and even Javascript do lambdas / homs just fine
<FromGitter> <tenebrousedge> even PHP does actually
<FromGitter> <dscottboggs_gitlab> @sardaukar I would put all of this in a module and put the channel as a module-level property like ⏎ ⏎ ```module MyServer ⏎ class_property channel : Channel(String) = Channel(String).new ⏎ end``` [https://gitter.im/crystal-lang/crystal?at=5e9ba28aa9ca18620649f8bc]
<FromGitter> <stronny> depends on the definition of fine lol
<FromGitter> <randiaz95> yep php lends itself to easily identify functions with dollar signs right?
<FromGitter> <randiaz95> whereas in python you can't tell the diff of a lambda function or var without checking type
<FromGitter> <Blacksmoke16> variables ^
<FromGitter> <Blacksmoke16> `$myStr = 'foo';`
<FromGitter> <randiaz95> variables have $ and functions dont have $?
<FromGitter> <Blacksmoke16> correct
<FromGitter> <sardaukar> ok, I have the channel at the module level
<FromGitter> <randiaz95> there you o
<FromGitter> <randiaz95> go*
<FromGitter> <Blacksmoke16> `public function doSomething() { }`
<FromGitter> <sardaukar> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5e9ba2e585b01628f05e2df7]
<FromGitter> <randiaz95> php is a one hit wonder
<FromGitter> <randiaz95> let it be lol
<FromGitter> <sardaukar> so I can't use the lambda as a Handler? :|
<FromGitter> <Blacksmoke16> paste the code again?
<FromGitter> <dscottboggs_gitlab> well I'm confused
<FromGitter> <dscottboggs_gitlab> https://crystal-lang.org/api/0.34.0/HTTP/WebSocketHandler.html#new(&proc:WebSocket,Server::Context-%3E)-class-method
<FromGitter> <randiaz95> Am I using idiomatic crystal here in the layer array? ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5e9ba384471108620541a81e]
<FromGitter> <dscottboggs_gitlab> I guess so, did you run the formatter on it?
<FromGitter> <sardaukar> looks like the docs for WebSocketHandler are not really noob-friendly 😓
<FromGitter> <sardaukar> they actually seem to be out of date
<FromGitter> <Blacksmoke16> make it with a block and not a proc
<FromGitter> <sardaukar> then why does the compiler give an arity error?
<FromGitter> <dscottboggs_gitlab> that's what I would try next too @Blacksmoke16
<FromGitter> <Blacksmoke16> ```ws_handler = HTTP::WebSocketHandler.new do |ws, ctx| ⏎ nil ⏎ end``` [https://gitter.im/crystal-lang/crystal?at=5e9ba402e920022432b74d79]
<FromGitter> <Blacksmoke16> its a yielded captured block
<FromGitter> <Blacksmoke16> not a proc, the ivar name is mislabeled imo
<FromGitter> <dscottboggs_gitlab> yeah my bad I misunderstood the `&@proc` syntax
<FromGitter> <sardaukar> yep, that works - I'll try porting the select loop over
<FromGitter> <stronny> yeah, it's subtle but `def name(&@var)` actually takes zero arguments and a block
<FromGitter> <randiaz95> @stronny what does the ampersand mean in crystal, is it this in a class?
<FromGitter> <stronny> did you read the reference?
<FromGitter> <randiaz95> Not up to that point yet lol
<FromGitter> <randiaz95> I just confused it with ampersand in map method
<FromGitter> <stronny> no, it's the same ampersand
<FromGitter> <Blacksmoke16> `&` means that the method only yields
<FromGitter> <stronny> the idea was to help people actually
<FromGitter> <Blacksmoke16> `&block` means that the method yields but the block is captured https://crystal-lang.org/reference/syntax_and_semantics/capturing_blocks.html
<FromGitter> <sardaukar> IT WORKS!!!!111111
<FromGitter> <sardaukar> ZOMG
<FromGitter> <randiaz95> lol
<FromGitter> <sardaukar> this is awesome
<FromGitter> <sardaukar> thanks, everyone!
<FromGitter> <dscottboggs_gitlab> whoo!
<FromGitter> <randiaz95> Yep this is very ruby/crystal specific lol
<FromGitter> <randiaz95> Sorry about that
<FromGitter> <dscottboggs_gitlab> indeed
<FromGitter> <stronny> it's a bit different between ruby and crystal
<FromGitter> <dscottboggs_gitlab> nothing to be sorry about, it's kinda confusing and unique
<FromGitter> <randiaz95> I get it though, originally I was like why would you say do? Ain't it supposed to be obvious to do?
<FromGitter> <dscottboggs_gitlab> yeah, it's a weird syntax for callbacks/lambdas tbh
<FromGitter> <dscottboggs_gitlab> but it reads well in DSLs
<FromGitter> <stronny> do is nothing new, shells have do/done
<FromGitter> <randiaz95> I think haskell uses do too..
<FromGitter> <randiaz95> I like it though ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5e9ba642a1284c4f209f71d4]
<FromGitter> <dscottboggs_gitlab> well, because all blocks are inlined (unless they're captured), which does affect the resulting binary size and (I think) compile time
<FromGitter> <sardaukar> I made a screencast of my project doing live reload https://imgur.com/a/LZ66xv2
<FromGitter> <sardaukar> this is so cool :D
<FromGitter> <tenebrousedge> one thing that I have been okay with about Python is `operator`
<FromGitter> <sardaukar> (sorry, my screen resolution is ultrawide)
<FromGitter> <dscottboggs_gitlab> @sardaukar veru moce!
<FromGitter> <sardaukar> oh wow, imgur butchered that file :|
<FromGitter> <randiaz95> Super cool man!!
<FromGitter> <sardaukar> hopefully it's visible
<FromGitter> <dscottboggs_gitlab> yeah it did but I got the point haha
<FromGitter> <randiaz95> yeah you dropped a ton of html and it rendered automagically
<FromGitter> <dscottboggs_gitlab> @tenebrousedge what do you mean by that?
<FromGitter> <tenebrousedge> ```from operator import floordiv ⏎ reduce(floordiv, [3,5,7,9], factorial(10))``` [https://gitter.im/crystal-lang/crystal?at=5e9ba70d74bfed5a1b496215]
<FromGitter> <dscottboggs_gitlab> ah.
<FromGitter> <sardaukar> @randiaz95 I just edited the markdown source, the site got rebuilt and pinged the browser to reload almost instantly
<FromGitter> <sardaukar> I only have 3 posts now, but still pretty impressive
<FromGitter> <dscottboggs_gitlab> yeah I like it. You could even drop turbolinks in there and it would be almost invisible
<FromGitter> <sardaukar> turbolinks need a server, right? this is just static HMTL/CSS
<FromGitter> <sardaukar> (with a sprinkle of JS to read the socket while in local development)
<FromGitter> <dscottboggs_gitlab> no, turbolinks just diffs the received HTML and renders the changes instead of showing a page jump
<FromGitter> <sardaukar> yeah, but they still need a target URL serving something, right?
<FromGitter> <sardaukar> this is just static HTML without a server
<FromGitter> <dscottboggs_gitlab> No, you have a server? You just wrote an HTTP::Server?
<FromGitter> <sardaukar> for local development only
<FromGitter> <randiaz95> I wonder what applications websockets with neural networks have outside of chatbots...
<FromGitter> <sardaukar> the idea is the "output" of the build is just static files, ready to upload somewhere
<FromGitter> <sardaukar> the server is just to render the file locally, while you're authoring
<FromGitter> <randiaz95> Yeah kind of like autorefresh on amber or nodemon or react
<FromGitter> <sardaukar> yeah, like Hugo and Jekyll and other static site generators
<FromGitter> <dscottboggs_gitlab> https://github.com/turbolinks/turbolinks#features ⏎ ⏎ > No server-side cooperation necessary. ⏎ ⏎ my point is just that it will look nicer when the render changes, without changing how your existing setup works. [https://gitter.im/crystal-lang/crystal?at=5e9ba83f85b01628f05e3b28]
<FromGitter> <dscottboggs_gitlab> You don't gotta use it if you don't want to obviously haha
<FromGitter> <sardaukar> it's not that I don't want to, it's just that the idea is to generate HTML files that don't need a server
<FromGitter> <sardaukar> to simplify deployment
<FromGitter> <dscottboggs_gitlab> ah I see
<FromGitter> <randiaz95> Right, 1 server forever
<FromGitter> <sardaukar> pretty fast, low attack surface, etc
<FromGitter> <dscottboggs_gitlab> wouldn't you want to strip your websocket JS out anyway though?
<FromGitter> <sardaukar> it's not present on the "final" build
<FromGitter> <randiaz95> hey bruno have you heard of brackets ide?
<FromGitter> <sardaukar> only for live reload locally, while working on the site
<FromGitter> <sardaukar> yeah, it's like an editor, right?
<FromGitter> <dscottboggs_gitlab> so why not put the turbolinks code in with the reload stuff and have it stripped out in the final build?
<FromGitter> <randiaz95> Im sure you could duplicate that with crystal
<FromGitter> <randiaz95> and make it way better
<FromGitter> <sardaukar> @dscottboggs_gitlab websockets are simpler?
<FromGitter> <sardaukar> yeah, this was more like an exercise to see if I could pull it off
<FromGitter> <sardaukar> the markdown output, theming, etc
<FromGitter> <sardaukar> oh, Brackets wouldn't work because my themes are ECR
* FromGitter * dscottboggs_gitlab shrugs
<FromGitter> <sardaukar> example of the theme that generates that homepage from the screencast https://gist.github.com/sardaukar/edc97bb8b55c71c7178c2dd03d2c9d5a
<FromGitter> <dscottboggs_gitlab> would you mind publishing the result to github when it's done, @sardaukar? I could probably use those pieces and examples in the future
<FromGitter> <sardaukar> I will, for sure!
<FromGitter> <sardaukar> no point in keeping this to myself :D
<FromGitter> <sardaukar> I also plan on bloggin about it
<FromGitter> <sardaukar> will probably have enough material for a few posts
<FromGitter> <sardaukar> the only annoyance now is that I'm using
<FromGitter> <dscottboggs_gitlab> sweeet
<FromGitter> <dscottboggs_gitlab> oof
<FromGitter> <sardaukar> actually, not sure if it is Granite
<FromGitter> <dscottboggs_gitlab> good luck, never really got into ORMs
<FromGitter> <Blacksmoke16> they're just warnings so no big deal atm
<FromGitter> <Blacksmoke16> can disable them if you want
<FromGitter> <sardaukar> it looks like it's from Crystal itself...? https://gist.github.com/sardaukar/cd383d30cdc82491f61ebda1f1ab2666
<FromGitter> <Blacksmoke16> `--warnings none`
<FromGitter> <sardaukar> @dscottboggs_gitlab I use an ORM so the themes can do easy SQL-ish queries over the blog's cntent
<FromGitter> <sardaukar> @Blacksmoke16 that kills *all* warnings, right?
<FromGitter> <sardaukar> not really my scene :D
<FromGitter> <Blacksmoke16> yea
<FromGitter> <Blacksmoke16> `--exclude-warnings <path> Exclude warnings from path (default: lib)` is also an option
<FromGitter> <randiaz95> Hey George, how do you handle returning either a scalar float or possible array in a function? Do you overload it in a class or handle the logic within one function.
<FromGitter> <randiaz95> The inputs also become arrays of arrays instead of just array if it returns an array
<FromGitter> <sardaukar> @Blacksmoke16 ended up with `--exclude-warnings /home/sardaukar/.asdf/installs/crystal/0.34.0/share/crystal/src/ --exclude-warnings lib/ `
<FromGitter> <sardaukar> weird that Crystal itself generates deprecation warnings?
<FromGitter> <dscottboggs_gitlab> why's that?
<FromGitter> <dscottboggs_gitlab> better to warn people ahead of time about breaking changes
<FromGitter> <randiaz95> sure
<FromGitter> <sardaukar> if a big part of 0.34 was the Log revamp, why not make sure 0.34 code was updated for it?
<FromGitter> <dscottboggs_gitlab> it was, but they left the old stuff in for a release so it didn't break projects, they'll remove it in the next one or so
<FromGitter> <sardaukar> oh ok makes sense
<FromGitter> <sardaukar> it's super late over here, thanks again for all the help everyone! see you around 👋
<FromGitter> <dscottboggs_gitlab> 👍 see you!
<FromGitter> <Blacksmoke16> got my DI thing working with generic types
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5e9bad2ce920022432b76254]
<FromGitter> <Blacksmoke16> kinda neat
<FromGitter> <dscottboggs_gitlab> nifty
<FromGitter> <Blacksmoke16> is getting pretty legit ha
<FromGitter> <Blacksmoke16> deff the best DI shard around thats for sure
<FromGitter> <dscottboggs_gitlab> isn't it also the only one? haha 😅
<FromGitter> <Blacksmoke16> naw theres like three others
<FromGitter> <Blacksmoke16> all suffer from same core problem afaik tho
<FromGitter> <dscottboggs_gitlab> huh. i didn't realize
<FromGitter> <dscottboggs_gitlab> what's the problem?
<FromGitter> <Blacksmoke16> they are all class based
<FromGitter> <Blacksmoke16> i.e. one container for every fiber
<FromGitter> <Blacksmoke16> all fibers*
<FromGitter> <Blacksmoke16> which would mean two requests would be sharing the same services for example
<FromGitter> <dscottboggs_gitlab> oooh. that's not good
<FromGitter> <Blacksmoke16> whereas since mine is instance based each fiber could have its own container instance
<FromGitter> <Blacksmoke16> ofc is a bit more overhead related to that as one needs to be instantiated on every requests but meh
<FromGitter> <dscottboggs_gitlab> @Blacksmoke16 do you think this would be merged? https://github.com/crystal-lang/crystal/compare/master...dscottboggs:feature/websocket-handler-docs
<FromGitter> <Blacksmoke16> maybe create another initializer for the proc
<FromGitter> <Blacksmoke16> then can pass the captured block to that overload
<FromGitter> <dscottboggs_gitlab> ah, that's an idea
<FromGitter> <dscottboggs_gitlab> Actually, I think with the documentation, it's better the way it is. You can always do `.new &->method`
<FromGitter> <Blacksmoke16> hm?
<FromGitter> <Blacksmoke16> wouldnt that still be a proc?
<FromGitter> <dscottboggs_gitlab> https://carc.in/#/r/8wwg
<FromGitter> <Blacksmoke16> hm, but still couldnt use a proc?
<FromGitter> <Blacksmoke16> dunno if thats a big deal or not but :shr
<FromGitter> <Blacksmoke16> :shrug:
<FromGitter> <dscottboggs_gitlab> hm? what do you mean?
<FromGitter> <Blacksmoke16> like still couldnt pass a normal proc tho?
<FromGitter> <dscottboggs_gitlab> https://carc.in/#/r/8wwh ?
<FromGitter> <Blacksmoke16> not using `&->` tho
<FromGitter> <Blacksmoke16> thats special syntax i think
<FromGitter> <dscottboggs_gitlab> https://carc.in/#/r/8wwi
<FromGitter> <Blacksmoke16> https://carc.in/#/r/8wwl
<FromGitter> <Blacksmoke16> is what i mean using `&` with the proc is prob some block syntax
<FromGitter> <Blacksmoke16> idk if its useful or not to pass the proc directly
* FromGitter * dscottboggs_gitlab shrugs
<FromGitter> <jojokoro> I'm trying to find the better web framework for building APIs in Crystal
<FromGitter> <jojokoro> Found this Onyx which seems fairily good, but it scores very bad in benchmarks
<FromGitter> <jojokoro> anyone already used it?
<FromGitter> <Blacksmoke16> anything in particular you looking for feature wise?
<FromGitter> <Blacksmoke16> there are quite a few frameworks...
<FromGitter> <dscottboggs_gitlab> no, I've never used onyx. What George said
<FromGitter> <jojokoro> Look at that. Oddly (https://www.techempower.com/benchmarks/#section=data-r18&hw=ph&test=db&l=zdk8an-f) slow.
<FromGitter> <Blacksmoke16> pretty sure its just single threaded while others are using multiple processes for each core
<FromGitter> <Blacksmoke16> but yea, its not really being maintained anymore
<FromGitter> <tenebrousedge> benchmarks aren't really a great reason to pick a framework
<FromGitter> <Blacksmoke16> ^
<FromGitter> <jojokoro> Just having to write some microservices, deal with auth (JWT), middlewares, DB connection (doesn't need to feature full ORM)
<FromGitter> <Blacksmoke16> kemal would be the simplest, but least features
<FromGitter> <Blacksmoke16> amber/lucky would be the larger more full featured ones
<FromGitter> <Blacksmoke16> is also Athena which is about in the middle, based on like spring/symfony
<FromGitter> <dscottboggs_gitlab> I think you want Kemal. I have https://github.com/dscottboggs/kemal-jwt-auth for JWT
<FromGitter> <dscottboggs_gitlab> Athena or lucky are also worth looking at
<FromGitter> <dscottboggs_gitlab> gtg
<FromGitter> <Blacksmoke16> o/
<FromGitter> <Blacksmoke16> i should prob add athena to that list
<FromGitter> <Blacksmoke16> kinda forgot that was a thing
<FromGitter> <randiaz95> Athena plug every night lol
<FromGitter> <Blacksmoke16> he brought it up :P
<FromGitter> <randiaz95> Your a good marketer lol
<FromGitter> <Blacksmoke16> im trying ha
<FromGitter> <Blacksmoke16> im quite a fan of it 😉
<FromGitter> <randiaz95> Lolz I like it too..
<FromGitter> <Blacksmoke16> any questions etc so far?
* FromGitter * tenebrousedge must find the shortest possible way to write All The Things
* FromGitter * tenebrousedge wrestles Python into submission
<FromGitter> <randiaz95> How do you combine two controllers into one?
<FromGitter> <tenebrousedge> ...
<FromGitter> <randiaz95> I created this monolith
<FromGitter> <randiaz95> lol
<FromGitter> <Blacksmoke16> hm?
<FromGitter> <randiaz95> composition is best?
<FromGitter> <randiaz95> Make a parent Controller?
<FromGitter> <Blacksmoke16> for what purpose?
<FromGitter> <randiaz95> Well, you know how one of your examples has a prefix url feature?
<FromGitter> <Blacksmoke16> sharing some common methods between controllers?
<FromGitter> <Blacksmoke16> eya
<FromGitter> <Blacksmoke16> yea
<FromGitter> <randiaz95> I want to combine two controllers with two different url prefixes
<FromGitter> <randiaz95> /user and /inventory
<FromGitter> <randiaz95> but keep the codebases separate
<FromGitter> <Blacksmoke16> sorry still not sure i follow
<FromGitter> <Blacksmoke16> you want to merge two controllers into one?
<FromGitter> <randiaz95> Yep
<FromGitter> <Blacksmoke16> for what reason? if they handling separate things does it not make more sense to keep the separate?
<FromGitter> <randiaz95> So different ports too?
<FromGitter> <Blacksmoke16> oh, share them between totally diff servers
<FromGitter> <randiaz95> i want 2 controllers on the same server
<FromGitter> <randiaz95> listening on 1 port
<FromGitter> <Blacksmoke16> isnt that how it works by default? just like amber/lucky?
<FromGitter> <randiaz95> The thing I don't understand coming from python flask is; how does the server know about the controller?
<FromGitter> <randiaz95> its just magic?
<FromGitter> <randiaz95> all you need to do is require "./controllers/*" and the server knows?
<FromGitter> <Blacksmoke16> yes, at compile time all routes get registered with the router
<FromGitter> <Blacksmoke16> yes
<FromGitter> <randiaz95> ugh..
<FromGitter> <randiaz95> :')
<FromGitter> <randiaz95> that felt like a diareah
<FromGitter> <tenebrousedge> compilation, it does the things
<FromGitter> <Blacksmoke16> is that bad? :p
<FromGitter> <randiaz95> I am so used to explicitness.
<FromGitter> <randiaz95> I was like WHERE DO I DO THIS!?1
<FromGitter> <randiaz95> lol
<FromGitter> <tenebrousedge> be lazier
<FromGitter> <randiaz95> Yep, I feel like in ruby and crystal I am doing less config and more wizardry
<FromGitter> <randiaz95> more fun
<FromGitter> <randiaz95> Lol
<FromGitter> <randiaz95> Dude in flask you must literally add the functions to the app
<FromGitter> <Blacksmoke16> sounds annoying
<FromGitter> <randiaz95> George how much ram does it take to shards install your json api blog?
<FromGitter> <Blacksmoke16> mm let me try
<FromGitter> <Blacksmoke16> might need some deps updated
<FromGitter> <randiaz95> It's essentially malware to my Mac
<FromGitter> <randiaz95> Lol
<FromGitter> <randiaz95> If I wasn't training 30 gigs of ram on my desktop I would try there
<FromGitter> <Blacksmoke16> it installed fine, used like 5mb
<FromGitter> <Blacksmoke16> what shards version you on?
<FromGitter> <Blacksmoke16> Anyway, I'm out for the night
alexherbo2 has joined #crystal-lang
_whitelogger has joined #crystal-lang
postmodern has quit [Quit: Leaving]
_ht has joined #crystal-lang
gangstacat has quit [Quit: Ĝis!]
gangstacat has joined #crystal-lang
<FromGitter> <ImAHopelessDev_gitlab> > George how much ram does it take to shards install your json api blog? ⏎ ⏎ not as much as vscode or slack
zorp has joined #crystal-lang
_ht has quit [Remote host closed the connection]
_ht has joined #crystal-lang
<FromGitter> <marynowac> i've notice something strange to me. simple subtraction returns a result increased by 0000000175. ⏎ why? ⏎ ⏎ ```a = 2465.51094 ⏎ b = 2453.0274 ⏎ ⏎ puts a - b # => 12.483540000000175``` ⏎ ... [https://gitter.im/crystal-lang/crystal?at=5e9c28720480c128efcd5783]
<jhass> good old IEE754 floating points fun
<jhass> none of these numbers can be accurate represented in IEE754 floating point
<oprypin> ok here's my Unused code deletion based on the output not being affected https://gist.github.com/ab4656fbc6f9c64023ac971a23562242
<oprypin> /cc @Blacksmoke16
<FromGitter> <marynowac> so nothing can be done about it? i just write a little helper to settle taxes for myself and i know i can `round(2)` each result, but that behaviour worries me a little…
<oprypin> marynowac, BigDecimal
alexherbo24 has joined #crystal-lang
<oprypin> that unused code deletion is pretty crazy. it deletes things that happen to be ok to delete but i wouldn't delete it in my right mind
alexherbo2 has quit [Ping timeout: 260 seconds]
alexherbo24 is now known as alexherbo2
<FromGitter> <marynowac> @oprypin thanks a lot :-)
alexherbo2 has quit [Quit: Ping timeout (120 seconds)]
alexherbo2 has joined #crystal-lang
<jhass> for money an often good enough approach is to convert everything to cents at earliest after input, store and calculate with the cents in integers and only convert back into floats before display
<oprypin> jhass, well luckily bigdecimal does just that anyway
alexherbo24 has joined #crystal-lang
alexherbo2 has quit [Ping timeout: 256 seconds]
alexherbo24 is now known as alexherbo2
<FromGitter> <dscottboggs_gitlab> If I allocate a pointer with `LibC.malloc` and create a slice from it, it's scanned by the GC, right?
<FromGitter> <stronny> do you really allocate with malloc or do you get allocated pointer from C fun?
<FromGitter> <dscottboggs_gitlab> I'm really allocating with malloc. There's no way to allocate a slice in crystal without zeroing it other than `Slice(T).new LibC.malloc(size * sizeof(T)), size`, because it's *technically* unsafe to do that, but there are cases where it doesn't make sense to bother zeroing the slice
<FromGitter> <dscottboggs_gitlab> it's "unsafe" in the sense that the slice is filled with garbage data
<FromGitter> <dscottboggs_gitlab> the code I just wrote: ⏎ ⏎ ```code paste, see link``` ⏎ ⏎ Trying to figure out if I need to realloc before passing back the subslice to avoid leaking the tail of the possibly less than `n` size slice [https://gitter.im/crystal-lang/crystal?at=5e9c400f74bfed5a1b4aa874]
<jhass> No, you want to use GC.malloc
<FromGitter> <dscottboggs_gitlab> ah ok, thanks
<jhass> but I wouldn't bother and just use Slice.new really
<FromGitter> <dscottboggs_gitlab> that makes a lot of sense TBH
<FromGitter> <dscottboggs_gitlab> meh, I get my kicks from writing shit like this on the weekend lol
<FromGitter> <faustinoaq> Hi can someone help me :) How can I get `pp! Time.local.year.to_u8` working on latest Crystal version?
<FromGitter> <faustinoaq> On Crystal v0.30.1 https://carc.in/#/r/8wzm I got `Time.local.year.to_u8 # => 228`
<FromGitter> <tenebrousedge> and how is that a sensible value?
<FromGitter> <faustinoaq> On Latest Crystal v0.34.0 https://carc.in/#/r/8wzn I get `Unhandled exception: Arithmetic overflow (OverflowError)`
<FromGitter> <tenebrousedge> https://carc.in/#/r/8wzp
<FromGitter> <tenebrousedge> this seems like a bad idea
<FromGitter> <tenebrousedge> why are you doing this?
<FromGitter> <faustinoaq> @tenebrousedge Thank you!, I'm trying to assign the some values to a byte package
<FromGitter> <faustinoaq> something like this:
<FromGitter> <faustinoaq> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5e9c506574bfed5a1b4ae6d6]
<FromGitter> <tenebrousedge> isn't there a real compression algorithm that you can use?
<FromGitter> <tenebrousedge> or can you just use unix time?
<FromGitter> <faustinoaq> I'm just trying to port a python lib for an IoT PowerSwitch, It worked successfully on Crystal v0.30.1, now I'm want to make it compatible with latest Crystal version, see: https://github.com/faustinoaq/crystal-broadlink/blob/master/src/broadlink.cr
<FromGitter> <faustinoaq> Thank you @tenebrousedge It works like a charm! 🎉 😎
<FromGitter> <tenebrousedge> :plus1:
<hightower2> Hey should Pointer(something).null be considered null? I have a case where the && || comparison works fine, but .try doesn't seem to (it runs when I suppose it shouldn't):
<FromGitter> <tenebrousedge> `try` is only special for `nil`
<hightower2> yes but shouldn't the comparison on the pointer return nil=true for this case?
<hightower2> well, ok
<FromGitter> <tenebrousedge> so what happens is that `try` yields self for all objects, and `nil` is overriden to just return `nil`
<FromGitter> <tenebrousedge> to me it makes some sense that the null pointer would be falsey but not nil
<hightower2> ok
<FromGitter> <tenebrousedge> so perhaps instead of `try` you can do `(ptr = whatever) && do_something_with_ptr`
<FromGitter> <tenebrousedge> or `if ptr`
<hightower2> yes yes, switched to if because after a couple if-s eventually I have a couple lines to run
<hightower2> (could have also used 1 && 2 && begin ... end)
alexherbo2 has quit [Quit: The Lounge - https://thelounge.chat]
<hightower2> thanks
<FromGitter> <tenebrousedge> well, I'm not saying it's prettier, just that there's method in this madness
<FromGitter> <tenebrousedge> yw
<FromGitter> <grkek> Are broken pipe errors considered as okay?
<FromGitter> <tenebrousedge> it usually means your house will flood a bit
<FromGitter> <grkek> Oh my that's a good one
<FromGitter> <tenebrousedge> most often I see that when my ssh session is interrupted
<FromGitter> <tenebrousedge> what's the context here
<FromGitter> <grkek> It's in context of a client refreshing a web page really fast
<FromGitter> <grkek> while there is a large file which must be sent over
<FromGitter> <tenebrousedge> maybe you should show them a progress icon so that happens less?
<FromGitter> <grkek> Okay so it is fine to be frank
<FromGitter> <grkek> I have one more question
<FromGitter> <grkek> How do you guys manage to deploy kemal apps on heroku which have websocket live "chat" sessions
<FromGitter> <tenebrousedge> I mean it sounds like a user problem more than a code problem. User is doing stupid things. Encourage them not to. I'm not sure if there's a technical solution
<FromGitter> <tenebrousedge> websockets seem like they're supported https://devcenter.heroku.com/articles/websockets
<FromGitter> <stronny> a technical solution would be for example refactor a large file into small independent entities
<FromGitter> <grkek> I did deploy kemal apps to heroku but once I tried to stress test them they failed by keeping me await it for a long time
<FromGitter> <stronny> I presume this "file" is either a `<script src="">` or some XHR
<FromGitter> <grkek> Its just an HTML file
<FromGitter> <grkek> which is way too large
<FromGitter> <tenebrousedge> give them a loading spinner to look at
<hightower2> oprypin, stronny: I came to one additional idea re. searching within substrings. Instead of creating new strings to forcefully limit the area of search, I can simply do the search and have a convenience function which resets search result to nil if the offset at which it is found is outside of the range in which I wanted to search. This would work at least for some % of my cases because I lazily search with an iterator, so I risk at
<hightower2> most one search which I'm gonna discard before stopping.
<FromGitter> <grkek> Interesting fact I found about websockets is that heroku just keeps shutting them down after some time
<FromGitter> <tenebrousedge> > The normal Heroku HTTP routing timeout rules apply to WebSocket connections. Either client or server can prevent the connection from idling by sending an occasional ping packet over the connection.
<FromGitter> <grkek> Fucking ping packets
<FromGitter> <grkek> aight might as well do that
<FromGitter> <grkek> Lovely my chat app works fine now
<FromGitter> <tenebrousedge> :plus1:
<FromGitter> <randiaz95> Save the planet ping responsibly
<FromGitter> <grkek> every 30 secs
<FromGitter> <lagerfeuer> I was looking at the documentation for `alias`, what am I missing here? https://play.crystal-lang.org/#/r/8x0y
<FromGitter> <Blacksmoke16> any reason you're recreating something that already exists in the stdlib?
<FromGitter> <randiaz95> yea I recommend using to_json
<FromGitter> <randiaz95> https://crystal-lang.org/api/0.24.2/Hash.html#to_json%28json%3AJSON%3A%3ABuilder%29-instance-method
<FromGitter> <randiaz95> Map to json
<FromGitter> <randiaz95> sorry hash to json
<FromGitter> <Blacksmoke16> but to your question `{"test" => true} of String => Json::Type`
<FromGitter> <Blacksmoke16> `Hash(String, Bool)` is not the same thing as `Hash(String, Json::Type)`
<FromGitter> <grkek> sometimes even Hash(String, String) doesn't work
darkstardevx has joined #crystal-lang
<FromGitter> <grkek> String is mentioned in the JSON::Type
<FromGitter> <randiaz95> You mean {} of Hash(String, String)?
<FromGitter> <grkek> literally {"hi" => "ho"}
<FromGitter> <Blacksmoke16> yes but thats `Hash(String, String)`
<FromGitter> <Blacksmoke16> it doesnt account for the other possible types in the union
<FromGitter> <grkek> Unions are weird
<FromGitter> <Blacksmoke16> hence you have to say the value should be of type `Json::Type`
<FromGitter> <grkek> black magic
<FromGitter> <randiaz95> I thought they were explicit...
<FromGitter> <lagerfeuer> Ahh okay, I see. It was really confusing me tbh.
<FromGitter> <lagerfeuer> Thanks for the quick response guys
<FromGitter> <grkek> ;)
<FromGitter> <Blacksmoke16> there was a forum post about this, let me look it up
<FromGitter> <randiaz95> There seems to be always someone here in Crystal gitter
<FromGitter> <randiaz95> I think same level as Golang discord channel
<FromGitter> <lagerfeuer> True, I've asked something here before and I've always gotten answers immediately :D
<FromGitter> <randiaz95> Wierd how I couldn't find active chats for Python or javascript
<FromGitter> <Blacksmoke16> nvm i cant find it
<FromGitter> <randiaz95> which are much more widely used languages
<FromGitter> <randiaz95> @lagerfeuer I am still trying to read the https://crystal-lang.org/reference/ so I am also still trying to learn idiomatic Crystal
<FromGitter> <grkek> They will probably link you a stackoverflow link
<FromGitter> <randiaz95> @grkek do you mean for js or python?
<FromGitter> <grkek> both
<FromGitter> <grkek> since they are huge
<FromGitter> <randiaz95> Right...
<FromGitter> <grkek> problems which occur are similar
<FromGitter> <grkek> most of the time
<FromGitter> <randiaz95> Stack overflow is a huge FAQ for py and js
<FromGitter> <randiaz95> java and c++ too
<FromGitter> <grkek> Have you heard of the Grip framework?
<FromGitter> <randiaz95> nope
<FromGitter> <grkek> here you go
<FromGitter> <grkek> :^)
<FromGitter> <lagerfeuer> I've found the reference and API docs to be really good so far, it's just some things are a bit weird in Crystal. I also posted to reddit yesterday about abstract classes and `Proc` definitions which use those. I've only used Crystal for a couple hours so far though.
<FromGitter> <grkek> Crystal is easy to learn
<FromGitter> <lagerfeuer> I haven't had any problems with it except some type questions, I like ruby too, I guess that helps.
<FromGitter> <randiaz95> Why grip if Athena exists?
<FromGitter> <randiaz95> In grip a controller is like a handler?
<FromGitter> <randiaz95> must be registered in the app
<FromGitter> <grkek> Ooof
<FromGitter> <grkek> @Blacksmoke16 I guess you won
<FromGitter> <randiaz95> LOL!
<FromGitter> <randiaz95> I haven't looked to deep into it lol
<FromGitter> <randiaz95> It may still be better; but I have looked into Athena.
<FromGitter> <grkek> Grip was branched from Kemal
<FromGitter> <randiaz95> @grkek why do people flaunt requests per seconds without telling us the specs of the computer?
<FromGitter> <randiaz95> 285,013 requests/second. sounds great.. But is that on a 5 dollar digitalocean server?
<FromGitter> <grkek> If you click the link
<FromGitter> <grkek> you will be taken to the specs
<FromGitter> <grkek> :^)
<FromGitter> <randiaz95> I wish they would run it all on a 5 dollar digital ocean server
<FromGitter> <randiaz95> To turn it into a single comparable dollar per request per second lol
<FromGitter> <randiaz95> request per second dollar?
<FromGitter> <ImAHopelessDev_gitlab> i like that metric
<FromGitter> <ImAHopelessDev_gitlab> be good for the low end box community
<FromGitter> <randiaz95> problem its not really dollar its dollar per month
<FromGitter> <randiaz95> requests per second per dollar per second seconds cancel out and its just requests per dollar
<FromGitter> <ImAHopelessDev_gitlab> just times it by 30, *taps head*
<FromGitter> <randiaz95> lol
<FromGitter> <randiaz95> requests per dollar lol
<FromGitter> <randiaz95> if each request is 1 penny per impression we can then see if business model exists..
<FromGitter> <ImAHopelessDev_gitlab> requests per byte consumed
<FromGitter> <ImAHopelessDev_gitlab> have fun
<FromGitter> <randiaz95> Lol
<FromGitter> <randiaz95> memory size too?
<FromGitter> <ImAHopelessDev_gitlab> might as well
<FromGitter> <randiaz95> We would need to make a cost index...
<FromGitter> <ImAHopelessDev_gitlab> 😆
<FromGitter> <randiaz95> cost index = Request per stroke/middle out bytes consumed.
<FromGitter> <grkek> Man I sneezed and broke my laptop almost rip
<FromGitter> <randiaz95> lol
<FromGitter> <randiaz95> No one caught my sillicon valley joke
<FromGitter> <randiaz95> :'(
<FromGitter> <grkek> I did but
<FromGitter> <grkek> it seems a bit
<FromGitter> <grkek> odd?
<FromGitter> <ImAHopelessDev_gitlab> wat was it
<FromGitter> <grkek> The stroke scene where they theorize jacking everyone off to win the prize
<FromGitter> <randiaz95> yep
<FromGitter> <randiaz95> Its hilarious lol
<FromGitter> <ImAHopelessDev_gitlab> oh part of the movie? i thought a joke about sillicon developers
<FromGitter> <ImAHopelessDev_gitlab> i've never seen the movie
<FromGitter> <randiaz95> Its a show
<FromGitter> <randiaz95> its actually on the lower tier of hulu now
<FromGitter> <randiaz95> so I finally got to see it
<FromGitter> <ImAHopelessDev_gitlab> i think the only show i watch is shark tank lol
<FromGitter> <randiaz95> i <3 sharktank
<FromGitter> <ImAHopelessDev_gitlab> my business teacher in 11th grade started showing it in class. i've been hooked ever since
<FromGitter> <grkek> @ImAHopelessDev_gitlab why are you hopeless tho?
<FromGitter> <ImAHopelessDev_gitlab> oprpyin was helping me with a question last year. eventually it got to the point of him saying, "god, you are hopeless" ⏎ ⏎ ever since then, i think that names fit me well
<FromGitter> <grkek> He can be rude sometimes
<FromGitter> <grkek> yes
<FromGitter> <ImAHopelessDev_gitlab> i also realized i'm a contrarian programmer and don't really follow conventions at all, which makes it harder when i ask for help
<FromGitter> <kinxer> @ImAHopelessDev_gitlab I think you're a contrarian in general. :P
<FromGitter> <ImAHopelessDev_gitlab> :D
<FromGitter> <ImAHopelessDev_gitlab> i get emotionally attached to things, that i'm not supposed to get emotionally attached to. it could range from doing a formal job interview, to a character in a programming language
<FromGitter> <ImAHopelessDev_gitlab> or a specific methodology / concept in a language or thing. could be anything
<FromGitter> <kinxer> You still using Tuples for everything?
<FromGitter> <ImAHopelessDev_gitlab> little bit, but mostly went to classes and structs
<FromGitter> <grkek> Well as long as you enjoy it it is just about right
<FromGitter> <ImAHopelessDev_gitlab> i always catch myself writing a tuple then realize wtf am i doing
<FromGitter> <kinxer> Classes and structs are good, and tuples are still useful for some things.
<FromGitter> <ImAHopelessDev_gitlab> exactly
<FromGitter> <Blacksmoke16> not what he was using them for tho :p
<FromGitter> <tenebrousedge> @ImAHopelessDev_gitlab you should pick up Lisp, you might like it
<FromGitter> <kinxer> @Blacksmoke16 Ssshhh, I'm trying to be positive.
<FromGitter> <tenebrousedge> https://xuanji.appspot.com/isicp/ interactive version of MIT's classic text, Structure and Interpretation of Computer Programs
<FromGitter> <ImAHopelessDev_gitlab> one thing i learned over the years is this: it's not the programming language, it's your ability to conceptualize the idea and use the language to express it. i learned most languages can express the concept. ⏎ ⏎ i always thought, "oh, i'll learn this programming language and it will just magically make me learn how to code these things!"
<FromGitter> <kinxer> I don't know where Girng lives, but if it's in the US, there's a great demand for COBOL right now. :P
<FromGitter> <Blacksmoke16> hard part of programming isnt writing the code
<FromGitter> <kinxer> ^
<FromGitter> <Blacksmoke16> its designing the systems that are readable, maintainable, and testable
<FromGitter> <grkek> hard part of programming is trying not to forget to eat
<FromGitter> <tenebrousedge> even modern COBOL is...not my cuppa
<FromGitter> <kinxer> And naming things (though that falls under "readable" and "maintainable").
<FromGitter> <kinxer> @grkek Big oof. Please take care of yourself.
<FromGitter> <ImAHopelessDev_gitlab> my point is a programming language is not going to magically make you a better developer. which is what *i thought*
<FromGitter> <tenebrousedge> "There are only two hard problems in computer science: cache invalidation, naming things, and off-by-one errors."
<FromGitter> <grkek> Crystal can make you a better developer
<FromGitter> <kinxer> Yeah, that's definitely an important lesson to learn.
<FromGitter> <kinxer> @tenebrousedge Is that a Knuth quote?
<FromGitter> <ImAHopelessDev_gitlab> why does that say false
<FromGitter> <tenebrousedge> @kinxer no
<FromGitter> <ImAHopelessDev_gitlab> i use Bcrypt on my masterserver
<FromGitter> <ImAHopelessDev_gitlab> this from a PR?
<FromGitter> <Blacksmoke16> use `.verify` iirc
<FromGitter> <grkek> It says false because the two are different values
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/8x1m
<FromGitter> <grkek> first one outputs this: $2a$10$azWWiMTdJUKCSqenUtPbpO7kKcHp/UIE3hOJ5bLcmJEJOJsn7.QJ2
<FromGitter> <kinxer> Re COBOL: https://learnxinyminutes.com/docs/cobol/
<FromGitter> <kinxer> A great sadness falls upon the land...
<FromGitter> <ImAHopelessDev_gitlab> ok i already use .verify @raz u scared me
<FromGitter> <Blacksmoke16> er https://github.com/crystal-lang/crystal/issues/7753 this one
<raz> ImAHopelessDev_gitlab :P
<raz> i was looking at older api docs that didn't have the verify yet :<
<FromGitter> <grkek> Why use old docs :> ?
<FromGitter> <ImAHopelessDev_gitlab> remnant from google search
<FromGitter> <ImAHopelessDev_gitlab> prob just didn't c
<FromGitter> <grkek> > Didn't C
<FromGitter> <grkek> oof
<raz> grkek: because google spits out random versions and there's no clear indicator
<FromGitter> <grkek> Let's fight the CEO of Google
<raz> nah, let's put a version dropdown in the docs
<raz> :P
<FromGitter> <grkek> That might work as well but
<FromGitter> <grkek> less fun'
<FromGitter> <ImAHopelessDev_gitlab> opyprin can go first since he works there
<FromGitter> <grkek> What does he do at google ?
<raz> and a big fat warning like "this is v0.0.4 - you probably don't want to be looking at this"
<FromGitter> <ImAHopelessDev_gitlab> make PRs for crystal
<FromGitter> <ImAHopelessDev_gitlab> :laugh"
<FromGitter> <ImAHopelessDev_gitlab> @raz good idea lol
<raz> ;)
<FromGitter> <grkek> I feel so horrible right now
<FromGitter> <ImAHopelessDev_gitlab> @raz i don't know how many freaking times i stumble upon an old docs from google's search and have to change it in the url
<FromGitter> <kinxer> @raz Like CMake (https://cmake.org/cmake/help/v3.10/)?
<FromGitter> <grkek> I want to smoke, my gallbladder is irritated and I am suffocating because I cant smoke and cant breathe and I will probably die now
<raz> ImAHopelessDev_gitlab: yup, happens 30 times a day for me. i stopped caring. most of the time they tell me what i want anyway. well... unless it's about bcrypt xD
<FromGitter> <ImAHopelessDev_gitlab> is this COBOL thing for real or an inside joke?
<FromGitter> <tenebrousedge> it's real
<FromGitter> <tenebrousedge> and really in demand right now
<FromGitter> <kinxer> It's widely used in a lot of organizations that created their infrastructure before the 1990s.
<FromGitter> <grkek> Boomers rise again
<FromGitter> <ImAHopelessDev_gitlab> does it have a TCPServer class? That's the real question
<FromGitter> <tenebrousedge> lol
<FromGitter> <kinxer> Lol.
<FromGitter> <ImAHopelessDev_gitlab> deal me in!!
<raz> kinxer: yes please! but don't forget the warning banner like e.g. postgres has: https://www.postgresql.org/docs/9.0/sql-notify.html
<raz> because i imagine most people, most of the time, really don't wanna look at docs about crystal from 3 years ago
<FromGitter> <Blacksmoke16> there has been some progress on that lately
<FromGitter> <Blacksmoke16> new release will show the name/version of the dos
<FromGitter> <grkek> I saw that it was very cute
<FromGitter> <Blacksmoke16> is an issue about warning when not viewing latest as well iirc
<FromGitter> <ImAHopelessDev_gitlab> > you should pick up Lisp, you might like it ⏎ ⏎ is there a ruby to lisp handbook or something? Does lisp have a tcpserver/socket support, etc? (serious question)
<raz> some javascript fu could even redirect to the latest by default. then it takes an extra click if you really want something old, but i think avoids extra clicks and confusion in the more common case
<FromGitter> <ImAHopelessDev_gitlab> dude, this syntax is like js callback hell
<FromGitter> <tenebrousedge> you could probably write Ruby in Lisp, and you could write at least a simple Lisp in Ruby
<FromGitter> <ImAHopelessDev_gitlab> wtf am i looking at
<FromGitter> <tenebrousedge> Ruby has been called an acceptable Lisp: http://www.randomhacks.net/2005/12/03/why-ruby-is-an-acceptable-lisp/
<FromGitter> <grkek> Lisp has worse syntax than bash
<FromGitter> <grkek> imo
<FromGitter> <tenebrousedge> Lisp is more of a discovery than an invention
<raz> lisp has syntax?
* raz scratches head
<FromGitter> <grkek> *Scratches raz's head*
<FromGitter> <tenebrousedge> it's pretty directly analogous to the lambda calculus
<raz> doesn't it have like 3 keywords, and two of them are ( and )
<FromGitter> <ImAHopelessDev_gitlab> good lord kai
* raz purrs
<FromGitter> <grkek> *Lights raz on fire*
<FromGitter> <grkek> oops
<FromGitter> <grkek> sorry I am such a scorpio haha
<raz> that's ok, i need to run for coffee anyway
* raz disappears in a puff of smoke
<FromGitter> <grkek> Oh
<FromGitter> <tenebrousedge> Lisp / LC are sort of the idea that you can start with the identity function, and build all of computing out of just that
<FromGitter> <tenebrousedge> it's as fundamental to computation as ones and zeros, if not more so
<FromGitter> <ImAHopelessDev_gitlab> ``` (defun factorial (n) ⏎ (if (= n 0) 1 ⏎ (* n (factorial (- n 1)))))``` [https://gitter.im/crystal-lang/crystal?at=5e9c8ca05706b414e1ddb0c8]
<FromGitter> <ImAHopelessDev_gitlab> `)))))`
<FromGitter> <grkek> Jesus that is horrible
<FromGitter> <watzon> Basically how an AST works
<FromGitter> <tenebrousedge> yes
<FromGitter> <kinxer> Oh, it uses a prefix notation, too. Huh.
<FromGitter> <watzon> I think most any LISP would make a good introduction to programming
<FromGitter> <tenebrousedge> @watzon MIT agrees
<FromGitter> <watzon> It teaches you how things actually work underneath all the sugar the other languages provide
<FromGitter> <ImAHopelessDev_gitlab> good introduction to make new students ragequit computer science
<FromGitter> <kinxer> I mean, that's the purpose of a good 101 class, right?
<FromGitter> <watzon> Basically
<FromGitter> <watzon> Weed out the weak
<FromGitter> <kinxer> Get rid of the people who are trying to do it because it pays a lot.
<FromGitter> <kinxer> I mean, some of those people happen to be proficient enough to get through, but still.
<FromGitter> <ImAHopelessDev_gitlab> you can weed em just by those terrible online coding games
<FromGitter> <grkek> How does this matter to a student which is just trying to create things?
<FromGitter> <tenebrousedge> “A language that doesn't affect the way you think about programming is not worth knowing.” - Alan Perlis ⏎ By that standard, Lisp is one of the best programming languages ever
<FromGitter> <watzon> Helps you create things better, and more efficiently if you know what the language is actually doing
<FromGitter> <grkek> You need to know just enough to create something you want
<FromGitter> <watzon> People that don't know what the language they're using doing underneath are typically just less efficient programmers
<FromGitter> <grkek> and pay the code monkeys to make it better?
<FromGitter> <watzon> @grkek false
<FromGitter> <kinxer> My comment about 101 classes was mostly a joke. Honestly, I do think that programming should have more accessible entry points for people who just want to learn how to automate simple tasks, run statistical calculations, etc.
<FromGitter> <grkek> @kinxer see this fella agrees with me
<FromGitter> <watzon> @kinxer yeah that's fine, and mostly why languages like Python are so popular
<FromGitter> <watzon> But if you're a serious developer it pays to know what is happening at a lower level
<FromGitter> <grkek> 90% of the Python devs dont even know what the fuck the GIL does
<FromGitter> <grkek> or that it even exists
<FromGitter> <grkek> haha my code go brrrr
<FromGitter> <kinxer> @grkek Hey, now. People who are creating software for a living (or even as a serious hobby) need something different (and harder).
<FromGitter> <ImAHopelessDev_gitlab> gdscript from godot was actually introduced into a school curriculum in west virginia lol
<FromGitter> <kinxer> I mean, Godot seems like a pretty good teaching tool. GDScript is a pretty simple scripting language, and the engine lets you see visually the effects of what you've written.
<FromGitter> <watzon> WVU?
<FromGitter> <ImAHopelessDev_gitlab> when i was in high school, they had an insane amount of courses on adobe flash cs3
<FromGitter> <ImAHopelessDev_gitlab> look how well that got me lmfao
<FromGitter> <kinxer> And if you want to (or if it's assigned), you can get into pretty complex stuff.
<FromGitter> <watzon> Oof, Flash was a nightmare
<FromGitter> <ImAHopelessDev_gitlab> @watzon yeah i didn't even know at the time, i was told it was the "future"
<FromGitter> <watzon> Well that sure turned out well
<FromGitter> <watzon> I only experimented with flash briefly thankfully
<FromGitter> <watzon> Didn't really get into the nightmare that was ActionScript
<FromGitter> <tenebrousedge> I thought it was basically just a version of JS
<FromGitter> <tenebrousedge> which is its own nightmare, I guess
<FromGitter> <watzon> It was, but somehow worse
<FromGitter> <watzon> It
<FromGitter> <watzon> It's still ecmascript
<FromGitter> <ImAHopelessDev_gitlab> i still remember doing the tutorials. if you search em on youtube, and find those adobe flash tutorials from 2007-2010 it was like that. makes tick figures, animate then, go into timeline, start writing as3 code, etc
<FromGitter> <grkek> https://i.imgur.com/0LgYnXC.png
<FromGitter> <ImAHopelessDev_gitlab> web designer teacher came by to each desk to test your "game" to make sure you have jumping or whatever stuff working lolz
<FromGitter> <grkek> this basically sums up the compsci class
<FromGitter> <ImAHopelessDev_gitlab> @grkek ROFL
<FromGitter> <watzon> compsci classes aren't really useful for learning to program, but they can be useful for other things
<FromGitter> <watzon> Especially if you're the kind of person that learns well in a classroom setting
<FromGitter> <watzon> Which I'm not
<FromGitter> <grkek> @watzon I've watched your videos
<FromGitter> <grkek> enjoyed em a lot
<FromGitter> <watzon> Thanks man. I just got a desk and got my spare room turned into an office, so that should make it a bit easier for me to make more
<FromGitter> <grkek> I would love to see one on spreading classes between threads as in multithreading
<FromGitter> <ImAHopelessDev_gitlab> but boy.. i do remember the days everyone in class would be playing flash games and the teacher would always have to manually blacklist the new sites. ⏎ i eventually created a proxy script in php and told a few select friends about in class, web design teacher wasn't happen, then blacklisted that .info domain name. i only paid $1.99 for it at the time so it wasn't that bad lol
<FromGitter> <watzon> Man multithreading is really not my forte yet haha, but I'll see what I can do
<FromGitter> <grkek> Sometimes I just forget about how multithreading actually works
<FromGitter> <grkek> maybe because it violates the laws of physics?
<FromGitter> <watzon> It's just not how we're taught typically. Most people learn to program in a single threaded environment, then you throw some kind of concurrency on top of it that somewhat emulates what you'd expect from multithreading, but still in a single threaded manner. Then when you actually have to deal with multithreading you're like "wtf is happening? what are locks? what is the meaning of life?"
<FromGitter> <grkek> ikr
<FromGitter> <randiaz95> Locks just stops other threads from modifying a datastructure right?
<FromGitter> <randiaz95> So that they other threads wait for it to be available.
<FromGitter> <grkek> correct
<FromGitter> <randiaz95> Dart > Dlang
<FromGitter> <randiaz95> Dart has great ui libraries
<FromGitter> <randiaz95> Dlang just another server language
<jhass> dart is great. if only they would have a null type
<jhass> main thing I miss there
<FromGitter> <randiaz95> It has null though!
<jhass> that's the problem!
<FromGitter> <dscottboggs_gitlab> maybe in libaries but I've never seen another langauge close to the expressiveness and capabilities of D. Dart is decent but there's nothing special about it at the language level. It's just yet another C-like OOP Garbage-collected statically-typed language. Sorry but those have been a dime a dozen for a long time now
* FromGitter * dscottboggs_gitlab apologizes for hanging out in /r/programmingcirclejerk too much lately
<jhass> I think Darts ecosystem and compiler is quite impressive nice though
<FromGitter> <dscottboggs_gitlab> on a crystal-related note, I'm translating some C into Crystal and I love this: ⏎ ⏎ ```CAP.times do |i| ⏎ rbq.push? i ⏎ end``` [https://gitter.im/crystal-lang/crystal?at=5e9ca3e5c38aa05a1a86c283]
<FromGitter> <dscottboggs_gitlab> jhass, I didn't realize there was something impressive about Dart's compiler, in what way?
<jhass> most languages are good at gnerating native optimized code or dynamic introspectable one. Dart seems to have hit a nice sweet spot there where you have things like instant hot code reloading in dev and fully integrated debug support but can compile to target pretty much anything from your browser to some embedded hardware
<FromGitter> <dscottboggs_gitlab> hm, that does sound like a nice development experience, but with knowledge of how much corporate backing Dart has, I'm not surprised that area has been invested in thoroughly. Not sure that speaks to the language itself, but at the end of the day that's a moot point
<antoszka> jhass: you mean like common lisp had for decades? :)
<FromGitter> <dscottboggs_gitlab> CL compiles to JS?
<jhass> yes just with much less ((compsci babble)) around it
<jhass> I'm sure somebody has done it
<jhass> for me ecosystem is a huge part. It's what makes me hate JS even more than its implicit type conversion madness. It makes Java harder than it needs to be because everything is just so fragmented. Haven't really touched PHP in some years but IME it too has too many people not being guided by good tooling into writing good libraries and deployment setups. Good stdlibs I would also totally count
<jhass> into tooling/ecosystem. After that there's not that many differentiating factors left, maybe 3-4 categories, a couple more if you look into concurrency paradigms
<FromGitter> <dscottboggs_gitlab> then what are you doing here? lol not to be mean but crystal's tooling isn't spectacular. I've got *halfway*-decent syntax highlighting, linting, and auto-formatting but that's it. No cached compilation, minimal debugger support, no browser target, etc, etc...
<FromGitter> <randiaz95> y
<FromGitter> <randiaz95> crystals syntax with darts ecosystem would be amazing..
<FromGitter> <dscottboggs_gitlab> JFC yes
<FromGitter> <dscottboggs_gitlab> can you imagine writing cross-platform native apps in crystal? fuck yes
<jhass> maybe we'll get there. As you say we lack the amount of coorporate backing that makes this happen fast. In the meantime it's a fun project to hack on :)
<FromGitter> <dscottboggs_gitlab> true! I just wish the compiler wasn't such a mystery.
<FromGitter> <dscottboggs_gitlab> I've tried digging in several times to hack on it and it's just crazy how complicated it is
<jhass> it certainly could use a rewrite, it has a lot of Ary's make it work style :D
<jhass> after all it started out as PoC/hackathon project
<FromGitter> <dscottboggs_gitlab> Not even a rewrite, just some docs saying "here's what this bit does" would be nice
<FromGitter> <dscottboggs_gitlab> > it started out as PoC/hackathon project ⏎ ⏎ oh jeeze I didn't realize taht
<jhass> did you know it was bootstrapped in ruby? :D
<FromGitter> <randiaz95> Lol!
<FromGitter> <dscottboggs_gitlab> Yes I did
<FromGitter> <randiaz95> Did you know when I was installing a new version of ruby on my computer it actually required crystal as a dependency?
<FromGitter> <randiaz95> Wierd lol
<FromGitter> <dscottboggs_gitlab> hahahahahaaha
<jhass> so the initial idea really was "how much of ruby can we compile?"
<jhass> initial versions required no type annotations whatsoever
<jhass> it just was very slow very fast :D
<FromGitter> <dscottboggs_gitlab> I've seen samples of that, it's crazy
<FromGitter> <randiaz95> very slow very fast?
<FromGitter> <randiaz95> Im confused lol
<jhass> reaching very slow compile times with mildly complex code very fast
<FromGitter> <dscottboggs_gitlab> yeah, makes sense haha
<FromGitter> <dscottboggs_gitlab> TBH it's crazy to even try it, but it's cool that they did
<FromGitter> <dscottboggs_gitlab> I'd love to see them talk about that era now with the experience they've had turning it in to a production-ready semi-popular language
<jhass> it allowed to make the first crystal compiler by largely copy pasting the ruby code,
darkstardevx has quit [Remote host closed the connection]
darkstardevx has joined #crystal-lang
<FromGitter> <randiaz95> So type annotations helped faster compile times.
<FromGitter> <randiaz95> Sorry when i eat i get lethargic.. Its been 1 month of no. exercise lol
<FromGitter> <stronny> I have a question
<FromGitter> <stronny> in c/c++ arg evaluation in a call has no guaranteed order, right? so `f(a++, a++)` is UB right?
<FromGitter> <stronny> well what about Crystal? is it all right to do `f(aes.update(ciphertext), aes.final)`?
<hightower2> Hey is there a way to break the outer loop from the inner one? I see that `break` only accepts the exit/return value, not the loop name
<FromGitter> <stronny> make the outer loop a method and return
<jhass> well, let's be honest nothing in Crystal is defined behavior :D
<jhass> I would expect currently it's a yes though
<FromGitter> <stronny> the same goes for shortcut eval like `expr || expr`, we can rely on the order I'd imagine
<jhass> yeah, that's even defined somewhat since that short-circuits is documented
<jhass> so how can it shortcircuit if evaluating the RHS first, that'd be contradictionary
<FromGitter> <stronny> it's all over the place, idiomatic ruby and by extension crystal
<hightower2> stronny indeed will do it with a function, thanks
ur5us has joined #crystal-lang
<FromGitter> <kinxer> I've been thinking about how to make an interface akin to `JSON::Serializable` for XML; has anyone seen something like that (or another good XML serialization interface) in any other languages?
_ht has quit [Quit: _ht]
<FromGitter> <asterite> c# does it, I would look at that
<FromGitter> <kinxer> Thanks; will do.
<FromGitter> <watzon> Golang actually does as well
<FromGitter> <watzon> With their `marshal/unmarshal`
<FromGitter> <sardaukar> hello all 👋
<FromGitter> <sardaukar> so I have a server running with a WebSocketHandler, and it's fine
<FromGitter> <sardaukar> except when I get `Error writing to socket: Broken pipe (IO::Error)` sometimes
<FromGitter> <sardaukar> I believe it's because of Firefox's dodginess
<FromGitter> <sardaukar> how can I rescue these errors?
<FromGitter> <sardaukar> I tried surrounding the `server.listen` call with a begin/rescue but no dice :|
<hightower2> Hey folks, what's the fastest/most optimized way to find minimum of 3 numbers, but which may be nil? (In case they are nil they are skipped, i.e. they should not affect comparison)
<FromGitter> <sardaukar> this is the error I get https://gist.github.com/sardaukar/2d0089c6eabe3314adae790ef138a954
<raz> hightower2: depends on the context, but perhaps something like n || 0 can work to avoid a nil problem?
<jhass> more like || Int32::MAX
<raz> ehm yea. math was never my strongest subject.
<hightower2> yes, that'd probably work, yeah sounds like the easiest, thanks
<jhass> any of the three can be nil or only one of them?
<hightower2> all
<FromGitter> <watzon> @sardaukar to catch the error you can just do ⏎ ⏎ ```begin ⏎ # your code ⏎ rescue err : IO::Error ⏎ # do something on `IO::Error` ⏎ end``` [https://gitter.im/crystal-lang/crystal?at=5e9cc82cd240da243386204a]
<FromGitter> <watzon> Ahh you tried catching it
<FromGitter> <watzon> It would help to see the code
<FromGitter> <sardaukar> here's the server bit https://gist.github.com/sardaukar/9b4bfbaf6715333183c89ea7004ce557
<FromGitter> <sardaukar> I'm using `IO::Error` on the rescue now, but it doesn't seem to catch the error for some reason
<FromGitter> <sardaukar> Firefox just reconnects the websocket or something, because after that broken pipe error, it keeps working (I have a ping going, and the ping resumes after the error)
<FromGitter> <watzon> So the error likely isn't in the `server.listen` call. Try just using a rescue for the entire `run!` block
<FromGitter> <sardaukar> ok
<FromGitter> <watzon> So ⏎ ⏎ ```def run! ⏎ # your code ⏎ server.listen ⏎ rescue err : IO::Error ⏎ end``` [https://gitter.im/crystal-lang/crystal?at=5e9cc8e0d240da2433862340]
<FromGitter> <sardaukar> same error
<jhass> hightower2: but maybe just d = a; d = a < b ? a : b if a && b; d = a < c ? a : c if a && c
<FromGitter> <watzon> Ok so the error has to be occurring elsewhere
<FromGitter> <sardaukar> I don't understand how the rescue is not catching the error
<FromGitter> <sardaukar> the server starts up here
<FromGitter> <sardaukar> the stacktrace shows Crystal's code...?
<FromGitter> <sardaukar> ```code paste, see link```
<jhass> the server spawns a fiber for each incoming request
<jhass> the exception crashes that fiber I guess
<FromGitter> <sardaukar> so is there any way to catch it?
<FromGitter> <watzon> Yeah must be
<jhass> but I guess the latter doesn't fix it for websocket handling?
<FromGitter> <sardaukar> do you think I should comment on 9065 with my use case?
<jhass> mh, no. 9095 might influence how we fix it in stdlib for your issue, but it'll need to happen there
<jhass> WebsocketHandler should handle this more transparently for you
<jhass> so might be worth a new issue
<FromGitter> <sardaukar> ok, I'll try to create a new one
<FromGitter> <stronny> 1) ignore IO::Error ⏎ 2) start getting strange bugs ⏎ 3) ??? ⏎ 4) F U N [https://gitter.im/crystal-lang/crystal?at=5e9ccbd4d65bcf75b5d57be6]
<jhass> otoh taking a second look at the trace, it does go through RequestProcessor and handle_client
<jhass> so maybe 9115 already fixes it?
<jhass> stronny: not any IO::Error, just EPIPE. https://pmhahn.github.io/SIGPIPE/ explains excellently why
<FromGitter> <stronny> what? where do you get a sigpipe from?
<jhass> the kernel. read the link :D
<jhass> also 9065 is worth a read
<FromGitter> <stronny> I read mans not links with python
<FromGitter> <stronny> ```code paste, see link```
<jhass> sardaukar: if you need to workaround this now, short of monkeypatching stdlib, inserting a HTTP::Handler at the right place that catches it might work, but I didn't try. And then this just spams your log, it doesn't crash the server, right?
<FromGitter> <stronny> 1) you don't want sigpipe set MSG_NOSIGNAL ⏎ 2) the correct way to deal with this would be to net write to a closed socket
<FromGitter> <sardaukar> it doesn't crash the server, Firefox just skips a ping message and carries on to the next ping
<FromGitter> <sardaukar> I just wanted to keep the users from panicking and seeing the error
<FromGitter> <stronny> but that would be impossible for crystal, so let's support one hack with a bunch of other hacks
<jhass> probably after reconnecting, it does look like the current connection was lost
<FromGitter> <stronny> so I'm grumpy, it's just I've lost 6 months on this rubbish
<jhass> pull requests are always welcome :)
<jhass> we're all learning
<FromGitter> <sardaukar> hope it makes sense
<FromGitter> <sardaukar> jhassh: me too! 😅 not sure how to handle this
<FromGitter> <sardaukar> a bit too low-level for my area of expertise, I think
<FromGitter> <stronny> am I reading this right? are you gonna just ignore sigpipe globally?
<jhass> if the user doesn't handle it
<jhass> for stdin/stdout/stderr
<jhass> most languages seem to do that
<FromGitter> <stronny> actually it's less catastrophic than I imagine, you'll still gonna get an exception ⏎ the only inconvenience is that the program will exit with an exception than just silently
<FromGitter> <sardaukar> so why is there a broken pipe error anyway?
<FromGitter> <stronny> because you are reading a closed socket
darkstardevx has quit [Ping timeout: 258 seconds]
<jhass> generally because the reader you're writing to is gone
<FromGitter> <stronny> or writing
<jhass> so in case of a network socket the connection was lost (or closed by the client)
<FromGitter> <sardaukar> why does that happen, though? I'm not managing the sockets myself so it feels like Crystal could make it... not happen?
<FromGitter> <sardaukar> this is all localhost, so why would connections be dropping?
<FromGitter> <stronny> with current concurrency model, yeah, good luck with than
<jhass> no idea wh but apparently it does
<FromGitter> <stronny> why wouldn't sockets get closed on loopback iface though?
<jhass> stronny: know any language that raises exceptions for IO errors and does not ignore this on stdout/stderr?
<FromGitter> <stronny> sorry don't understand the question
<jhass> you seem opposed to crystal not printing the exception if you do crystal_program_with_lots_of_output | head
<FromGitter> <stronny> the customary way is a builtin sigpipe handler
darkstardev13 has joined #crystal-lang
<FromGitter> <stronny> will just kill your program and that's it
<jhass> why's catching the exception so different?
<jhass> note my proposal is to catch it _after_ any user code
<jhass> so totally overridable
<FromGitter> <stronny> it's messy, it exposes the inner gear to users
<FromGitter> <stronny> not to users of Crystal mind you, to end-users
<jhass> I don't follow, suppressing the output is exactly the proposal
<FromGitter> <sardaukar> I think he means it "lifts the veil" on Crystal internals too much for users
<FromGitter> <sardaukar> instead of having an established abstraction over it somehow
<jhass> I don't follow how foro that either
<jhass> the problem with the global SIGPIPE handler is that it's hard to differentiate in there where the error came from. I'm not going to repeat here now, but the point is well made in https://github.com/crystal-lang/crystal/issues/9065#issuecomment-613574298
<FromGitter> <stronny> maybe I got mixed up in all of this
<FromGitter> <stronny> yes, signals don't have context
<FromGitter> <stronny> my ideal solution would be this: ⏎ ⏎ 1) leave sigpipe as is. "Nobody wants a HTTP server to exit because a client closed a connection." well then use libc as intended, you already have all the tools ⏎ 2) fix the stdlib so that it doesn't request sigpipe when it can't handle it ⏎ 3) fix the language and stdlib so *reading a closed socket* is an error, not a norm [h
<FromGitter> ... ttps://gitter.im/crystal-lang/crystal?at=5e9cd33cd240da2433864780]
<FromGitter> <stronny> as it's clearly unrealistic, I guess I'm fine with ignoring sigpipe and just hacking around so that EPIPE would `exit(1)`, but only on 0, 1 and 2
<jhass> I admit I'm not too well versed in systems programming: isn't reading from a socket the way you find out it was closed by the client?
<jhass> how do you "not request sigpipe"?
<FromGitter> <anicholson> 👋 Hi everyone, I have a macro question, based upon this simple gist: ⏎ ⏎ https://gist.github.com/anicholson/714503c05584225a55d478c04a48adfe
<oprypin> anicholson, `{{ *` is a construct to comma-separate the args
<oprypin> just do `{%for expr` `{{expr}}`
<FromGitter> <stronny> ```code paste, see link``` ⏎ ⏎ which is a bit problematic sure [https://gitter.im/crystal-lang/crystal?at=5e9cd51ed240da2433864e8b]
<jhass> that's send(2)?
<FromGitter> <anicholson> @oprypin okay, that would probably work. I'd be a bit sad to leave the Enumerable syntax behind but if that's the idiom then great :)
<FromGitter> <stronny> yeah
<oprypin> anicholson, well u dont have to abandon that syntax. though it's better to, because notion of idiomatic code in macros is different.
<oprypin> i mean `{% for expr in expressions.select { |x| (x.class_name == "Call") }.map { |x| x.block.body } %} {{expr}} {% end %}`
<jhass> I'm not sure avoiding the exception is really worth to redo IO::FileDescriptor just for sockets
<oprypin> but yeah thats not nice
<FromGitter> <stronny> sockets use send already, they overload
<jhass> oh?
<FromGitter> <anicholson> @oprypin I didn't think to look for that because when I didn't try to splat them, it interpolated the result as a collection. Does `.each` do what I want here? I assumed not but if the other answer is a `for` comprehension then maybe it would?
<jhass> mh, indeed
<FromGitter> <stronny> I guess it may be the case that EPIPE is completely unavoidable (you send 1000 bytes, socket closes after 500)
<FromGitter> <stronny> well the way our ancesors dealt with it is a fork per client lol
<jhass> I'd also wonder about portability to BSD, Darwin etc
<oprypin> anicholson, im not sure what you're talking about. `each` is not idiomatic in macros, or maybe doesnt even exist, i dont remembe
<jhass> I really don't see why just handling the error in stdlib in all the places it makes sense is so bad
<FromGitter> <stronny> because how do you handle it?
<oprypin> anicholson, `{%for` is the replacement of `each`
<FromGitter> <stronny> are you sure silencing this exception will be appropriate *always* ?
<jhass> your proposal is just supressing it as well, no?
<oprypin> anicholson, but again, idiomatically this would use neither `select` nor `map`.
<jhass> just via different means
<oprypin> `{% for x in expressions %} {% if x.class_name == "Call" %} {{ x.block.body }} {% end %} {% end %}`
<FromGitter> <stronny> no, I wouldn't treat it differently, I'd leave it as exception
<FromGitter> <stronny> I'd just make it so it becomes meaningful
<FromGitter> <stronny> first thing that comes to mind is an API like this ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5e9cd7e55706b414e1debde1]
<FromGitter> <stronny> just to give an idea
<FromGitter> <stronny> then you can indeed lose EPIPE wrt sockets, but you have aclear code path out of it
<jhass> that seems to be something to discuss meaningfull interfaces for per stdlib component
<jhass> "I want to have a callback for when the socket for my websocket client was closed" is a very legit feature request
<jhass> and I would never pose a policy where the answer to this is "we cannot do this because we always ignore EPIPE". Of course not.
<jhass> but for now to just ignore EPIPE does seem to improve over status quo, which is confusing users with notifying them about something they cannot handle
<FromGitter> <stronny> the problem is much harder
<FromGitter> <sardaukar> yeah, feels bad to not be able to `rescue` it
<FromGitter> <stronny> EPIPE is write half-socket is closed, read half could be alive and kicking
<jhass> only one more reason to look at the best interfaces per usecase in stdlib
<FromGitter> <stronny> question: how do you concurrently read and write on the same socket AND handle errors in a meaninful way in Crystal?
<jhass> working with plain Socket API? Just rescue?
<FromGitter> <stronny> so you have two exceptions at the price of one
<jhass> so what
<FromGitter> <stronny> possibly EOF and EPIPE, but not nessecerily
<FromGitter> <stronny> that's not meaningful, that's helpless
<FromGitter> <stronny> hey, while we're at it let's silence EOFError as well, it's confusing and users can't handle it
<jhass> you're not being very constructive here and I should gone to sleep an hour ago anyways. If you have meaningful and constructive proposals for improving status quo you know the community is always responsive to such. I think nobody claims that we have a perfect design here yet. Most of us are aware that probably just doesn't exist
<FromGitter> <stronny> I have a prototype for concurrency improvements
<FromGitter> <stronny> I've posted it several times, but it's a lot of work to comb through
<FromGitter> <stronny> so only one person did that
<FromGitter> <stronny> anyway sorry to keep you awake
<FromGitter> <stronny> I'll shut up