<crystal-gh>
[crystal] kenta-s opened pull request #4875: Improve JSON::ParseException message for empty string (master...improve-json-parse-exception-message-for-empty-string) https://git.io/v5kFs
dhk has joined #crystal-lang
dhk has quit [Quit: Leaving]
snsei has quit [Remote host closed the connection]
snsei has joined #crystal-lang
<FromGitter>
<codenoid> hi, i wanna ask something, what is the difference between sidekiq and rabbitmq ?
alibby has joined #crystal-lang
snsei has quit [Remote host closed the connection]
<FromGitter>
<maxfierke> @codenoid RabbitMQ is a high-performant message broker written in Erlang. Sidekiq is library for background processing and uses Redis. You *could* use RabbitMQ as a the queuing backend for background processing , but would need an AMQP client in a listening application to do the processing work. Where I work, we use RabbitMQ for passing messages between systems but then the listening systems might actually
<FromGitter>
... enqueue separate jobs (in Resque, Sidekiq, etc.) to do the actual work. That being said, there are AMQP clients that will do the managing of background workers as well.
<FromGitter>
<codenoid> oo, yup btw erlang is good for that, my case, i want to use messaging system beetwen my crystal app and mongodb
<FromGitter>
<codenoid> my Mongodb Is die when receiving a lot of IO process from crystal
snsei has joined #crystal-lang
snsei has quit [Remote host closed the connection]
snsei has joined #crystal-lang
snsei has quit [Remote host closed the connection]
snsei has joined #crystal-lang
maxpowa has quit [Ping timeout: 248 seconds]
maxpowa has joined #crystal-lang
snsei has quit [Remote host closed the connection]
snsei has joined #crystal-lang
snsei has quit [Remote host closed the connection]
<FromGitter>
<zatherz> you can just detect if ABC has 0 entries, if yes return `{} of Nil => Nil`, otherwise return the value of ABC *but* redact the `of Nil => Nil` part
<Groogy>
I just ended up doing a compile data and runtime data :P
<Groogy>
constants
<FromGitter>
<zatherz> I'd love better macros in crystal
<FromGitter>
<zatherz> like Jai
<FromGitter>
<zatherz> but unless a major compiler rewrite happens I don't think that's gonna happen
<Groogy>
I would love D static language
<Groogy>
D hit it just right in my opinion
<FromGitter>
<zatherz> I dislike the idea that "macros aren't supposed to be used for complicated things"
<FromGitter>
<zatherz> yeah, unfortunately not how attributes work
<FromGitter>
<zatherz> as far as I see it's not an actual property on the target object, at least on parser level
<FromGitter>
<zatherz> it's just a separate Attribute expression
<FromGitter>
<zatherz> yaaaay
<FromGitter>
<zatherz> my macro call change works
<FromGitter>
<zatherz> not sure if it's the right way to do this though
<FromGitter>
<zatherz> @asterite how does normal crystal disambiguate between call and var? is it on parser level? if so, is it possible to disambiguate in macros?
<FromGitter>
<zatherz> the second form might be clearer
<FromGitter>
<zatherz> RX14: I see; `parse_macro`
<RX14>
everything inside {% begin %}/{% end %} or a macro or anything like that is parsed initially as just a block of text
<FromGitter>
<zatherz> btw that `a() = 3` business is definitely not intended right
<RX14>
with some templating stuff too
<RX14>
and then you run the templates
<RX14>
and what you get out at the end is another block of text
<FromGitter>
<Fanna1119> @zatherz ahh that makes sense :D
<RX14>
that is then parsed through the parser and inserted
<FromGitter>
<zatherz> yeah, and it's just pasted
<RX14>
@zatherz no it's not intended
<RX14>
but neither is it particularly harmful
<FromGitter>
<zatherz> it's a nice way to confuse everybody who is going to read your code if you just use it everywhere lol
<RX14>
well
<FromGitter>
<zatherz> it's an easy fix though, I'll just do it
<FromGitter>
<zatherz> Call has a `has_parentheses` flag
snsei has joined #crystal-lang
<FromGitter>
<bararchy> Does someone have a project at Github that uses the Crystal HTTP::Server with or without other frameworks (Kemal, etc..) that wouldn't mind me doing some security reserch upon ?
rohitpaulk has quit [Ping timeout: 248 seconds]
<FromGitter>
<zatherz> oh cool has_parentheses isn't set properly
snsei has quit [Ping timeout: 255 seconds]
<FromGitter>
<zatherz> okay so the root of the issue
<FromGitter>
<zatherz> is that since macro methods are a predefined table
<FromGitter>
<zatherz> @def_vars isn't populated with anything ever
<FromGitter>
<zatherz> nice it even does push_def, just doesn't add anything to it
<FromGitter>
<bararchy> btw, getting `Unhandled exception in spawn` while using a bare HTTP::Server is a bug ? or just how it handles errors ?
<FromGitter>
<bew> well, it's telling "unhandled exception", means something wasn't handled, we can't really say that it handles error..
<FromGitter>
<bararchy> lol yeha, I'll open an issue
<FromGitter>
<zatherz> at least I got to use it once
<RX14>
well there's my long github comment for the day
<FromGitter>
<zatherz> I'm confused, why does parse_expression just call parse_op_assign and then parse_expression_suffix
<FromGitter>
<zatherz> what's so special about op assign
<FromGitter>
<zatherz> RX14: ^
<RX14>
not a clue
<FromGitter>
<bew> @zatherz do you have some knowledge on how to write a parser?
<FromGitter>
<zatherz> @bew why are you so passive agressive
<FromGitter>
<bew> I didn't meant to be any aggressive, I'm just asking, to redirect you to what you need to answer your question
<FromGitter>
<bew> ...
<FromGitter>
<zatherz> I have not ever seen a parser before where "read any kind of expression" effectively just calls "read the assign operator expression", if that answsers your question
<FromGitter>
<zatherz> *answers
rohitpaulk has joined #crystal-lang
<FromGitter>
<bew> sorry, I thought I knew, but when trying to explain it turns out I'm not sure why..
<FromGitter>
<bew> or at least I think I get it, but don't know how to explain by text.. sry for that
<FromGitter>
<mgarciaisaia> Yeah - since we have to cross the ocean for an event like this to happen, and given that cities in Europe are *kinda* close between them, maybe do a bunch of CodeCamps in a couple of different cities instead of a single one
<Groogy>
cool
<Groogy>
what did you do at the last one?
<FromGitter>
<codenoid> v. 1.0 will be published, (?) :O
<FromGitter>
<codenoid> is @totokaro real @faustinoaq account ?
<wmoxam>
Hrmm, so this fancy new QT lib is gonna force me to fix issues with shards on OBSD :p
<wmoxam>
I've been aware of them for a while, just had no incentive to fix them before 😅
<Papierkorb>
lawl
xaxisx_ has joined #crystal-lang
xaxisx has quit [Ping timeout: 248 seconds]
DTZUZO has joined #crystal-lang
rohitpaulk has quit [Ping timeout: 260 seconds]
Philpax__ has quit [Ping timeout: 260 seconds]
Philpax__ has joined #crystal-lang
mark_66 has quit [Remote host closed the connection]
rohitpaulk has joined #crystal-lang
Philpax_ has joined #crystal-lang
Philpax__ has quit [Ping timeout: 248 seconds]
snsei has quit [Remote host closed the connection]
snsei has joined #crystal-lang
snsei has quit [Ping timeout: 240 seconds]
Philpax_ has quit [Ping timeout: 248 seconds]
Philpax_ has joined #crystal-lang
Philpax__ has joined #crystal-lang
Philpax_ has quit [Ping timeout: 248 seconds]
Philpax__ has quit [Ping timeout: 248 seconds]
Philpax__ has joined #crystal-lang
<FromGitter>
<eliasjpr> Hello everyone, an update was posted in Trello (https://trello.com/c/belEWLqo/60-crystal) by Nanobox @danielhunsaker1 to add support for Crystal to their platform. I was wondering if someone can provide them with an answer, I will kindly respond that the community is following up with this. On another note currently, we are tracking this issue on Amber repo, I think that the Amber repo is the wrong place for
<FromGitter>
... this type of issue since is more related to crystal tooling than amber framework itself and maybe should be posted on the https://github.com/crystal-lang-tools/ repo
ragmaanir has joined #crystal-lang
<FromGitter>
<ylluminate> thanks @eliasjpr good news is that Crystal has the most votes for a language to support on Nanobox right now and so that probably is a pretty solid priority for them if someone can help them through the issue.....
<oprypin>
eliasjpr, it's not even possible to figure out this kind of problem at the rate of 1 message per month
<oprypin>
needs a ton of back-and-forth
<oprypin>
RX14 has talked to someone in this chat about this
<FromGitter>
<eliasjpr> I know you guys are busy as we all normally are but I think this is a great push for the community for platforms like nanobox to adopt support for Crystal. Maybe this is enough motivation for @RX14 to jump in and help or someone with solid understanding with whats going on. I would think this is in the best interest of Crystal and Nanobox is a win win for both
rohitpaulk has quit [Remote host closed the connection]
eliasjpr has joined #crystal-lang
eliasjpr has quit [Client Quit]
saadq has quit [Ping timeout: 255 seconds]
saadq has joined #crystal-lang
<FromGitter>
<mverzilli> I see @RX14 has just answered. Other than that, not sure what we can do. To compile Crystal without Crystal you'd need to go back to the last Ruby version and recompile all versions from there, I don't even know if that's still possible :P
<FromGitter>
<mverzilli> It'd be interesting to see if/how they do it with other bootstrapped languages, like Rust
<RX14>
well it looks like they havent done rust
<FromGitter>
<eliasjpr> 🙌
<FromGitter>
<bew> I don't get it, why do they need to install crystal without crystal? No way to cross compile and/or put a binary somewhere?
<FromGitter>
<eliasjpr> At least the ball is on their side of the court :) Thanks guys
<RX14>
I think that they simply didn't know that the omnibus existed and had no way to install crystal
<RX14>
they probably don't want to know how to install crystal without a crystal compiler
<RX14>
they want to be able to install crystal
<Papierkorb>
Is nanobox a managed cloud solution thingy like DO?
<FromGitter>
<bew> Yeah ok, it makes sense
<FromGitter>
<mverzilli> that makes much more sense, let's see what they reply!
<FromGitter>
<ylluminate> Papierkorb it's more like a heroku replacement that uses your own servers' instances (primarily Linode right now). I've been surprised by it so far and used it to replace a couple of smaller heroku deployments.
<RX14>
would be even easier if my compiler PRs were merged and we had a statically compiled omnibus
<RX14>
well i don't think any of my PRs are waiting on me @mverzilli
<RX14>
oh actually probably the debug info specs PR
Philpax__ has quit [Ping timeout: 240 seconds]
Philpax__ has joined #crystal-lang
xaxisx has joined #crystal-lang
ragmaanir has quit [Quit: Leaving]
xaxisx_ has quit [Ping timeout: 252 seconds]
Philpax__ has quit [Ping timeout: 240 seconds]
Philpax__ has joined #crystal-lang
<FromGitter>
<mverzilli> I mean, #4874 and #4872 already are approved by @ysbaddaden so they're good to go
<FromGitter>
<mverzilli> "would be even easier if my compiler PRs were merged and we had a statically compiled omnibus" <- from that I interpreted you were waiting on some approvals before merging, so I asked what PRs you were waiting for feedback on, to prioritise them :)
<RX14>
@mverzilli oh I guess they are approved lol
<RX14>
@mverzilli would be nice if we got that IO pr merged though
<RX14>
seems we've decided that it's the right direction to go in
<crystal-gh>
crystal/master d3537fc Chris Hobbs: Add configurable default target (#4874)...
txdv has quit [Ping timeout: 260 seconds]
txdv has joined #crystal-lang
<FromGitter>
<mgarciaisaia> Hey, @RX14, how do you see the `--static` thing in the omnibus picture? I felt you were talking about *replacing* the omnibus with that flag, but may it be that omnibus should build Crystal using that flag so it gets a distro-independent compiler?
<FromGitter>
<mgarciaisaia> I'm currently building a compiler with `--static` support to *then* build a statically linked compiler
<FromGitter>
<mgarciaisaia> All of that inside omnibus
<RX14>
well if I can replace the entire bloated omnibus repo with a Dockerfile and a shell script then why not do that
<FromGitter>
<zatherz> I think I'm misunderstanding how `@def_vars` in the parser works
<RX14>
it's infinitely easier to understand how the build process works
<RX14>
than with an overly-abstracted build tool
<FromGitter>
<zatherz> I tried pushing all the method names (push, pp, etc) in parse_macro
<FromGitter>
<zatherz> right after the push_def
<FromGitter>
<zatherz> and I see it resolves `var?("puts")` properly once but then doesn't 4 times and errors with unknown macro variable puts
<FromGitter>
<zatherz> actually that's not correct, it doesn't resolve it once and resolves it 4 times
<FromGitter>
<zatherz> but still errors
<FromGitter>
<zatherz> I assume it's something to do with depth
<RX14>
@mgarciaisaia you could use --static with omnibus-crystal, maybe? but I'd rather take the opportunity to replace the build process with a more portable (docker) and more understandable (linear execution) solution
<RX14>
did you see my repo?
<FromGitter>
<mgarciaisaia> Just seen it
<FromGitter>
<zatherz> oh god I'm so stupid
<FromGitter>
<zatherz> first off I misunderstood what `@def_vars` is, and second off I didn't notice this
<FromGitter>
<mgarciaisaia> That Dockerfile is building a compiler that would run only on any linux that shares arch with that alpine image, right?
<FromGitter>
<mgarciaisaia> Packaging for each distro would be out of scope, right?
<FromGitter>
<mgarciaisaia> Or is something that would eventually be added there?
<FromGitter>
<zatherz> error in object prelude, nice lol
<RX14>
@mgarciaisaia no it works for any x86_64 linux kernel
<RX14>
and it always produces binaries for x86_64-linux-gnu
<FromGitter>
<mgarciaisaia> But we don't have to build Debian *and* Centos anymore
<RX14>
hmm?
<FromGitter>
<mgarciaisaia> don't/won't
<RX14>
oh you mean creating actual distro packages
<RX14>
sorry i misread
<RX14>
I think that's in scope
<RX14>
I just need to find portable tools which can create deb/rpm packages
<FromGitter>
<mgarciaisaia> Yeah
<RX14>
then unzip to /opt/crystal/ and symlink /opt/crystal/bin/crystal from /usr/bin/crystal
<RX14>
it was second on my todo list
<RX14>
right after adding shards to the omnibus
<FromGitter>
<mgarciaisaia> Omnibus already builds shards - doesn't it?
<RX14>
yes it does
<RX14>
i meant my replacement omnibus
<FromGitter>
<zatherz> :O it works
<FromGitter>
<zatherz> with empty prelude right now
<FromGitter>
<zatherz> but `{% puts %}` parses correctly
<RX14>
what on earth are you trying to do zatherz
<FromGitter>
<zatherz> doing prep work for further macro work
<FromGitter>
<zatherz> I want to make methods in macros parse like outside of macros
<FromGitter>
<zatherz> `{% puts %}` right now errors out saying that the variable puts doesn't exist
DTZUZO has quit [Ping timeout: 252 seconds]
<FromGitter>
<zatherz> that's because `var?` returns true no matter what inside macros
<FromGitter>
<zatherz> I changed that
<RX14>
but why
<FromGitter>
<zatherz> so that if anybody wants to implement defs-inside-macros they don't have to fix that first
<FromGitter>
<zatherz> also consistency
<FromGitter>
<zatherz> `puts` works but `{% puts %}` errors while `puts()` works and `{% puts() %}` works
<FromGitter>
<zatherz> also, works with normal prelude now 👌
<RX14>
i'll never accept defs inside macros
<RX14>
if you need it your macro is too large
<RX14>
and you should do it without so much macro hell
<FromGitter>
<zatherz> you do realize the reason macro hell exists is *because* stuff like that is impossible
<RX14>
no it's because people like you abuse macros
<FromGitter>
<zatherz> why would you want to handicap the language because you made up some sort of blurry line of where "your macro is too large"
<FromGitter>
<zatherz> macros are too large because you need 50 levels of indirection to avoid copy pasting
<FromGitter>
<zatherz> this is like the argument against generics in Go
<RX14>
it's not about too large
<RX14>
it's about too complex
<RX14>
and your macros are very much too complex
<FromGitter>
<zatherz> what is too complex? if something is a bottleneck at runtime and can be done at compile time, why shouldn't it be done at compile time?
<FromGitter>
<zatherz> yeah they're complex because they need to have a lot of indirection
Philpax__ has quit [Ping timeout: 248 seconds]
<RX14>
no they're complex because you're trying to do too much with them
<FromGitter>
<zatherz> what https://gitlab.com/zatherz/magicjson isn't actually complex, it's basically `field` macros to add entries to `MAGICJSON_FIELDS` and generation of `def initialize(parser : PullParser)`
<RX14>
to accomplish the wrong thing
<FromGitter>
<zatherz> what is the right thing
<RX14>
using JSON.mapping properly
<FromGitter>
<zatherz> using bad solutions that require me to copy paste code everywhere
<FromGitter>
<zatherz> i.e. json.mapping
<RX14>
no, using the right solutions which force you to write good, readable, understandable, and yes, a bit longer, code
<FromGitter>
<zatherz> the same thing being copied 3 times with small changes is not readable and understandable
<FromGitter>
<zatherz> "JSON.mapping not supporting inheritance or composition is a feature"
<RX14>
no
<RX14>
isn't that already solved with constants?
<FromGitter>
<zatherz> might as well delete generics then because lack of generics forces you to write good, readable, understandable and longer code
<FromGitter>
<zatherz> what
<RX14>
just place your mapping body in a constant in the superclass
<FromGitter>
<zatherz> and reimplement inheritance yourself
<RX14>
use 1 macro to merge the two named tuples and splat
<FromGitter>
<zatherz> with a lot of boilerplate
<RX14>
for a very uncommon use case it's a perfectly acceptable solution
<RX14>
one which DOESN'T require you to NIH and create your own pos
<RX14>
"a lot of boilerplate" it's nothing
Philpax__ has joined #crystal-lang
<FromGitter>
<zatherz> is it an uncommon use if you have 77 classes
<FromGitter>
<zatherz> using it
<RX14>
it's uncommon for you to misuse json like that, yes
<FromGitter>
<zatherz> Are you joking? It's uncommon to write an API client for an API that uses JSON?
<FromGitter>
<zatherz> and "misuse"?
<RX14>
if even 5% of APIs did inheritance in JSON then we'd get a lot more issues regarding this problem
<RX14>
the fact that we don't means your API is an outlier
<Papierkorb>
`JSON.mapping({ *FOO, another: String })` doesn't sound too bad
<FromGitter>
<zatherz> Okay, so to stop people writing complicated macros
<RX14>
Papierkorb, exactly my point
<FromGitter>
<zatherz> You are going to make people write 5x more complicated macros
<RX14>
no
<RX14>
how is literally what Papierkorb said more complex than... whatever on earlth you created
<FromGitter>
<zatherz> okay, now how do I use JSON.mapping to include a `client` in my payloads
<RX14>
exactly how i told you on discord
<FromGitter>
<zatherz> which comes from crystal, not from the JSON payload
<RX14>
which you ignored me
<FromGitter>
<zatherz> Yeah, by working around hte type system
<RX14>
ok
<RX14>
if you want to be a purist use haskell
<RX14>
here in crystal land we get shit done
<FromGitter>
<zatherz> Not amazing macro support -> incomplete solutions -> need for a more complete solution -> complex macro -> not amazing macro support because too complex macro
<FromGitter>
<zatherz> a never ending circlejerk of "but this feature can be abused"
<RX14>
we literally just gave you the solution
<RX14>
with no macros involved
<RX14>
at all
<RX14>
and yet you contrinue to make this about macros
<FromGitter>
<zatherz> Yes, and you completely forgo type safety, a core feature of the language
<Papierkorb>
How does it forgo type safety?
<FromGitter>
<zatherz> again, because a macro to do it would be too complicated
<RX14>
no, we don't completely forgo it
<RX14>
we add 1 nillable variable
<RX14>
with a getter which raises
<FromGitter>
<zatherz> You either have guaranteed type safety or you do not have guaranteed type safety
<FromGitter>
<zatherz> Papierkorb: referring to "okay, now how do I use JSON.mapping to include a `client` in my payloads"
<FromGitter>
<zatherz> the "suggestion on discord" was to make a nilable Client and assign it after initializing
<RX14>
and the solution i have proposed to zatherz time and time again is the same asterite proposed on that issue
<RX14>
use a raise-on-nil property
<RX14>
and assign client late
<RX14>
i even told you how to do it recursively
<Papierkorb>
Sounds more like an architectural issue.
<RX14>
well it's one that's hard to avoid Papierkorb
<Papierkorb>
If you want immutable objects, then build them in a way which allows them to..?
<FromGitter>
<zatherz> Yeah I'm just gonna go ahead send this email to Discord so that they can change their API for me
<RX14>
the discord API isn't the issue
<RX14>
the issue is getting a reference to the discord client into the discord API objects deserialized from json
<Papierkorb>
Though imho, a data transfer class (`X.mapping`) requiring additional outside dependencies is a design defect
<Papierkorb>
Not in Crystal at that
hightower2 has joined #crystal-lang
<FromGitter>
<zatherz> did asterite propose that solution because he has some weird idea of particular features which increase complexity being good but other features which increase complexity being bad, or did he propose that solution because there are no other good solutions currently available
<RX14>
Papierkorb, the ideal would be to compose classes
<Papierkorb>
We got a winner!
<RX14>
which i proposed before
<RX14>
but the objects are recursive
<RX14>
sorry
<RX14>
nested
<RX14>
which makes it a pain in the ass
<Papierkorb>
Doing the right thing usually comes at a price
<hightower2>
Hey, which issue are we talking about? (A link to it or?)
<RX14>
gitther has gained my daily prize for the worst designed IM app before skype on linux
<FromGitter>
<zatherz> assuming it was supposed to be `do`, he only mentions that it's better to keep the *JSON module* simple, and he even says that the nilable hack is ugly
<Papierkorb>
RX14: The old or new "skype on lin" application?
<Papierkorb>
new being this crappy web app abomination
<RX14>
idk
<RX14>
i ditched it
<Papierkorb>
old is/was based on Qt. Still works fine!
<RX14>
last i knew it was native at least
<RX14>
@zatherz sometimes you have to accept ugly hacks.
<RX14>
and that single ugly hack is CERTAINLY less ugly than your macros
<FromGitter>
<zatherz> What kind of defeatist attitude is that
<RX14>
realism
<FromGitter>
<zatherz> Yeah it's less ugly than magicjson
<Papierkorb>
A hack comes with the next hack. They're ugly by definition. Doing it "the right way" without hacks increases complexity at the price of improved maintainability
<Papierkorb>
Or in other words: Composition. Like RX14 said.
<RX14>
it's hardly even an ugly hack
<FromGitter>
<zatherz> It is quite literally an ugly hack that works around a core part of the language
<RX14>
because it really doesn't have any wider consequences
<RX14>
it's a single veriable with a raise-on-nil getter
<FromGitter>
<zatherz> it does, you can't verify that your program is type safe at compile time
<RX14>
there's almost no scope for it getting uglier
<RX14>
yeah well zatherz
<RX14>
that ship has already left the port multiple places in the stdlib
<RX14>
where we have raise-on-nil getters
<Papierkorb>
zatherz, the issue is *your* architectural design, which in turn requires you to resort to this 'hack'.
<FromGitter>
<zatherz> TIL that I'm working on the Discord API
<RX14>
no
<RX14>
thats not what Papierkorb is saying
<RX14>
the discord API is fine
<Papierkorb>
Not at all indeed
<FromGitter>
<zatherz> No it's not fine
<RX14>
well
<RX14>
no it's not
<FromGitter>
<zatherz> GUILD_CREATE sends channels with no IDs whereas everything else sends channels with IDs
<FromGitter>
<zatherz> is that fine
<FromGitter>
<zatherz> *guild IDs
<RX14>
but it's issues are unrelated to this issue
<RX14>
is what i'm trying to say
<RX14>
it's a better API than a lot of APIs i've seen
<FromGitter>
<zatherz> They are very related, if a CHANNEL_CREATE would send a full Guild payload instead of just an ID I wouldn't need to have a client in the payload that resolves this ID
<RX14>
no
<RX14>
you'd want smart objects regardless
<RX14>
that's just one more reason to keep a client accessible
<RX14>
there are plenty others
<RX14>
you want to either do it the pure way and compose the object
<RX14>
or do it the easy way - with little downsides - and use a raise on nil getter
<RX14>
i really do not see why you're making such a fuss over 1 raise call
<RX14>
because they really are common
<RX14>
this isn't about type safety
<RX14>
what you're trying to provide is guarantees that errors will never happen
<RX14>
which is impossible
<FromGitter>
<zatherz> back to the core issue - D can execute a lot at compile time, Jai is going to be able to execute entire programs at compiletime, why can't Crystal have above average macro support?
<FromGitter>
<zatherz> is it because it can be abused?
<RX14>
im my view, yes
<FromGitter>
<zatherz> Can generics be abused?
<RX14>
in other's view, because it's easy to implement
<RX14>
generics can be abused but they are abused much less often
<Papierkorb>
... Which issue are we talking about now exactly?
<FromGitter>
<zatherz> how often are macros abused
<Papierkorb>
Macros sucking? Composition being hard? Discords API being drunk?
<RX14>
zatherz thinks macros suck because he tried to overcomplicate his macros
<FromGitter>
<zatherz> rx14 how often are macros abused compared to the abuse of generics?
<RX14>
which we just proved are not required anyway
<FromGitter>
<zatherz> how often are exceptions abused?
<RX14>
i don't know i don't keep count
<FromGitter>
<johnjansen> you guys know this is going to be a theme in the future … macros will be loved and hated … reminds me of some ruby features in a way
<FromGitter>
<zatherz> then why are you making claims that macros are abused much more often than other things?
<Papierkorb>
As a firm believer in abusing all language features to their extend - and hence, Macros fall in there - I can say: Macros are not underpowered. Some niceties are missing, ok, nothing's perfect right? But they're pretty darn capable. What exactly is missing?
<FromGitter>
<zatherz> Macros are very capable
<FromGitter>
<johnjansen> i dont mean macros, i mean … there is always 1 feature that polarizes
<Papierkorb>
johnjansen, Yes absolutely. Which is why we have to teach people how to use them. Fear only comes only from ignorance.
<RX14>
and I think zatherz is using macros incorrectly
<FromGitter>
<johnjansen> totally … but stand by for the haters in the future ;-)
<Papierkorb>
johnjansen, Makes it easy to weed out "those", at least with higher accuracy than just reading chat logs heh ;P
<RX14>
Papierkorb, i don't believe in abusing stuff i'd rather write clean code
<FromGitter>
<zatherz> Papierkorb: The problem is that you can only choose either "readable" or "fast" with macros in Crystal
<RX14>
abusing macros for fun is fine
<RX14>
but using that in a real project that other people have to use?
<Papierkorb>
Abuse to allow clean code where appropriate
<RX14>
i wouldn't wish that on anyone
<FromGitter>
<johnjansen> i wouldnt like to comment on that, but others will certainly misuse them and hate on them … we as a community need to figure out ways of dealing with that ahead of time so we dont wind up with a `ruby is so slow` kind of hate toward macros
<FromGitter>
<zatherz> You can go the readable way and just `run` everything
<RX14>
yeah but it's really hard to have a mental model of when too far is too far
<RX14>
because *you* always understand it
<FromGitter>
<zatherz> then use `compiler/crystal/syntax/ast` in the scripts you `run`
<FromGitter>
<zatherz> but that absolutely kills the compile time
<FromGitter>
<zatherz> you can go the fast way using normal macros
<RX14>
macros are never fast
<FromGitter>
<zatherz> but then you get into complications, i.e. let's say you have 3 places
<Papierkorb>
The mapping macros are a prime example of this. A known pattern. Replicating this will not cause much confusion.
<FromGitter>
<zatherz> where you need to convert an identifier
<FromGitter>
<zatherz> into an ivar-compatible name
<FromGitter>
<zatherz> just basic stripping of `?` and `!` from the end for example
<FromGitter>
<johnjansen> i would suggest that macros provide the ability to DRY code (first and foremost) … you *can* do alot of magic with them but given the compile time requirement, most boil down to some form of DRY
<RX14>
the mapping macros are a fairly thin and readable layer on top of pullparser
<FromGitter>
<zatherz> `id.gsub(/(\?|!)$/, "")` should be enough to do that
<RX14>
asterite got this absolutely correct
<RX14>
you write the code 10 times by hand
<RX14>
create any abstractions you can without using macros
<Papierkorb>
RX14: I consider them to be in the "somewhat complex" group. They're fine.
<FromGitter>
<zatherz> but you need this in 3 places, so you put on your "I love Go" hat and you copy paste it to those 3 places
<RX14>
and then if there's still some boilerplate you can't abstract
<RX14>
thats when you use macros
<FromGitter>
<zatherz> now you realize that `a?=`is also a valid identifier
<FromGitter>
<johnjansen> +1 @RX14 … DRY
<FromGitter>
<zatherz> so you need to make sure you hit every single usage of that `gsub` line and update it to hit the other cases
<FromGitter>
<zatherz> you think to yourself that maybe you could abstract this into a method that you can call from the macros
<RX14>
well you can always expand into other macros lol
<RX14>
it's not like there's no extensibility at all
<RX14>
it's just slow and terrible
<FromGitter>
<zatherz> but you can't, so you follow RX14's advice and use macros that output macros
<FromGitter>
<zatherz> now you have a billion lines of `{% begin %}`, tons of indirection and the actual macro code has fifteen backslashes before it, and in a week you won't be able to read it anymore
<RX14>
zatherz my point is that you should feel terrible because you're doing something terrible
<RX14>
in that respect macros are exactly working as intended
<FromGitter>
<zatherz> my point is that you should feel terrible because you are using Go users' Stockholm Syndrome-powered argument against generics
<FromGitter>
<zatherz> as an argument against macros
<RX14>
well
<RX14>
we have macros
<RX14>
go doesn't have generics
<FromGitter>
<johnjansen> @zatherz is there some reason you repeat the gsub in so many places, when it should happen in 1 place (with tests) and be called in the normal way … what am i missing … wouldnt you want to remove the duplication of logic?
<FromGitter>
<zatherz> Go actually has generics in the standard library
<RX14>
i'm not telling you to go copy-paste stuff
<FromGitter>
<zatherz> @johnjansen macros
<RX14>
you're abusing the edges of the language and you're getting abuse back
<FromGitter>
<zatherz> entire discussion started because I mentioned I might try to implement defining methods inside macros in the future
<RX14>
and i said i'd attempt to veto it
<FromGitter>
<zatherz> RX14: "I'm not telling you to go copy-paste stuff, I'm telling you to go copy-paste stuff"
<RX14>
where did i tell you to copy paste stuff
<RX14>
I don't hate macros
<RX14>
i hate macros which are ugly and too complex and too long
<FromGitter>
<zatherz> Don't you think that a way to reuse macro code without indirection would remove ugliness, complexity and make macros shorter?
<RX14>
perhaps it would
<RX14>
but my point is that you shouldn't be writing macros that need it anyway
<RX14>
so at best it's unnecesary
<RX14>
atworst it's encourging people to think using macros as a firsts olution
<RX14>
macros are always undesirable
<FromGitter>
<zatherz> how is it encouraging people to think using macros as a first solution
<RX14>
they're always used because you can't do it without macros
<RX14>
@zatherz because if they have all these shiny features and attention they become idolised as "cool" instead of an ugly wart that in an ideal world simply wouldn't be there
<RX14>
but this isn't an ideal world
<RX14>
and some things are better done with macros
<RX14>
but i'm just trying teo tell you I don't think what you're doing is something better done with macros at all
<FromGitter>
<mgarciaisaia> I've really enjoyed Ary's take on macros during this talk - https://vimeo.com/190927958
<FromGitter>
<johnjansen> for what its worth, ive written alot of production crystal code and havent needed macros more that a handful of times, and i dont have alot of repetition anywhere … macros are great, but you shouldnt use them unless you get a tangible benefit and your code is still simple to maintain
<FromGitter>
<zatherz> The problem with that attitude is that it's pretty much just "Macros can be too complex, therefore there shouldn't be methods to make macros less complex"
<FromGitter>
<johnjansen> my attitude?
<FromGitter>
<johnjansen> or @asterite’s ?
<FromGitter>
<zatherz> I mean RX14's stance
<FromGitter>
<zatherz> sorry
<RX14>
no because with my stance i'd never build a macro that complex in the first place
<FromGitter>
<zatherz> The macro is complex, because there is no way to make it less complex.
<FromGitter>
<zatherz> There is no way to make the macro less complex, because the macro is complex.
<RX14>
no
<RX14>
we just told you EXACTLY how to make this macro infinitely less complex
<RX14>
by entirely not using macros at all
<RX14>
and yet you're still making this about macros
<FromGitter>
<johnjansen> actually @RX14 i will correct you ;-) you would first write your code without macros, and only when / if it became necessary you would look into the benefits and costs of moving to / using macros, and assuming that all pointed toward macros as the correct approach, then you would go that way ;-)
<FromGitter>
<johnjansen> hehe
<RX14>
that's what asterite said in that talk, basically
<FromGitter>
<johnjansen> exactly
<Papierkorb>
johnjansen, thanks for the TL;DW. I agree too.
<RX14>
i am guilty of skipping most of the write it without macros step myself...
<RX14>
but for small self-contained problems you can usually reason it out in your head
<FromGitter>
<johnjansen> agreed
<RX14>
and if it's 5 lines of macro with little scope for complexity growth then you can just write it right away
<RX14>
although you do have to be aware of exactly how powerful blocks and methods in crystal can be before you start doing that
<RX14>
because you can abstract away some awfully complex stuff with 0 overhead using blocks
<FromGitter>
<johnjansen> totally
<FromGitter>
<zatherz> Can't know how much better/worse it is unless I try, so I'm gonna try to rewrite DCR with JSON.mapping and nilable client fields
<FromGitter>
<zatherz> I actually did try this once, but I ended up scrapping it before I got to any usable result
<FromGitter>
<johnjansen> OOI what is DCR?
<RX14>
zatherz' NIH fork of a discord library
<RX14>
it should have been a composition
<RX14>
not a fork
<FromGitter>
<zatherz> a discord.cr fork I made to make discord.cr more user friendly
<RX14>
it should have wrapped discordcr
<RX14>
and depended on it
<FromGitter>
<zatherz> it might
<FromGitter>
<johnjansen> interesting … ok, yep, unless you intend sending it back to the original repo as a PR
<FromGitter>
<zatherz> it used magicjson, my own JSON.mapping replacement
<FromGitter>
<zatherz> so wouldn't be accepted anyway
<FromGitter>
<fridgerator> "hey look this language has macros".... "dont use macros in this language"
<FromGitter>
<picatz> 😂
<FromGitter>
<picatz> @fridgerator to be fair, I think it was more like "don't over-use macros in this language"
<FromGitter>
<fridgerator> alright alright
<FromGitter>
<picatz> Or, maybe "abuse" instead of "over-use"
<FromGitter>
<elorest> Yeah that was my take.
<FromGitter>
<picatz> I think macros themselves are already pretty powerful ( and confusing if you didn't write the macro ).
<FromGitter>
<picatz> I'm personally in the camp of not over-using/abusing macros; and most of the code I've used them for has been for purely syntax sugar-look'n stuff because I like it when my code is pretty.