<yopp>
I've got `class Document < ::Hash`. And crystal complains that there`wrong number of type vars for Hash(K, V)`. It should be something like Hash(T,T)? Or Hash(Any,Any)?
<yopp>
Document is Hash-like type
mgarciaisaia has joined #crystal-lang
<RX14>
why would you want to subclass hash?
<RX14>
also it would be class Foo(K, V) < Hash(K, V)
<RX14>
or maybe class Foo < Hash(String, Int32)
<RX14>
but i would strongly recommend using composition here
<RX14>
not inheritance
<yopp>
RX14, because they subclassed hash in ruby lib. Not such a good idea even in ruby.
<bmcginty>
yopp: curious what you're porting, if you can share. also, could you do instance_variable_get? as a macro? just return @{{name.id}} (or something like that...I don't have docs in front of me or brains at the moment).
soveran has quit [Remote host closed the connection]
soveran has joined #crystal-lang
soveran has joined #crystal-lang
soveran has quit [Changing host]
<FromGitter>
<sdogruyol> @andreaTP welcome to Crystal community :+1:
<FromGitter>
<andreaTP> thanks!
<FromGitter>
<bcardiff> @andreaTP great! I would suggest you to benchmark that `class Point` changing it to `struct Point`. That should improve things.
<crystal-gh>
[crystal] asterite pushed 1 new commit to master: https://git.io/v1N1t
<crystal-gh>
crystal/master 0c9ee1f Ary Borenszweig: Docs: fixed small links issue. Related to #3693
<crystal-gh>
[crystal] Sija opened pull request #3742: Add :nodoc: to Class#crystal_instance_type_id (master...crystal_instance_type_id-nodoc) https://git.io/v1NMa
mark_66 has quit [Remote host closed the connection]
<FromGitter>
<andreaTP> wow changing it improve by 5X :-)
<FromGitter>
<andreaTP> I usually refer my implementations to the Scala one, and try to stay with it as much as possible, as said, first ever time with crystal and it takes about 2 hours effort from zero to that :-) one of the best personal experience with a new language to be honest
<RX14>
yeah I really like the way crystal handles JSON for a statically typed language
<FromGitter>
<asterite> @dom96 thanks! Is there a typo in the example? The proc is called "apply" but the example shows "map". Also, why isn't it idiomatic?
<RX14>
the group_by call seems to make up most of the cost
<RX14>
@asterite somehow when using kcachegrind I get line numbers greater than the number of lines in the file
<RX14>
i think there's a problem with the debug line info
<Yxhuvud>
group_by..values? isn't that #partition ?
<FromGitter>
<andreaTP> Yes a huge part in this test is taken by the hashmap
<RX14>
@Yxhuvud no i don't think so
<dom96>
asterite: probably a typo. We have 'map' which returns a new seq and 'apply' which performs the operation in-place
<RX14>
partition works for booleans
<dom96>
asterite: because Nim is a procedural language, it's more idiomatic to use a for loop.
<crystal-gh>
[crystal] asterite closed pull request #3724: Add File and Dir empty? methods (master...add-file-and-dir-exists-methods) https://git.io/v153a
<RX14>
running #clusters is 146 times slower then running #closest on each x
<RX14>
so it really is the group_by that is >99% of the cost
<FromGitter>
<andreaTP> I haven't yet digged enough, what about types in Crystal? There are structural? And HKT? Or again what do you do to reconcile types in different code bases?
<FromGitter>
<andreaTP> I mean there are here type classes or things like this?
soveran has quit [Ping timeout: 256 seconds]
bjz has quit [Quit: My MacBook Pro has gone to sleep. ZZZzzz…]
soveran has joined #crystal-lang
soveran has joined #crystal-lang
soveran has quit [Changing host]
soveran has quit []
soveran has joined #crystal-lang
soveran has joined #crystal-lang
soveran has quit [Changing host]
mgarciaisaia has quit [Quit: Leaving.]
<RX14>
@andreaTP types themselves are pretty simple in crystal
<RX14>
we have generics, and thats about as fancy with types your typical codebase is going to get
<minus>
why does crystal need a GC?
<RX14>
so that it's one less thing for the user to worry about
<minus>
or one more
<FromGitter>
<andreaTP> @RX14 so you mean that code will flow pretty straight forward and just blocks and functions guarantee composability?
<RX14>
Crystal is an object oriented language
<RX14>
so it has a type system built for OO
<FromGitter>
<andreaTP> And what if you have different codebases that try to have have for example the same #log method and you wanna abstract over that?
<RX14>
two objects with #log with the same signature?
<FromGitter>
<andreaTP> I mean with different Log classes inherited
<RX14>
yup
<RX14>
you could pass around a union of the two types
<FromGitter>
<andreaTP> Sorry for bothering :-) and thanks a lot for your time btw
<RX14>
if you wanted to have a more conrete type to represent that, you would have to reopen both classes and include a module which unified them
<RX14>
in general I would recommend wrapping them in your own code
<RX14>
make your own log interface and create classes which called the underlying logger implementations
<RX14>
that has the advantage of being able to handle implementation differences between the two classes
<FromGitter>
<andreaTP> Uhmmm this will end in some boilerplate code imo ..
<RX14>
well the scenario you describe is quite rare
<RX14>
boilerplate code isn't a bad thing in itself imho until it becomes more effort to maintain the boilerplate than the simplicity you gain
<RX14>
copy and pasting code is perfectly fine until you have to copy and paste it too often
<RX14>
and for this specific case of abstracting a logger I would think that the number of implementations you're going to have is going to be quite small so it's probably not worth doing something fancy
<FromGitter>
<andreaTP> I really wanna deepen in real use cases outside language codebase itself for sure :-)
<FromGitter>
<andreaTP> I mentioned logger due to have background XD
<FromGitter>
<andreaTP> that is something that can get into trouble in large codebases in Java world
<RX14>
you could say that crystal's big stdlib is a byproduct of this, because if you have a Logger class in the stdlib which everyone uses, then you never have the problem at all :)
<FromGitter>
<andreaTP> this easily becomes untrue as soon as libraries proliferates
<Papierkorb>
RX14: Though the logger has to hold pace. I'm using the "logging" gem in ruby land, which is much better than the stock logger class
<RX14>
yes
<RX14>
logger is a pretty bad example
<RX14>
i quite like java's loggers where they're namespaced
<RX14>
so libraries can log under their namespaces
<Papierkorb>
The logging gem is modeled after a popular java logging lib iirc
<RX14>
at various log levels
<Papierkorb>
Yep
<RX14>
and then you can adjust what logging happens at the namespace level
<RX14>
being able to just turn on logging for libraries is fantastic
<FromGitter>
<andreaTP> my point here is to check how much the language itself trust external libraries :-) that is always a trade-off
<FromGitter>
<andreaTP> Please tell me if I'm hijacking the channel anyhow, sorry of I hurt anyone
<RX14>
no of course not
<RX14>
this channel is generally pretty quiet, there's always room for some longer conversation
<FromGitter>
<andreaTP> Wow so please guys go on and elaborate on extensibility I will be here to listen eager your opinions
<FromGitter>
<andreaTP> Just as a chat I skipped Crystal talk at Ecoop last year because the first spot is * sexy as Ruby * and I normally skip untyped languages talks....
<RX14>
hah
<FromGitter>
<andreaTP> But right now it turn out it is a complete Typed language
<RX14>
have you read the language docs about how the type system works?
<FromGitter>
<andreaTP> And first feeling is great
<FromGitter>
<andreaTP> I can say half of it
<RX14>
ok
<FromGitter>
<andreaTP> Honestly I just spent something.around 3 4 hours
<RX14>
well I would say the most powerful part of crystal's type system is the type unions
<RX14>
and that calling a method on a union works as long as every member of the union can sccept that signature
<RX14>
the rest of the type system itself is pretty boring
<FromGitter>
<andreaTP> Well I found it confusing at first due to type inference
<RX14>
the type inferrence algorithm is pretty nice too
<RX14>
it tends to just get out of the way
<RX14>
the best way to get familiar with crystal's type system is to use it honestly
<FromGitter>
<andreaTP> What happens is that you can assign int to strings
<FromGitter>
<andreaTP> I like the honestly keyword :-)
<RX14>
well it's more accurate to say that you can assign an int to a variable which is typed String :)
<FromGitter>
<andreaTP> But I usually prefer to get at least compiler warnings on such things
<RX14>
not having that rule would actually ruin quuite a lot of the language imho
<FromGitter>
<andreaTP> If you declare a variable you.can assign whatever ....
<RX14>
but the error becomes immediately obvious when you use the variable with the expectation that it has a String type
<Yxhuvud>
well, you get an error if you actually declare it as something and assigne something different
<Yxhuvud>
but assignment != declaration.
<FromGitter>
<andreaTP> I said warning not error
<RX14>
but it happens so often in actual code
soveran has quit [Remote host closed the connection]
<FromGitter>
<andreaTP> Not at all it happens always if you are not careful declaring types in my.experience
<RX14>
but in crystal you shouldn't need to declare types often
<FromGitter>
<andreaTP> Uhmmmm I prefer to declare them once
<FromGitter>
<andreaTP> Than to cast or whatever Everytime I use a function
<FromGitter>
<andreaTP> Usually I mean
<RX14>
you want to manually declare the type of every variable? like in java?
<FromGitter>
<andreaTP> Probably.yes at declaration time if it is not obvious, it saves you on ALL the rest!
<RX14>
i find that the issue of typos doesn't actually come up too often
<RX14>
and at least when you do the compiler errors are quite obvious
<FromGitter>
<andreaTP> I always try to think about what happens when codebase become larger
<RX14>
but variable typing is an issue for functions
<FromGitter>
<andreaTP> And typos are the least important thing
<RX14>
and doesn't tend to extend to the codebase as a whole
<RX14>
so as long as your functions remain the same size, it doesn't tend to be an issue
<RX14>
functions and function arguments can be explicitly typed
<FromGitter>
<andreaTP> In Crystal you have functions pointers
<FromGitter>
<andreaTP> I agree on explicitly typing functions of course :-)
<RX14>
actually I tend not to do it
<RX14>
at least not the arguments
<RX14>
typing return values is much more beneficial
<FromGitter>
<andreaTP> Could I ask why?
<RX14>
what you do with your arguments in the function, by using their interface, is usually an adequate enough type
<RX14>
i guess you could call it structural typing
<FromGitter>
<andreaTP> You can throw casual exceptions handling that
<RX14>
what do you mean?
<FromGitter>
<andreaTP> I mean without declaring variance on the type
<FromGitter>
<andreaTP> On method handling contravariance I.e.
dtzu has joined #crystal-lang
<FromGitter>
<andreaTP> You are expecting your users will experiment against your API before getting it right instead of typechecking it
<FromGitter>
<andreaTP> I hope I am wrong e
<RX14>
if the type you pass into the function doesn't have a method that the function uses, you will get a compile error
<RX14>
not a runtime error
<FromGitter>
<andreaTP> So it is structurally typed?
<FromGitter>
<andreaTP> It is not mentioned in docs as far as I read....
<RX14>
i guess it is a form of structural typing
<RX14>
but you can't name a structural type in crystal
<FromGitter>
<andreaTP> Sorry again for bothering but I found it incredibly interesting :+)
<RX14>
you can only give names to concrete types
<FromGitter>
<andreaTP> Uhmmm this sounds like a lack of foundations?
<FromGitter>
<andreaTP> Even if the idea is really great
<FromGitter>
<andreaTP> In scala you can have alias type for such things
<RX14>
ok, the way crystal's type system works is that every time you call a method, crystal checks that the types you've passed in to the function are valid
<RX14>
i'm not selling it very well but it works well in practice
<RX14>
i guess
<FromGitter>
<andreaTP> At compile PR run time?
<FromGitter>
<andreaTP> The check happens I mean
<RX14>
yes, all the type checking is done at compile time
<RX14>
in fact, if you have foo("bar") and foo(1), crystal will generate two methods, for foo(String) and foo(Int32)
<RX14>
even if foo only has one single definition
<FromGitter>
<andreaTP> I really have to deepen this tpoic, too late right now :-) please give me some links :-)
<RX14>
for example def foo(item); puts item; end
<RX14>
well i guess I would recommend reading some of the stdlib
<RX14>
to get an idea of how crystal works in tractice
<FromGitter>
<andreaTP> No link on how it works?
<RX14>
hmm
<FromGitter>
<andreaTP> Blog whatever...
<RX14>
i've learnt through experimentation so i'm not really sure
<FromGitter>
<andreaTP> It will be really appreciated
<RX14>
there might be something on crystal's blog
<FromGitter>
<raydf> @andreaTP , what topic are you looking for?
<FromGitter>
<jots_twitter> oof, just found out that "retry" doesn't exist in crystal.
<RX14>
retry has been discussed, but typing with retry becomes quite a problem
<FromGitter>
<jots_twitter> I see. working around it now by having the method call itself recursively (after fiddling with state to help it work next "try").