<asterite>
Yes, but read the whole PR's text to understand why that isn't very good
<jhass>
asterite: not sure I found the argument against :)
<jhass>
anyway, this is a very double edged sword
<asterite>
jhass: imagine you want to add a new method to Enumerable
<jhass>
and I'm not yet sure that the wrong edge isn't the sharper one
<asterite>
you have to use that trick, checking T, etc.
<asterite>
with auto unpacking you just write the code and it works, for tuples and non-tuples
<jhass>
especially the second case is entirely non-obvious I think
<asterite>
I mean, there's nothing really dangerous with this
<asterite>
Really? I'll reply to kostya now
<jhass>
many Rubyists don't like autounpacking too much already, as it is just too unobvious
Ven has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<jhass>
I have to think more about it, if we can keep the noise low for handling T, some kind of direction as I was going, I don't have the feeling its bad having to do it
pawnbox has joined #crystal-lang
onec has quit []
mgarciaisaia has joined #crystal-lang
<asterite>
The solutions I see are: 1. do autounpacking or 2. leave Enumerable like that and not make Hash be an Enumerable
mgarciaisaia has left #crystal-lang [#crystal-lang]
<asterite>
I definitely wouldn't like to modify Enumerable to consider two cases for T, everywhere, and also forcing that on users wanting to extend Enumerable
<jhass>
mh
<jhass>
what if (we add syntax to) Foo(*T) with a single argument doesn't make T a tuple?
<jhass>
and *T with T not being a tuple would simply be T
ponga has quit []
<asterite>
But when if you do {% for type in T %} that will only work if T is a tuple, right?
<asterite>
I though a lot about the problem, and now I understand why auto-unpacking exists in Ruby... maybe it's for this case. I can imagine Matz and others thinking about this same problem too
<jhass>
yeah
<jhass>
I think the second rule bothers me the most, I see how it's useful from the consumer API perspective
<jhass>
but it's an insane special case from the yielders perspective
<asterite>
why?
<asterite>
why only apply the rule for just one argumen?
<asterite>
I don't think the yielder has to worry about this
<asterite>
unpacking is chosen in the block side
<asterite>
In fact, with this, Enumerable just yields the object and index, in each_with_index. Then when writing the block I can choose to unpack it, either explicitly or implicitly
<jhass>
say I want to verify how many arguments something yields, because I suspect a bug, like some coding taking too many block parameters and I suspect a nil coming from there
<asterite>
or just yields the object in `select`, without having to know if it's a tuple or not... and it doesn't need to do `yield *args` nor `do |*elem|`
<jhass>
I look at the implementation and see yield a, b
<jhass>
I might think it's two arguments
<jhass>
but I actually can no longer easily tell in which block argument b will end up in
<asterite>
yes, you can: in the last one
<asterite>
if there's more than one block argument, that is
<asterite>
if there's one, it's a
<asterite>
if there's two, it's a an b
<asterite>
if there's more than two...
<jhass>
if there's three I have to know whether a is a tuple or not
<asterite>
if there's three, a is a tuple
<jhass>
if there's four and a is a two element tuple, I have to synthesize an invisible arg as nil
<asterite>
otherwise the caller wouldn't have used three arguments
<asterite>
I mean, I can see auto tuple unpacking being used explicitly
<jhass>
no that's not true, my initial scenario was that the caller might have made a mistake I'm trying to debug
<asterite>
it's kind of strange, but if I provide more block arguments than the number of yielded objects, it's because I expect a tuple to be yielded, and I usually know how many elements in the tuple to expect
<asterite>
doesn't that also happens with just `yield a`, where a is an array, and auto-unpacking happens in Ruby?
<jhass>
yes, one of the reasons a bunch of rubyists wish it wasn't a thing
<asterite>
:-)
<asterite>
do you use this feature in Ruby?
<jhass>
on the block side, I can't remember doing it on the yield side
<jhass>
that is writing yield a instead of a, b = a; yield a, b
<asterite>
mmm... what's "on the yield side"?
<jhass>
I mean I don't yield an array with the intention of the consumer relying on autosplat to consume it
<jhass>
if I yield an array its for the consumer to work with it as an array
<jhass>
else I unpack the array already before yielding it
<jhass>
btw I don't mind at all the occasional each_with_index do |(k, v), i| in ruby
<jhass>
I think I wouldn't even mind a hash.map {|(k, v)| } in crystal
<asterite>
what about hash.each { |(k, v)| .. .}
<jhass>
would be consequent
<asterite>
we could do that... i think it would be a bit annoying, maybe
<asterite>
but it would be the simplest thing to do. Then it would just be an Enumerable({K, V}) and it will work, but you'll always have to explicitly unpack key and value
<jhass>
yes
<jhass>
mmh, I don't know
<asterite>
I actually never had issues with auto-unpacking (what's the official term for this?) in Ruby
<pabs>
asterite: splatting
<asterite>
and I used it a bunch of times, mostly when iterating arrays of arrays of known size
<jhass>
what I know is that autosplat is one of the more confusing regular topics in #ruby for newcomers
<jhass>
I see autosplat most commonly used
<pabs>
^
<jhass>
so making its behavior even more complicated to explain in crystal frightens me a bit
<asterite>
I see it like this: if we change hash to do yield({key, value}), then one has to use do |(key, value)|. It's explicit, there's no magic, and we can include Enumerable
<asterite>
then if I know autosplatting, I can use it too. The problem is someone looking at that code and doesn't know I wanted autosplatting
<asterite>
it's explicit for the one that writes the code, but implicit for the one that reads it
<jhass>
another brainstorm: what if autosplatting happens only if requested by the yielder? That means yield *a with a being a tuple would get the tuple for do |a| and the elements for do |a, b| (and the element for do |a| with a single element tuple)
<jhass>
then make Array.each do yield *e
<jhass>
yield *a with a not being a tuple would just yield the value normally
<jhass>
yield a would never autosplat, do |a, b| would make b always nil
<asterite>
Maybe. The problem is that someone wanting to include Enumerable in their type would have to do `yield *a` too
<jhass>
if they want to keep their each consistent with Enumerable, yeah
<asterite>
with explicit splat or autosplat they don't have to worry about that, it just works
<jhass>
my bigger issue is that Array({A}).each would yield A's instead of {A}'s
<asterite>
the explicit splat route isn't bad either
Raimondii has joined #crystal-lang
<jhass>
we probably should poll the community about it, I can't decide
paulcsmith_ has joined #crystal-lang
<jhass>
btw autounpack is probably the better name
Raimondi has quit [Ping timeout: 240 seconds]
<asterite>
yes, it's a hard decision
<asterite>
I'm tempted to do the autounpacking... it looks nicer to the eye and there's less typing... but I understand the reasons not to do it
<asterite>
I was against it before, but mostly because it seems too hard to implement :-P
soveran has quit [Remote host closed the connection]
Raimondii has quit [Ping timeout: 240 seconds]
<asterite>
Some guys at Manas also like the explicit unpacking approach
<asterite>
jhass: do you have some links about confusing around autounpacking? It's hard to search on Google
<jhass>
no, as said most of my experience about it comes from talk in #ruby
Raimondii has joined #crystal-lang
P_raimondii has joined #crystal-lang
P_raimondii is now known as Raimondi
Raimondii has quit [Ping timeout: 240 seconds]
mgarciaisaia has joined #crystal-lang
mgarciaisaia has left #crystal-lang [#crystal-lang]
<Davy_CC>
+1 vote for not auto-splatting, I think programmers can decide when to splat it and we can check if the argument is Enumerable or not in compile-time
<Davy_CC>
and programmers can choice `yield *a` or `do |*a|` for splatting is good
<crystal-gh>
[crystal] jhass opened pull request #2779: Return zero exit status for explicitly requested help displays (master...zero_exit_help) https://git.io/voq7P
<jhass>
asterite: so... maybe?
<jhass>
:P
soveran has joined #crystal-lang
<asterite>
hahaha, I don't know either
soveran has quit [Changing host]
soveran has joined #crystal-lang
<asterite>
but blocks in ruby are big beasts... in crystal they are (still) more innocent
soveran has quit [Ping timeout: 258 seconds]
Raimondi has joined #crystal-lang
Raimondi has quit [Read error: Connection reset by peer]
Raimondi has joined #crystal-lang
pawnbox has quit [Remote host closed the connection]
pawnbox has joined #crystal-lang
rolha has quit [Ping timeout: 264 seconds]
<crystal-gh>
[crystal] paulcsmith opened pull request #2780: Include `HTTP::` in docs for server handlers (master...patch-1) https://git.io/voqpm
<crystal-gh>
[crystal] jhass pushed 2 new commits to master: https://git.io/voqpW
<crystal-gh>
crystal/master 936837f Paul Smith: Include `HTTP::` in docs for server handlers...
<crystal-gh>
crystal/master a390424 Jonne Haß: Merge pull request #2780 from paulcsmith/patch-1...
mark_66 has quit [Remote host closed the connection]
Raimondi has quit [Read error: Connection reset by peer]
soveran has joined #crystal-lang
Ven has joined #crystal-lang
mgarciaisaia has joined #crystal-lang
soveran has quit [Remote host closed the connection]
<crystal-gh>
[crystal] asterite opened pull request #2781: Make Hash (and others) yield tuples in each (master...feature/hash_tuple) https://git.io/vomIQ
Nik736 has joined #crystal-lang
Raimondi has joined #crystal-lang
A124 has quit [Ping timeout: 250 seconds]
<rkeene>
I haven't checked in in a while -- has there been any work on making Crystal a better cross-compiler ?
A124 has joined #crystal-lang
soveran has joined #crystal-lang
mgarciaisaia has left #crystal-lang [#crystal-lang]
soveran has quit [Remote host closed the connection]
<rkeene>
Last time I looked it only accepted two pieces of information about the target -- the OS name and the CPU architecture... which is not enough information
<jhass>
not sure, I don't think so. What else do you need?
soveran has joined #crystal-lang
ton31337 has left #crystal-lang [#crystal-lang]
<rkeene>
The complete platform identifier, usually something like linux-unknown-x86_64-gnu or linux-unknown-arm-musl
<rkeene>
And some of those are multilib, so they support for example 32-bit and 64-bit code, so you have to specify additionally which one. Also popular is thumb/non-thumb.
<rkeene>
A lot of platforms encode the ABI information into the OS name by including the OS version, e.g. hpux11.11 and hpux12.00 have different ABIs
<jmg_>
Was just looking over the PR that introduces the `as` method... Made me curious if there has been any talk regarding syntax sugar to unwrap optionals
<jhass>
rkeene: isn't that what --cross-compile took all along?
<rkeene>
jhass, No, it just takes an OS name and CPU arch.
<jhass>
ah there's --target which takes an LLVM target triple
<jmg_>
While it wouldn't work with current grammar, just curious if there's been talk about shorthand to go from String? -> String. Similar to Swift's `!`
<jhass>
ah yeah I remember some, the consensus was that the verbosity of .not_nil! is good since it's potentially unsafe (that is can cause runtime errors)
<jhass>
the safe way already is just if foo
<jhass>
or .try &.cool
<jhass>
and .not_nil! is also a bit abstracted away already in getter! / property!
<jhass>
so I don't think we have an actual strong need here and the verbosity encourages you to avoid nilable vars in the first place :)
<rkeene>
jhass, Right, I think this hasn't changed -- you need to specify --cross-compile "Linux x86_64", which is redundant to --target and Crystal actually uses Linux and x86_64 in places where it should use the target
<jhass>
rkeene: contributions welcome, cross compilation is nothing any regular contributor is doing on a daily basis ;)
<rkeene>
Atleast this is how it used to be.. it made things confusing when cross-compiling from "Linux x86_64" to "Linux x86_64"
<rkeene>
jhass, My Linux distribution is always cross-compiled -- I can't run the executables it compiles even though they are for Linux/x86_64 and my laptop is Linux/x86_64
<rkeene>
If I compile my Linux distribution on Windows (./configure && make there too) it produces the same output (the installer ISO image is the first target in my Makefile) with the same constraints -- I can't run the code it compiles
<jmg_>
jhass: Awesome, I just wanted to read the discussion about it. `not_nil!` led me to https://github.com/crystal-lang/crystal/issues/406... It's just practically impossible to search for `?` and `!` via Github Issues
<jhass>
:)
sp4rrow has joined #crystal-lang
<sp4rrow>
I will fix it but where is the repo that generates this
Ven has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<sp4rrow>
cool that is interesting
<sp4rrow>
I have never dived down into that piece of tooling
Raimondi has quit [Read error: No route to host]
Raimondi has joined #crystal-lang
snsei has quit [Remote host closed the connection]
<jmg_>
jhass: Regarding the `not_nil!` method, in the following case is there a way to inform the compiler that `#types` is never going to be `Array(String)?` because of the previous `reject` method?