<FromGitter>
<anamba> @RX14 @j8r was thinking more about how we could sandbox dependencies. it would be nice if you could get some kind of guarantee that things you require are not going to do wildly unexpected things, like redefine Object.to_json to POST data to a remote server. i was thinking something along the lines of arguments to `require` that restrict reopening of classes. many shards would not need to reopen anything, those
<FromGitter>
... that need it could instruct users to provide a list of classes to reopen `require "myshard", allow_reopen: [Class1, Class2]` this might be a good first step. and the other benefit is that it would introduce scoping that could prevent accidents, in case two developers use the same module+class name for something. lastly, a ... [https://gitter.im/crystal-lang/crystal?at=5c0715fc630ddb19d4358747]
<RX14>
even if you do that, any dependency can use pointers
<RX14>
crystal isn't designed to be secure, so it never will be
<RX14>
JS was
<FromGitter>
<anamba> @RX14 oh right. pointers. well, there could be an arg on `require` to disable pointers and C integration as well and stick to "pure crystal" only. i'm assuming the vast majority of shards would be ok in that mode.
<RX14>
i'm sure I could find a million different ways to exploit a crystal program :)
<FromGitter>
<anamba> i think this issue can only become more important over time. it's not getting any easier to trust people on the internet
<FromGitter>
<anamba> see that's not very reassuring :)
<RX14>
its never really been an issue before now with other programming languages
<RX14>
and 3/3 times its been npm
<RX14>
popularity means contributors means code review means trust
<FromGitter>
<anamba> naturally the probability of something surfacing in npm is way higher because each js project includes like 10,000 npm packages :)
<RX14>
npm has too many tiny packages to have the tiny ones be popular
<RX14>
the problem is the 2000+ packages you install
<RX14>
in crystal it'd be like 50 at most for a very very large project
<FromGitter>
<anamba> anyhow, more security is better than less, even if it isn't perfect. even if adding args to `require` doesn't stop anyone, it raises the bar. if that's in place, now if you want to attack me through my dependencies, you at least need to be motivated enough to write something really tricky.
<FromGitter>
<anamba> (i edited anyone -> everyone, not sure what the IRC bot does with edits)
<FromGitter>
<DRVTiny> @anamba we realy want secure language with 254+2 == 0 ? :)
<FromGitter>
<anamba> that's already being fixed though
<FromGitter>
<DRVTiny> "&+" operator/mehod is not right solution for the problem of integer overflows. I think, it's better to get exception when using generic "+" method.
<FromGitter>
<anamba> is that how it was going to be? i thought it was going to be the other way, but changed over two releases.
lucasb has quit [Quit: Connection closed for inactivity]
<FromGitter>
<girng> @j8r still not update from github. guess they like to let spammers roam free
rohitpaulk has joined #crystal-lang
jemc has joined #crystal-lang
rohitpaulk has quit [Quit: Ping timeout (120 seconds)]
rohitpaulk has joined #crystal-lang
Renich has quit [Read error: Connection reset by peer]
Renich has joined #crystal-lang
Renich has quit [Quit: Renich]
Renich has joined #crystal-lang
_whitelogger has joined #crystal-lang
Renich_ has joined #crystal-lang
Renich has quit [Ping timeout: 250 seconds]
Renich_ is now known as Renich
<FromGitter>
<anamba> dang, those top 100 AoC people are really fast
<FromGitter>
<DanilaFe> It's quite insane
<FromGitter>
<DanilaFe> At least we have our Crystal leaderboard with friendly competition
Renich_ has joined #crystal-lang
Renich has quit [Ping timeout: 250 seconds]
Renich_ is now known as Renich
Renich has quit [Quit: Renich]
jemc has quit [Ping timeout: 246 seconds]
<FromGitter>
<girng> JSON.mapping <3 <3 <3
rohitpaulk has quit [Remote host closed the connection]
<FromGitter>
<anamba> this turned out to be an incredibly tiny shard. 😂 the actual code is just a handful of lines, maybe just copy and paste into your app. https://github.com/anamba/pwned_password.cr
<FromGitter>
<girng> that's pretty cool
<FromGitter>
<girng> i dont 'know if i'll put in my password though. iuno what they gonna do with my data LOL
<FromGitter>
<girng> i'll def try it with my short 4-6 letter passwords, but not my main
<FromGitter>
<anamba> it doesn't send your password :)
<FromGitter>
<anamba> the password is hashed locally, then only the first 5 characters of the hash are sent. it's a neat system.
<FromGitter>
<anamba> also ideally you shouldn't have a "main" password (just the one that unlocks your password manager)
<FromGitter>
<girng> how does it know your pass if it only sends the first 5 characters of a hash?
<FromGitter>
<girng> wouldn't it need the full hash to repressent the full password?
<FromGitter>
<girng> btw, not criticizing just curious how it works lol
<FromGitter>
<anamba> the basic idea though is you send the prefix and get back the list of all hashes starting with that prefix. then you just see if yours is in the list.
<FromGitter>
<girng> interesting i see
<FromGitter>
<girng> thanks for the links!
<livcd>
anamba: nice
<livcd>
anamba: Are you a korean american ?
<FromGitter>
<anamba> @livcd oddly enough i am a japanese american living in korea. been here almost 8.5 years now.
<livcd>
doh!
<livcd>
why did you move to KR ?
<FromGitter>
<anamba> @livcd change of scenery at first. since i can work from anywhere i figured why not. it was just supposed to be 1 year... which turned into 2... which turned into staying indefinitely. seoul is a really amazing city it turns out
<livcd>
I have a KR wife and we are looking to return to KR one day but I dont want to work for KR companies sso I am exloring my options
<FromGitter>
<girng> hows the cost of living compared to korea and japan?
<livcd>
I found it pretty cheap compared to Europe
<livcd>
but...I did not need to worry about apt
<livcd>
also I was not living in Seoul but down in the south
<FromGitter>
<anamba> @livcd yeah i'm guessing i wouldn't like living here as much if i was working for a korean company. but then, all i know about that is what i see in korean office dramas :-)
<livcd>
But you had a gig before moving to KR right ?
<livcd>
so was not much of a change for you
<FromGitter>
<anamba> yeah, just doing the same work in a different place.
<FromGitter>
<girng> korean is amazeballs. lead developers of the game Soul Worker are there (Lion Games). And games like black desert, risk your life/returnof warrior, black desert and continent of the ninth all have lead developers that started or are still in korea.
<livcd>
korea is a weird country :)
<FromGitter>
<anamba> i would guess that the vast majority of software devs here are game devs. and most of the rest work for samsung and lg.
<livcd>
not at all!
<FromGitter>
<girng> developers of some of the world's most fluid action rpg games originate from korea
<livcd>
i mean sure there's a lot of people working for chaebols
<FromGitter>
<bararchy> Did someone else noticed how huge rust bins are?
<FromGitter>
<girng> the ones that are filled with garbage behind my house ?
<FromGitter>
<girng> needs some boehm's gc
<FromGitter>
<bararchy> XD
<livcd>
anamba: do you rent or already own an apt there ?
<FromGitter>
<anamba> just rent. i like it here, but i'd still rather not be tied down.
<livcd>
right!
<livcd>
What kind of residency do you have over there ?
<FromGitter>
<anamba> i feel like this all has very little to do w/crystal :) and i gotta sign off here in a bit anyway.
<livcd>
sure sorry :)
<livcd>
I rarely get to talk to expats in KR that's why i am so interested
<FromGitter>
<girng> let me bring back the chat to crystal lang discussion, ready??
<FromGitter>
<girng> I. Love. JSON.mapping. There. we are back in action folks
<FromGitter>
<bararchy> Channel.recv
<FromGitter>
<bararchy> ;)
<FromGitter>
<girng> hahaha
<FromGitter>
<bararchy> yeha, JSON::Mapping makes my morning great also
<FromGitter>
<girng> rofl
<FromGitter>
<bararchy> XD
<FromGitter>
<bararchy> btw, JSON::Serializable is less up my ally, like, it has it's uses, but for a big JSON digest interface mapping makes more sense
<FromGitter>
<girng> i still use opyrin's macro_everything he helped me with
<FromGitter>
<girng> hopefully i can still use it forever :D
<FromGitter>
<girng> simple, but powerful af macro lol
<FromGitter>
<girng> it basically dupes code
<FromGitter>
<bararchy> LOL hahahaha
<FromGitter>
<girng> 😆
rohitpaulk has joined #crystal-lang
<FromGitter>
<vladfaust> I have a helpful tool idea - to print all possible errors a particular line of code could raise - with deep analysis
<FromGitter>
<vladfaust> As we are having a compiled language, this would allow to create unbreakable apps
<FromGitter>
<bararchy> @vladfaust sounds interesting, I would talk with @veelenga to see if he has something like that planned for ameba
<FromGitter>
<vladfaust> He's been pinged, waiting for a response here
<FromGitter>
<vladfaust> Some kind of `SafeCode` rule, which requires a LoC to be wrapped with rescuers, IDK
<FromGitter>
<vladfaust> Or an method annotation like `@[EnsureNoExceptions]` which raises in compilation-time if there is a possibility of raise. But I'm not sure if methods support annotations
<FromGitter>
<KevinSjoberg> I just solved day five of Advent of Code. Comparing my solution to my co-worker who uses Swift, his is much faster. Our solutions are pretty much identical. SPOILER: Link following this contains solution to day 5.
<FromGitter>
<KevinSjoberg> Anything I can do to improve it?
ashirase has quit [Ping timeout: 250 seconds]
<FromGitter>
<vladfaust> What's the Swift result?
rohitpaulk has quit [Ping timeout: 245 seconds]
ashirase has joined #crystal-lang
<FromGitter>
<KevinSjoberg> @vladfaust My code seem to average out on 6 seconds using a release build, his average out on a second using a release build in Swift.
<FromGitter>
<vladfaust> Also it would be more efficient to store the ords until the whole string is handled, and only build the string in the end
<FromGitter>
<vladfaust> And as you know the string size, you should create an Array with that size in the beginning to avoid further memory allocations
<FromGitter>
<KevinSjoberg> I totally agree, my code was not yet optimised for performance. The same goes for the Swift code. I just find it funny that Swift is 4x faster than Crystal with a very similar implementation.
<FromGitter>
<vladfaust> I cannot read Swift code, thus cannot agree with the similarity
<FromGitter>
<vladfaust> Would you mind applying my proposals?
<FromGitter>
<vladfaust> I'm interested in the performance gain
<FromGitter>
<KevinSjoberg> @vladfaust I applied the ord change without any improvements.
<FromGitter>
<vladfaust> @veelenga, sorry, I'm not good into difference between static and semantic analysis. But I could guess that semantic "digs" into the code, right?
<FromGitter>
<vladfaust> @KevinSjoberg that's impossible, because .lowercase and .uppercase are big-ass wrappers around ords
<FromGitter>
<vladfaust> Maybe a tiny, but an improvement should occur
<FromGitter>
<vladfaust> Try applying array of ords instead of substituting a string in every iteration -- this would give a lot of speed, I'm sure
<FromGitter>
<veelenga> @vladfaust I have't done the semantic analysis before, so i can be wrong here. In my understanding, semantics performs type inference, so it can allow us to figure out the types and probably it is possible to have some information about runtime values. But maybe @asterite can give much better explanation...
<FromGitter>
<alehander42> @vladfaust "I have a helpful tool idea - to print all possible exceptions a particular line of code could raise - with deep analysis" ⏎ ⏎ this requires some kind of effect system
<FromGitter>
<alehander42> basically, you want to be able to find all possible exceptions for each method according to some rules (e.g. walking through the AST children and collecting possible exceptions of calls/[]/a.b etc , but ignoring dead code or handled exceptions)
<FromGitter>
<alehander42> my point is, usually compilers either include this info in types
<FromGitter>
<alehander42> e.g. error codes / result sum types / monads(?? i think) etc
rohitpaulk has joined #crystal-lang
<FromGitter>
<alehander42> or they have an additional "effects" system: ⏎ e.g. Java's checked exceptions, Nim's effects and probably many more
<FromGitter>
<alehander42> so I guess this would require a nontrivial change to the crystal compiler, if it doesn't exist currently
lucasb has joined #crystal-lang
<FromGitter>
<vladfaust> I didn't know other languages have this functionality
<FromGitter>
<alehander42> well, basically this is about the more general topic of error handling: it seems as a quite a popular discussion in the last several years
<FromGitter>
<alehander42> basically that's maybe the biggest argument of the Result sum type(Ok/Error) / Error code(ala Go) crowd
<FromGitter>
<alehander42> its obvious in your code what and where can fail(and with Result types, probably also `how`)
<FromGitter>
<alehander42> on the other hand, one can still do that with exceptions: relatively similar to your idea (infer possible exceptions and maybe give a way to the user to annotate a function with `@safe (doesnt throw) or @throws(this and this)` .. but optionally!)
<FromGitter>
<alehander42> i am not really sure which approach would be more popular in the future :D
<FromGitter>
<KevinSjoberg> @vladfaust would it be faster in anyway using `String.build` or `IO::Memory` instead of a string literal in my solution?
<FromGitter>
<KevinSjoberg> @vladfaust alright, now it's even crazier. I get an average of 1,7 seconds in Ruby using the same solution with some minor modifications. Crystal gave me an average of 6 seconds.
<FromGitter>
<vladfaust> Nope. Use array of ords and only build the result in the very end
<FromGitter>
<KevinSjoberg> Seriously, there must be something with my Crystal code that the compiler is unable to optimise.
<FromGitter>
<vladfaust> @alehander42 it’s very interesting. An issue should be created to discuss it
<FromGitter>
<vladfaust> I guess ruby’s swapcase is better than your “implementation”
<FromGitter>
<KevinSjoberg> @vladfaust making a 4x difference? Really?
<FromGitter>
<vladfaust> Why not, it happens every iteration
<FromGitter>
<vladfaust> Compare these swapcases in a separate benchmarks
<FromGitter>
<KevinSjoberg> Sure.
<FromGitter>
<alehander42> maybe it's because strings in ruby are mutable and those in crystal: immutable, so additional allocations/copies are performed?
<FromGitter>
<vladfaust> Nice catch
<FromGitter>
<bararchy> you can freeze :)
<FromGitter>
<bararchy> Oh! make an imutable string by creating a static array of Char ;)
<FromGitter>
<vladfaust> Freezing applies to literals only, doesn’t it?
<FromGitter>
<vladfaust> I.e. literally present in the source code
<FromGitter>
<KevinSjoberg> So, swapping was not the issue.
<FromGitter>
<bararchy> how about `PUZZLE_INPUT = <<-STR.chars` and handeling it all like array of chars from the beggining
<FromGitter>
<bararchy> because a[.0..1] produces a new array
<FromGitter>
<greenbigfrog> Oh. right. Additionally I just remembered that `[0, 2, 7] # => Array(Int32)` which of course does not accept nil as value
<FromGitter>
<alehander42> @KevinSjoberg ok, I wrote my solutions in other langs and I found the immutability is the problem indeed
<FromGitter>
<alehander42> now my fixed version of your crystal solution is instant
<FromGitter>
<alehander42> just using arrays and `pop` / `<<`
<FromGitter>
<KevinSjoberg> @alehander42 care to share it? So the problem is that strings by nature is immutable in Crystal? This causing allocations when we modify/slice and append to them?
<FromGitter>
<alehander42> but i am sure crystal people can write it more idiomatically, I dont use crystal a lot
<FromGitter>
<alehander42> my theory is that is causes allocation + copy for each `str = some other completely new string expression`
<FromGitter>
<alehander42> actually, immutability doesnt have to lead to this kind of thing: e.g. in clojure new copies can share some of the contents of the original, optimizing this a lot
<FromGitter>
<alehander42> but i have no idea about the crystal string impl.
rohitpaulk has quit [Ping timeout: 244 seconds]
<FromGitter>
<KevinSjoberg> @alehander42 I think you're right. 125x performance improvement using an array instead of string.
<jokke>
today's aoc is nice. a lot to gain with an efficient algo
<FromGitter>
<alehander42> more important is the algo complexity: e.g. a copy is a linear (for string length) operation vs O(1) mutation
<FromGitter>
<alehander42> 125x is very dependent on input
<FromGitter>
<proyb6> I think some of the Crystal AOC2018 D5P2 has different results...
<FromGitter>
<KevinSjoberg> @jokke impressive!
<jokke>
thanks :)
<jokke>
a friend of mine came up with roughly the same algorithm but wrote it in haskell. that was impressive. super short and elegant.
<FromGitter>
<proyb6> @jokke The code seem to be hang on my macOS? CPU is just idle when ran
<jokke>
it expects the puzzle input from stdin
<jokke>
so use it like so: ./5 < input
jemc has joined #crystal-lang
<FromGitter>
<proyb6> I tried ./5 FuUmMfRbBVvYyzZrzZuUohNnHj which is hang, can anyone else test on macOS too?
<FromGitter>
<proyb6> Oh ```cat input5.txt | ./5``` work
<jhass>
so will ./5 < input5.txt
<jhass>
don't discard the <
<FromGitter>
<proyb6> That work as well
<jhass>
lastly ./5, pasting the contents and then pressing Ctrl+D will
return0e_ has quit [Remote host closed the connection]
rohitpaulk has joined #crystal-lang
rohitpaulk has quit [Remote host closed the connection]
return0e has joined #crystal-lang
<FromGitter>
<kingsleyh> anyone good at crypto here? I need ECIES / ECHD implementations that will work with my ECDSA implementation - and since we don't have any of this stuff yet in Crystal - I'm gonna have to write it - an alternative would be to mess about with some OpenSSL bindings but that looks pretty yuk! and every platform seems to have a different default version
<FromGitter>
<kingsleyh> I guess I really need someone to just hold my hand and tell me I can do it
<FromGitter>
<kingsleyh> and when I get a little tired to encourage me and say: that's the spirit - almost done now
<FromGitter>
<mpcjanssen> @kingsleyh isn't rule 1 of crypto, use a lib don't build it yourself?
<FromGitter>
<kingsleyh> yes @mpcjanssen - but when there is no lib - what do you do!
<FromGitter>
<bararchy> I think LibSSL bindings are the way to go
<FromGitter>
<alehander42> guys, if you are building a blockchain, maybe you should learn crypto first
<FromGitter>
<kingsleyh> well I know crypto - just as many eyes as possible are required
<FromGitter>
<bararchy> @alehander42 that's not helpful
<FromGitter>
<kingsleyh> the thing I'm concerned about with LibSSL is that people have been trying to get it work with Crystal for what seems like years - and currently still not there yet with all the stuff - and the conversations look pretty deeep!
<jemc>
using openssl as a library is a viable alternative, but be prepared to write a wrapper in C that actually exposes a sane API for FFI
<FromGitter>
<bararchy> I mean OpenSSL bindings seems pretty stright forward
<FromGitter>
<alehander42> maybe I misunderstood you, sorry if that's the case, just hoping that people really are sure in their tech when building secure-first stuff. ⏎ good luck in any case!
<FromGitter>
<bararchy> you don't need to gen a C wrapper ... you can bind to `ec.h` and `evp.h`
<FromGitter>
<kingsleyh> well I guess first I will take a crack at using the C libs
<FromGitter>
<bararchy> @kingsleyh That's the spirit!
<FromGitter>
<bararchy> ;)
<jemc>
we have this problem in Pony - the struct `ssl_ctx_st` has a size that is variable by platform, and it's not guaranteed to be stable, I think
<jemc>
size/layout, that is
<FromGitter>
<kingsleyh> gosh
<FromGitter>
<bararchy> jemc why not MACRO it then by flags ?
<jemc>
it's probably possible to reimplement the C ifdefs using crystal flags, but the "not guaranteed to be stable" part is the worrying part
<jemc>
basically, you end up depending on internal implementation details of the library, which is a concern
<jemc>
if you make a wrapper library, you can expose an opaque interface that doesn't require the caller to know the size of the struct
<FromGitter>
<bararchy> seems like the size is constant to `800` no?
<FromGitter>
<bararchy> I can't find reference to size changes based on arch
<FromGitter>
<bararchy> `but the "not guaranteed to be stable" part is the worrying part` ⏎ => Well, we use Crystal, do we really fear stability ? ;)
<FromGitter>
<asterite> yeah, a wrapper is probably the way to go (though it's a bit cumbersome). By the way, that's my only problem with bindings where you have to copy the types: sometimes you can't (easily). For example we had to write our sigfault handler in C because (if I remember correctly) the *member* `sa_sigaction` of `sigaction` is a macro
<FromGitter>
<kingsleyh> well actually I only really need OpenSSL::PKey::EC - as that should give me ECDSA and ECDH
<FromGitter>
<kingsleyh> so I might only implement that part
<FromGitter>
<kingsleyh> and I only need it for my curve - so that's probably the place to start - rather than trying to make something re-usable by others right away
thews has quit [Ping timeout: 250 seconds]
Renich has joined #crystal-lang
<FromGitter>
<RyanScottLewis> Is there a way to view code after macros have been expanded? I'm trying to debug a nested macro
<FromGitter>
<Blacksmoke16> `{{debug}}`
<FromGitter>
<Blacksmoke16> there is also `crystal tool expand`
<FromGitter>
<RyanScottLewis> It's not super clear that the --cursor option is required for `crystal tool expand` but works like a charm once ya figure that out
lucasb has quit [Quit: Connection closed for inactivity]
<FromGitter>
<kinxer> Is separating the stuff I want to test into a different file the only way to go about that?
<jokke>
well yeah
<jokke>
at least it's the only clean way to go about that
<FromGitter>
<kinxer> Gotcha. Thank you.
<FromGitter>
<j8r> @vlazar @kinxer making an issue for this ;)
<FromGitter>
<kinxer> @j8r For the shard/shards difference? xD
<FromGitter>
<greenbigfrog> what's confusing me the most about my aoc code, is way it works perfectly for the example, and task 1, but gets results of ~+10 for part 2
<jokke>
how do you know?
<jokke>
ah for part2
<jokke>
for the input up there
<jokke>
then there must be some issue with your task_1 already
<FromGitter>
<greenbigfrog> I've had someone else compare their result to mine per letter, and it's off ~+10 ⏎ Probably you're right
<FromGitter>
<girng> @oprypin if you check here (https://github.com/dominictarr/event-stream/issues/116#issuecomment-441747573) they say steal. but i don't know if that's exactly how it works. ⏎ but in any event.. the important question is.. is it possible for someone to obfuscate/hide a `http post` in crystal code?
<oprypin>
ok maybe steal it is
<oprypin>
sure, you can conceal anything in any package manager these days. crystal is among the least affected because full code audit is the most viable there
<jokke>
i'd love to have signed releases too
<Jenz>
@girng I'd say yes, without really having any arguments as for how
<FromGitter>
... uUxXuUuZzhHlLBKkTtqQEOoKkhPcCpXTtKkYwFfWDdyLZzxXEeDdykKFfcCfFtTwWMmcGMmrRbBAagsSFfTBtTmLlmMMbZzLDdlvkWwKdDVSIiVrRqBbQuUlLvjJsWwwWDCcSsdVaAvOoxHhVv"]` ⏎ And then `reduce(input[0])`
<FromGitter>
<j8r> @girng to mitigate this in shards
<FromGitter>
<j8r> ?
<FromGitter>
<j8r> In js, minified files are not uncommon. Minified Crystal doesn't exist, so it's more auditable
<Jenz>
obfuscated and minified code is not the same
<FromGitter>
<j8r> Yes, but both are hard to read
* Jenz
¯\_(ツ)_/¯
<FromGitter>
<j8r> @greenbigfrog why an array? Why not Tuple or String?
<FromGitter>
<girng> @j8r good idea. that means the maintainer could only be the person who could add naughty code?
<FromGitter>
<j8r> Of the lib? Everyone that have wrtite access can
<Jenz>
"_naughty code_" eh? Well that's a first
<FromGitter>
<j8r> What's changing is you'll see if there is a change
<FromGitter>
<girng> @j8r i mean your 242 issue in shard repo. your solution is to make the code bound to the maintainer only right
<FromGitter>
<j8r> The commit hash won't be the same
<FromGitter>
<j8r> @girng the solution is to add the commit hash of the corresponding tag. If the code change == commit change == different hash
<FromGitter>
<j8r> Evem if the owner delete/recreate the same tag
<FromGitter>
<j8r> We'll be notified
<oprypin>
i'm just mesmerized whenever I look at an official Arch package source
<Yxhuvud>
Does that mesmerize you? I've seen packaging of rpm's that have been many multiples of that size.
<oprypin>
no, in a good way
<Jenz>
oprypin: why?
<oprypin>
it's just very nicely made and everything makes sense and is very easily understandable
<Jenz>
Ah, good XD
<Yxhuvud>
I can recommend looking at the fedora packaging of ruby for something that will give you nightmares
<oprypin>
no pls
<Jenz>
Haha
<FromGitter>
<girng> i feel mesmerized whenever i look at my own code. my code is very special
<Yxhuvud>
girng: in a good or bad way?
<FromGitter>
<girng> bad hahahaha
<FromGitter>
<j8r> @girng special like you haha
Jenz has quit [Quit: night]
<FromGitter>
<j8r> If you see that your code is bad, that's good – you are progressing
<FromGitter>
<j8r> Badly, IMO, Crystal doesn't enforce enough a good one style. We can put inheritance, namedtuples and symbols everywhere, instead of composition, structs and enums
<FromGitter>
<greenbigfrog> my method to delete 2 points out of a string was deleting the wrong 2 char...
<jokke>
j8r: how come you think inheritance is bad codestyle?
<FromGitter>
<j8r> jokke: plenty of discussion are in the web, wiki, SO etc for this. In crystal, I'm still waiting someone to tell me how inheritance is better tha composition
<FromGitter>
<j8r> Composition can be used no matter of struct, module or class. No limit of `include`
<jokke>
yeah
<jokke>
i too favor composition
<jokke>
but it's not like i would consider inheritance _bad_
<FromGitter>
<j8r> Rust has only composition, Go none of this. Unnecessary i think
<jokke>
go isn't really a great language though
<dom96>
Go doesn't have composition?
<dom96>
Pretty sure that's not the case unless I'm misunderstanding what "composition" means
<FromGitter>
<j8r> H maybe, inheritance sure it doesn't have
<jokke>
go doesn't have much of anything :D
<FromGitter>
<j8r> Btw that's a bit special composition - structs inside structs
<FromGitter>
<j8r> IIRC
<FromGitter>
<straight-shoota> In the end, both composition and inheritance have their uses
<FromGitter>
<straight-shoota> That's why a oop language should have both
<FromGitter>
<girng> for example, a `broadcast_to_channel` method that is under my `GameServer` class. it accepts (channel, msg, cmd, client). instead of having every chatroom inherit this method, i just call it whenever a user sends a message. like `broadcast_to_channel chat_rooms[want_to_join], ({char_info: char_info, message: "#{client.selected_char_name} has joined."}), "USERJOIN", client`
<FromGitter>
<j8r> @straight-shoota so maybe you can answer the $1 B dollar question: what inheritance provides more thant composition in Crystal :) (I'm surely miss something valuable)
<FromGitter>
<hanneskaeufler> Hi y'all, another noob question here. Am I missing something obvious in not being able to use `ENV`and a `Hash(String, String)` interchangably? I basically want to inject a `ENV` into a ctor but in my test code I want to fake the ENV by using a Hash instead. All I am calling is `[key]`.
<FromGitter>
<girng> it's all about function memorization. the more functions you have in your brain (that are loaded dependent on what project your working on), the more powerful you feel while coding. when classes have a method, your brain has to think of that class first, then think of the method that is under the class. some people prob think this is more organized, but just from my experience, it hinders me. i like to just
<FromGitter>
... think of the function and BAM, start typing it. to me, the process of memory recollection is faster if done that way