jhass changed the topic of #crystal-lang to: The Crystal programming language | https://crystal-lang.org | Crystal 0.35.1 | Fund Crystal's development: https://crystal-lang.org/sponsors | GH: https://github.com/crystal-lang/crystal | Docs: https://crystal-lang.org/docs | Gitter: https://gitter.im/crystal-lang/crystal
deavmi has quit [Ping timeout: 240 seconds]
deavmi has joined #crystal-lang
<FromGitter> <scriptmaster> Holy F!! crystal 0.34.0 built kemal server is running at 0.3% of overall Mem on a commodity server. ⏎ nginx workers at 0.5% Mem ⏎ php-fpm 1.5% Mem ⏎ C# dotnet compiled 1.1% ⏎ dotnet run dev 2.1% ... [https://gitter.im/crystal-lang/crystal?at=5efa8358ec4a341beef8f0d4]
postmodern has quit [Quit: Leaving]
<FromGitter> <scriptmaster> I am amazed this is lighter than dotnet - my present choice in production :| This will be a big change for me in future. I am yet to run some tests and see to memory pressure over time. dotnet has been running for a while (days) and my experience in .NET overall = 14+ years. OMG !
<FromGitter> <scriptmaster> 1220 root 20 0 70480 7716 6268 S 0.0 0.4 0:00.01 kemal2 ⏎ 11737 root 20 0 70152 6732 5500 S 0.0 0.3 0:00.00 crystal-server
<FromGitter> <scriptmaster> @dscottboggs_gitlab thanks much! :)
<FromGitter> <dscottboggs_gitlab> Glad to have been able to help! Kemal is indeed an awesome server library, my choice!
oddp has quit [Ping timeout: 258 seconds]
<FromGitter> <scriptmaster> I am off my present job from Dell - I would love to get some work in kemal on remote
<FromGitter> <Blacksmoke16> kemals nice but basic
<FromGitter> <Blacksmoke16> since its more of a fancy router imo, so you end up essentially making your own framework with it as the base
<FromGitter> <dscottboggs_gitlab> true, but I usually just create JSON APIs with it and use Vue for the frontend, so it doesn't make that much of a difference. Also, not a fan of ORMs since I'm pretty decent with SQL as it is.
<FromGitter> <Blacksmoke16> time to checkout Athena again 😉 that's its specialty ha
<FromGitter> <scriptmaster> @dscottboggs_gitlab yep, I am good with SQL and good modeling techniques too. For frontend, I moved on to Svelte and Elm - but I dropped nodejs for server-side production apps many years ago and have been successfully running dotnet-core for many production apps.
<FromGitter> <dscottboggs_gitlab> Svelte is also a great option -- when I last looked into it it was a little young but I have heard it has evolved well since then
<FromGitter> <scriptmaster> Svelte is what we were trying to create a decade ago, with a C# transpiling, back from IE6/9 days, until Rich Harris took it and completed - haha :) Elm has types. TS is moving towards C#/wasm and why would someone let consumers download 1M .net/wasm runtime with a blazor app. I am very much considering a re-write of some production app in crystal/kemal soon.
alexherbo24 has joined #crystal-lang
alexherbo2 has quit [Ping timeout: 265 seconds]
alexherbo24 is now known as alexherbo2
<FromGitter> <wyhaines> @Blacksmoke16 So, Athena's sweet spot is APIs?
<FromGitter> <Blacksmoke16> at the moment yes, as it allows to focus on the core foundational stuff
<FromGitter> <Blacksmoke16> then once that is solid/proven can add additional abstractions to handle other stuff
<FromGitter> <Blacksmoke16> have any questions or anything feel free to join the gitter channel https://gitter.im/athena-frameworkcr/community
<FromGitter> <wyhaines> Cool. I will put some time into checking it out more deeply.
<FromGitter> <Blacksmoke16> 👍 sounds like a plan
postmodern has joined #crystal-lang
<postmodern> wondering whether people use "crystal" or "crystal-lang" when listing it in resumes or job postings? noticing that "crystal reports" tends to overlap with the "crystal" keyword.
<FromGitter> <Blacksmoke16> I'd probably include lang to make it a bit more clear
<FromGitter> <Blacksmoke16> Kinda how to Lang is fairly common
<FromGitter> <Blacksmoke16> Go lang
<postmodern> one word, hyphen, or space separated?
<FromGitter> <Blacksmoke16> 😬
<FromGitter> <wyhaines> IMHO, Crystal Language, or Crystal-lang. The main thing is to avoid that ambiguity with Crystal Reports.
<FromGitter> <Blacksmoke16> IDK I'm an engineer not a linguist 😆
<FromGitter> <Blacksmoke16> Do what I do and Google it and see what it corrects it to ha
<FromGitter> <aravindavk> #crystallang is used in twitter
<FromGitter> <Blacksmoke16> can a hashtag have a space or a hyphen tho?
bazaar has quit [Ping timeout: 258 seconds]
<FromGitter> <plambert> If I have a string that contains `\\u1234` style unicode points, how can I convert that with, for example, a `#gsub` call?
<FromGitter> <plambert> In other words, given a string `"\\u0022foo\\u0022:\\u0022bar\\u0022"`, I want to substitute the unicode escapes and get `"\"foo\":\"bar\""`
bazaar has joined #crystal-lang
<FromGitter> <plambert> I have tried `my_string.gsub(/\\u(....)/) { |m| String.new m[2..5].hexbytes }` and I get nulls instead of the actual characters.
<FromGitter> <plambert> Any thoughts, anyone? :)
<FromGitter> <Blacksmoke16> arent you double escaping the `\`
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/9cm3
<FromGitter> <plambert> The string contains the backslashes, the letter u, and four hex characters.
<FromGitter> <plambert> This is not a Crystal string constant at compile time.
<FromGitter> <plambert> It is the response from a web server.
<FromGitter> <plambert> So if I `puts my_string.inspect` I get exactly what I showed above. At runtime.
<FromGitter> <Blacksmoke16> and what if you just do `puts my_string`
<FromGitter> <Blacksmoke16> `inspect` is going to escape stuff to show you what it actually is, otherwise it probably is actually already what you want
<FromGitter> <plambert> What it actually is, is not what I want. I do not want nulls.
<FromGitter> <plambert> If i print it out, I will not see the nulls, and I will be really happy, until I try to parse the JSON, when it will fail.
<FromGitter> <plambert> Because there are nulls.
<FromGitter> <plambert> Imagine the string is actually `%{0022}`. How would I do it then? (It's confusing since it's the same notation Crystal uses in a constant, but this is not a constant.)
<FromGitter> <plambert> What I really want is to create a `Char` from a codepoint.
<FromGitter> <plambert> I could just ignore the `00` and it'd work for the single-byte characters. But not for the multi-byte characters.
<FromGitter> <Blacksmoke16> > It's confusing since it's the same notation Crystal uses in a constant, ⏎ ⏎ hm?
<FromGitter> <Blacksmoke16> what does that have to do with a constant?
<FromGitter> <plambert> Your play example used a Crystal constant, where the compiler interpreted the `\u` sequences. This is not a Crystal string constant.
<FromGitter> <plambert> So clearly there is confusion.
<FromGitter> <Blacksmoke16> it did?
<FromGitter> <Blacksmoke16> constant might not be the right word, as im thinking of like `FOO = "foo"`
<FromGitter> <plambert> No, a string constant is `"..."`
<FromGitter> <Blacksmoke16> ah a literal
<FromGitter> <plambert> As opposed to a string that is different each time the program runs.
<FromGitter> <watzon> You mean a String Literal
<FromGitter> <plambert> Thank you. String literal.
<FromGitter> <Blacksmoke16> i dont suppose you can share a larger example, you mentioned you're trying to parse JSON returned via a request?
<FromGitter> <plambert> (Which *is* a constant... but yes, String Literal is what I meant.)
<FromGitter> <plambert> The web server returns a string that looks like the one I gave.
<FromGitter> <plambert> Specifically, it's a web page that has one line that looks like `foo = "{\\u0022foo\\u0022:\\u0022bar\\u0022}"`
<FromGitter> <plambert> It is javascript code.
<FromGitter> <plambert> Inside those quotes is valid JSON. But I need to parse the `\\u` escapes.
<FromGitter> <plambert> So, given a UInt32, how can I get the associated Char?
<FromGitter> <Blacksmoke16> `.ord`
<FromGitter> <Blacksmoke16> er `.chr`
<FromGitter> <plambert> Awesome. That is what I couldn't find.
<FromGitter> <plambert> Thank you!
<FromGitter> <watzon> https://carc.in/#/r/9cml
<FromGitter> <watzon> Or shorter https://carc.in/#/r/9cmq
<FromGitter> <plambert> Thank you both, @Blacksmoke16 and @watzon !
Welog has quit [Ping timeout: 256 seconds]
Welog has joined #crystal-lang
ryanprior has quit [Quit: killed]
psydroid has quit [Quit: killed]
return0e[m] has quit [Quit: killed]
hamoko[m] has quit [Quit: killed]
ryanprior has joined #crystal-lang
hamoko[m] has joined #crystal-lang
return0e[m] has joined #crystal-lang
psydroid has joined #crystal-lang
oddp has joined #crystal-lang
postmodern has quit [Quit: Leaving]
<sorcus> Can i use `@type.instance_vars` for generation methods and how?
<jhass> what are generation methods?
<sorcus> jhass: Sorry, i mean `for generating methods.`
<jhass> sorcus: so here's a little secret (which you shouldn't use for your own library internals): foo.@var is valid code, instance variables aren't actually private
<jhass> I mean shouldn't except for
raz has quit [Ping timeout: 265 seconds]
<jhass> mmh, I would expect @type.instance_vars to be populated in a macro finished hook, but somehow it's not
<jhass> sorcus: anyways, consider a solution like the standard library getter,setter,property family of macros, defining the instance variable and any methods for it at the same time
<sorcus> jhass: Ok. thank you :-)
raz has joined #crystal-lang
<FromGitter> <asterite> sorcus: instance variable information is only available inside methods (when you use macros inside methods that are called)
<FromGitter> <asterite> for example that's how `Object#inspect` is implemented, by introspecting the instance var. However you can't generate methods, classes or basically anything by querying instance vars because that info is not available at that point. Only inside methods
<jhass> asterite: I guess we need to fix the docs then
<jhass> > finished is invoked after instance variable types for all classes are known.
<sorcus> asterite: Thanks :-)
<FromGitter> <ImAHopelessDev_gitlab> @postmodern on my resume it's listed as crystal-lang
wmoxam has quit [Ping timeout: 260 seconds]
<FromGitter> <asterite> finished is invoked when the last line of code is reached
<FromGitter> <asterite> I didn't write those docs, though
<jhass> asterite: so the correct way would be to say after parsing finished?
Welog has quit [Read error: Connection reset by peer]
<FromGitter> <asterite> I guess so
alexherbo2 has quit [Quit: The Lounge - https://thelounge.chat]
alexherbo2 has joined #crystal-lang
<FromGitter> <bdtomlin> Are there any drawbacks to cross compiling? The docs say "Crystal supports a basic form of cross compilation" but is the resulting binary from following that procedure the same as if compiled locally?
<FromGitter> <Blacksmoke16> it would be bigger size wise
<jhass> why?
<jhass> From Crystal's perspective it should be. The major question is whether your local LLVM build behaves the same as it would on the target machine
<FromGitter> <Blacksmoke16> wouldnt the libs it requires be included in the binary and not accessed from the system?
<jhass> no
<FromGitter> <Blacksmoke16> oh
<jhass> you're thinking of static vs dynamic linking, which is orthogonal to cross compiling
<FromGitter> <Blacksmoke16> ohhh right
<FromGitter> <Blacksmoke16> my bad
<FromGitter> <Blacksmoke16> dont mind me :p
<raz> hmm, how do you ensure you have the right library versions locally to cross-compile a dynamic executable?
<raz> that seems like black magic to me
<jhass> --cross-compile doesn't link
<raz> (i mean you can barely compile a plain linux binary on a linux box and have it work on another linux)
<jhass> it gives you the linker command and an object file to copy to the target
<raz> ohhh
<jhass> but yeah, stuff might still get amiss if your local version of the library is different and there's some binding code inspecting the version and doing different stuff depending on thatr
<jhass> openssl is a prime example here
<raz> openssl is always a prime example :<
<raz> how many decades old? and still breaks like every other month
<jhass> in general the topic is too complex and the question to broad to answer though, it depends a lot on what your host and target actually are
<jhass> and even then there's often more than one sensible way depending on your circumstances
<raz> yeh personally i just hope crystal gets its static build story sorted soon. that's where (my) money is. build static in VM of target OS and then not worry anymore.
<jhass> that's more of a OS story than a crystal story unfortunately
<jhass> alpine is basicallly popular for making this a little easier and providing static library builds for most things
<raz> is it? for me static builds in alpine seem almost there. except i only get ??? instead of backtraces, and occasional seg faults during compilation (but not in the resulting binary, at least not seen one yet)
<FromGitter> <Blacksmoke16> should have been fixed in latest release
<raz> yup, still have to try with .35
<raz> fingers crossed
<FromGitter> <bdtomlin> It sounds like there are some issues, so is cross compiling not recommended at the moment? Are most people just compiling on the destination?
<raz> i'm just waiting for static build to work on linux, osx, windows. then i can build my slack killer, collect VC millions and fund crystal until Go is extinguished
<jhass> bdtomlin: I just don't think it's topic that's too common or even comphrensibly explored in the community yet. Do what works for you, report any issues you find :)
<raz> it might also depend on cross-compile from where to where (from linux to win32?)
<FromGitter> <j8r> cross compiling is usually more manual than having a CI/CD that static link and deploy
<FromGitter> <j8r> or just dynamic link of course
<raz> i think having static builds on all platforms is a more fruity target, enabling more use-cases (easily distribute apps that work anywhere). cross-compile is kinda a convenience/speed thing (saves using a VM to compile)
<FromGitter> <j8r> not really for cross compile
<jhass> I don't see how static linking is a per target topic
<FromGitter> <bdtomlin> My issue is that I have a lucky app developed on Mac OS and deployed on ubuntu. Currently I have to have a larger vm instance just so it can compile, not to mention the resources used when deploying.
<FromGitter> <j8r> because you need to compile it anyway somehow
<FromGitter> <j8r> that's definitely not a good practice to have devs compiling their apps in their PC and deploy it
<raz> bdtomlin: would try docker. can be almost a one-liner in most cases
<jhass> bdtomlin: sounds like you should just invest into a CI/CD pipeline
<FromGitter> <j8r> A CI is not enough for compiling?
<raz> well if he just wants an ubuntu binary he could `docker run ubuntu`, mount local directory, compile, then copy the binary to the server
<jhass> macos docker is still a VM, fwiw
<raz> yes sorry, not talking about cross-compiling, just thought that's the problem he's trying to solve
<raz> (figured it might be easier to solve with docker than cross-compile)
<sorcus> If `Tuple` contains many numbers, should i specify `Tuple(Int32, Int32, Int32, ...)` for `property`? Maybe there is something shorter like `Array(Int32)`?
<jhass> sorcus: yeah, sounds like you've outgrown the valid usecases for tuple there
<jhass> probably Array, maybe StaticArray or Deque
<FromGitter> <bdtomlin> All good suggestions. This started as a relatively simple experiment app, but turned into something mission critical. Thanks for all the feedback.
<sorcus> jhass: Thank you again :-)
<jhass> yw
<sorcus> If i understand corretly, my `ptr` will be resired by realloc `proc` - https://github.com/crystal-lang/crystal/blob/master/src/big/lib_gmp.cr#L217
<sorcus> *correctly
<sorcus> *resized
<frojnd> Maybe someone more experienced will know how to help me. All I need is just a light db which takes a json, date, and a boolean flag. Out of this db I need to serve only get api calls for clients. They will only get one json at a time on their clients. I was thinking luck will do it but I think this is overkill for my use case. I will insert json (which contains string of about 2500 chars) myself
<frojnd> manually into db. So I really need somekind of serverless api solution. Also postgresql seems overkill for my use case. Any ideas suggestions? Sorry I know this isn't crystal related
<frojnd> s/luck/lucky
<FromGitter> <Blacksmoke16> is there routing involved, or only 1 endpoint?
<frojnd> Only one endpoint. Authentication preferred if possible
<frojnd> Bearer token or smth
<FromGitter> <Blacksmoke16> depending on *how* basic you want to be, one option would be to use like https://crystal-lang.org/api/master/HTTP/Server.html
<frojnd> And then I Just hook it with mongoDB
<FromGitter> <Blacksmoke16> and just handle auth/invalid paths in the basic server implementation
<FromGitter> <Blacksmoke16> yea
<frojnd> Any examples on how to do it without frameworks? I mean get data from db after api call?
<FromGitter> <Blacksmoke16> i mean that approach wouldnt be using a framework, other than a `mongoDB` shard id imagine
<frojnd> Ah ok
<FromGitter> <Blacksmoke16> ofc its also the most basic with the least amount of features if you ever wanted to expand on it
<frojnd> Will consider it after I get / if any users haha
<FromGitter> <Blacksmoke16> but for a single static endpoint that does 1 thing, its prob fine
<frojnd> Great, thank you.
<FromGitter> <Blacksmoke16> np
Human_G33k has quit [Ping timeout: 264 seconds]
postmodern has joined #crystal-lang
Welog has joined #crystal-lang
postmodern has quit [Quit: Leaving]
<FromGitter> <christopherzimmerman> Is there a reason that `Tuple.map` drops it's result to a union type? Shouldn't the outcome of the `map` be known at compile time?
<FromGitter> <christopherzimmerman> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5efb91dd6c06cd1bf4643b5b]
<FromGitter> <Blacksmoke16> because `.map` happens at runtime, it can't know what you're doing
<FromGitter> <plambert> It *could* know, I think. At least in many cases.
<FromGitter> <plambert> Since it knows the exact types of the members of the tuple at compile time, it could follow each type through the function to find the result.
<FromGitter> <Blacksmoke16> maybe, but at that point should you be using a tuple still?
<FromGitter> <plambert> I don’t know, it wasn’t my original question. Do we know all the possible use cases, and whether they’re “worthy?"
<FromGitter> <christopherzimmerman> I'm working on a DataFrame library. Using a `tuple` to store each series of the `DataFrame`, since types need to be known. I need a way to map a function across all of them, and maintain their independent data types.
<FromGitter> <christopherzimmerman> I had the same thought as Paul, I think it would be possible to know the type of Tuple maps in all cases
<FromGitter> <jwoertink> If you have the `-Dpreview_mt` turned on, it seems you can't use `Process.fork`. Is there another method? Or would you just use `spawn` in place of it?
<FromGitter> <kazzkiq> What is the state of statically linked binaries?
<FromGitter> <Blacksmoke16> apline + docker makes it easy
<FromGitter> <kazzkiq> If I build a statically linked binary for Linux distribution, should I be concerned of it not working depending on Linux distro, etc?
<FromGitter> <Blacksmoke16> afaik it should be fine assuming its the same architecture
<FromGitter> <kazzkiq> I remember someone saying in the forum once that they use older versions of distro for building so they make sure the binary will always run properly. (if they compiled in newer versions it may not be backwards compatible with some dependency etc)
<FromGitter> <kazzkiq> Not sure if this is a thing or I can just build using Alpine and be done with it.
raz has quit [Ping timeout: 260 seconds]
<FromGitter> <asterite> @plambert `Tuple#map` does `yield`, and `yield` just invokes the block. Sometimes it's invoked with an int, sometimes with a string. So the type of `yield` becomes the union of all of that. If you need to map over a tuple you can just write the tuple again and map over each value.
<FromGitter> <asterite> I guess technically the compiler could make each `yield` be independent of each other... but it's probably not worth it
<FromGitter> <wyhaines> @jwoertink Forking doesn't play nicely with threads. What is your use case for forking?
<FromGitter> <jwoertink> spinning up multiple http servers
<FromGitter> <jwoertink> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5efb9e82b8152d3484731626]
<FromGitter> <Blacksmoke16> 😬
<FromGitter> <jwoertink> if I change that to `spawn` it breaks in some strange ways
<FromGitter> <Blacksmoke16> `HTTP::Server` handles each request in its own fiber, so you really only need 1 server and MT handles the rest afaik
<FromGitter> <Blacksmoke16> prob some things arent thread safe
<FromGitter> <jwoertink> That's what I was thinking too. Figured I'd see how well this plays with minimal changes
<FromGitter> <wyhaines> Yeah, what @Blacksmoke16 said. If you are running multithreaded, forking a bunch of processes like that doesn't make a lot of sense. Just run a single server and let it do it's thing. With each request in a fiber, your work load will be spread out among your cores. ⏎ ⏎ But, yeah, be careful of thread safety. There still be dragons there.
<FromGitter> <Blacksmoke16> next step would be to ensure you're not sharing anything
<FromGitter> <Blacksmoke16> or if you are, doing it correctly
<FromGitter> <plambert> @asterite Thanks for explaining Tuple.map. That makes sense. I wonder if one could make a map-like macro that, at compile time, generates a call to the block for each member of the Tuple, and so they’ll be individually typed?
<FromGitter> <christopherzimmerman> @plambert my 2 minute attempt:
<FromGitter> <christopherzimmerman> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5efba5c3e0e5673398e4c97d]
<FromGitter> <Blacksmoke16> would that work if its not hardcoded
<FromGitter> <christopherzimmerman> Which part?
<FromGitter> <Blacksmoke16> oh wait, nvm, the macro defines a method
<FromGitter> <Blacksmoke16> idt you need a macro for that
<FromGitter> <christopherzimmerman> Isn't the alternative hard coding every needed mapped function into it's own function? I don't think you can make a method that takes a generic proc
<FromGitter> <christopherzimmerman> If you can, that would be much cleaner
<FromGitter> <plambert> What is the `if true` for?
<FromGitter> <Blacksmoke16> `{% begin %}` / `{% end %}` is the more idiomatic way
<FromGitter> <christopherzimmerman> I copied most of it from the source for `Tuple.map`
<FromGitter> <asterite> I tried it, I don't think it's possible
<FromGitter> <Blacksmoke16> same
deavmi has quit [Read error: Connection reset by peer]
deavmi has joined #crystal-lang
HumanG33k has joined #crystal-lang
HumanG33k has quit [Remote host closed the connection]
HumanG33k has joined #crystal-lang