<asterite>
On my VMs it's always printing UNKNOWN as the dir type
<jhass>
sure, right after lldb compiling is done ;P
<jhass>
asterite: looks fine, anything wrong with it?
<jhass>
asterite: there's another weird LLVM issue btw: it doesn't spit out object files that can be linked with -fPIC or -fPIE
<asterite>
You wouldn't happen to have trusty64 somewhere to try that code, right? :)
<asterite>
What's fPIC and fPIE?
<jhass>
what it comes down to is that they build a binary that uses relative jumps, which allows the kernel to do better address randomization basically
<jhass>
which makes ROP a lot harder
<jhass>
PIE is the newer version of PIC basically
<jhass>
some build environments set that as part of a "hardening process"
<asterite>
Dir.list uses it... but that method is ugly, it returns a name and a type. It could return a Dir::Entry of some sort, but if dirent is unreliable maybe we can just drop it, and just list the names and use Dir.dir?(...)
<asterite>
jhass: what do you think? You think it would be much slower that way?
<asterite>
(I want to solve this first so linux 32 and 64 bits works for me and we can start adding 32 bits to the releases)
<jhass>
asterite: sorry, llvm build is heavy so my machine is kinda slow
<asterite>
Here it's summer time and it gets very, very hot. In those moments I compile LLVM head and put my head near the fans of my computer
<asterite>
(well, at least I can hear them spin very fast)
<jhass>
:D
tymat has joined #crystal-lang
<jhass>
when I wish I had more than 8G of ram
<jhass>
linking llvm is ... ^
<jhass>
asterite: so, if dirent is not portable, the question whether the portable alternative is too slow doesn't come to mind for me, if I got you right
<jhass>
btw I have two ideas to make working with enums nicer
<jhass>
1) add methods to all enum instances for all variants that check whether the current instance is it: enum Foo; A; B; end; Foo::A.a? #=> true Foo::A.b? #=> false
<jhass>
2) let === compare it to symbols so you can do case Foo:A; when :A; when :a; when :B; when :b; end (that is allow the original case and lowercase)
<asterite>
Yes, those would be really nice
<asterite>
I actually think the compiler should do some sort of transformation
<asterite>
Because if you have an enum restriction then a symbol won't pass... but, the compiler could check if it's a symbol literal and do the conversion
<asterite>
In this way it will also be faster (no checks at runtime)
<asterite>
The downside is that you can't assign a symbol to a variable and pass it, but i think that's a less often case
<jhass>
I think we're approaching a point where we need to take care to add not too much compiler magic
<jhass>
one of the things I like about ruby is that you can reduce _a lot_ of stuff to simple standard method calls
<asterite>
In that case, if you want the symbol to enum conversion you would provide an overload for symbol, right?
<jhass>
even the &:foo trick is just that
<jhass>
or Module#include, just a method
<jhass>
right
<jhass>
in ruby, case foo; when -> {|x| x.even? }; end; works because Proc#=== is an alias to Proc#call
<jhass>
and so on
<asterite>
The last one also works in Crystal ;-)
<asterite>
I know, we try to make all things be defined in crystal itself. But sometimes we have to make a compromise and decide whether something is going to be nice but slow or it can be a bit uglier but much faster
<asterite>
But we are always trying to push the limits :)
<asterite>
(like, recently we implemented some Function primitives in crystal itself)
<asterite>
I'm starting to think that not matching Ruby API in some cases is not very good
<asterite>
Like includes?, ends_with?
<asterite>
They are just small details
<asterite>
We could provide aliases, maybe
<jhass>
well, two options really: 1) familiar environment for the ruby programmer: Rubys APIs should work where possible 2) clean plate: redesign stdlib with clear conventions on how naming should be
<jhass>
currently it's sorta in between
<jhass>
simple example: Matz said that he would drop Hash#has_key? in favor of Hash#key? if it wouldn't break every second Ruby program in existence
<jhass>
because Hash#key? follows the naming scheme, Hash#has_key? doesn't
<asterite>
Interesting
<asterite>
Well, in our case we don't have to worry about backwards compatibility. Porting a Ruby app can't never be a one to one translation
<asterite>
A concatenation for each file. Anyway, if we find a portable way to do it, I think Dir#read, Dir#each, etc. should return Dir::Entry objects with that info
<epitron>
Can't you just make an ifdef?
<epitron>
Dir.files and Dir.dirs might be handy too
<jhass>
epitron: it seems to work on my arch, but not on asterite's ubuntu...
<jhass>
or maybe it's ext3/4 vs btrfs, who knows
<epitron>
Yeah - so just have two versions of Dir.list!
<asterite>
The strange thing is that it seems to be working on drone.io too, and I think that's an ubuntu too
<jhass>
I think it's the filesystem
<epitron>
Makes sense
<asterite>
I think it's the filesystem too, so an ifdef won't be enough
<epitron>
Why not?
<epitron>
Oh right
<jhass>
compile time flag to find out the runtime filesystem? ;)
<epitron>
Lol
<epitron>
Sorry
<jhass>
you're welcome
<jhass>
:P
<epitron>
That is annoying
<epitron>
I guess if it gets 0 back it could stat
<jhass>
so, stat in stdlib it is
<epitron>
That's pretty simple
<jhass>
and since you get to the low level in crystal so easily
<jhass>
we just do crystal-fast-dir
<jhass>
for those cases where you can use it because you know what you're doing
<epitron>
Hmmm
<epitron>
<asterite> We were using dirent's d_type, but that returned 0 for me in some linuxes
<weskinner>
ahh. Is it something worth trying to document at this time?
<asterite>
Yes, maybe. At least something saying "create a Projectfile and list dependencies like this". Then say about the current limitations (only github, checkouts out lastest version, etc.)
<asterite>
It's not too much documentation to write, so I think it's worth it
<weskinner>
cool. Is markdown preferred?
<asterite>
weskinner: just some minutes, I'll be back
<asterite>
weskinner: how to document is itself not documented (gotta love recursion), but we use GitBook in the gh-pages branch of the main repository
<asterite>
I would add a section saying "Dependencies" and documenting it there
<asterite>
Or you can just add a wiki page in the repo and later one day we can move it to the main docs
<weskinner>
asterite: can you explain:
<weskinner>
def eval with DSL.new(self) yield end
<weskinner>
in project.cr
<weskinner>
is "with" a crystal keyword?
asterite has quit [Ping timeout: 246 seconds]
asterite has joined #crystal-lang
<asterite>
weskinner: yes, it's a keyword. It's a way to almost do instance eval, but not quite. It's useful for DLSs
<asterite>
(that's the only documentation of that for now)
<asterite>
Basically, when you invoke a method without a receiver inside a block that was yielded with `with ... yield`, methods will be first looked in that yielded object
<weskinner>
so Projectfile with be evaluated with "struct Deps" in scope?
<weskinner>
ahh nm I see in the specs now how it works
asterite has quit [Ping timeout: 246 seconds]
<weskinner>
Projectfile should look like "deps do; github "..."; github "..."; end;"
waj has quit [Quit: Leaving.]
<weskinner>
is the "&.call" from ruby or is that unique to crystal?
<jhass>
in between
<weskinner>
aware of (&:call) but haven't come across &.call
<jhass>
it's inspired by &:call
<weskinner>
ah ok
<jhass>
but more powerful
<jhass>
although also with slightly different limitations
<jhass>
.inject(&.+) doesn't work, it calls the unary + and doesn't pass the second block arg as argument
<weskinner>
I stumbled across &.call &.call ... chain in the compiler. It's a nice syntax
<jhass>
but you can do &.foo('foo')
<jhass>
and (&.foo {|x| ... })
<jhass>
and so on
<weskinner>
nice
<jhass>
it's basically a syntax rewrite to {|x| x....}
ismael_ has joined #crystal-lang
waj has joined #crystal-lang
ismael_ has quit [Remote host closed the connection]
weskinner has quit [Ping timeout: 246 seconds]
<epitron>
jhass: ruby should adopt &.
<epitron>
It's great
<jhass>
;)
<jhass>
asterite did something silly these days with it: &.each &.try &.each do |item|
<epitron>
Does crystal have a way of specifying block args for it?
<jhass>
what do you mean?
<epitron>
Hmm!
<epitron>
Uhm
<epitron>
hash.map &.first gets you keys
<epitron>
But what if you wanted to do something with both args
<epitron>
I guess you'd use a block
<epitron>
:)
<jhass>
yeah, &. only works for single argument blocks for now
<jhass>
it ignores all other arguments
<jhass>
thus .inject &.+ doesn't work as expected
<epitron>
Orly
<epitron>
Makes sense I guess!
<jhass>
it calls the unary one
<jhass>
>> [-4].inject &.+
<epitron>
Hah
<DeBot>
jhass: -4
<jhass>
or not even that, dunno
<jhass>
>> [-4, -2].inject &.+
<DeBot>
jhass: -4
<epitron>
>> [-4].inject &.-
<DeBot>
epitron: -4
<epitron>
Shrug
<epitron>
>> [-4].map &.-
<DeBot>
epitron: [4]
<epitron>
:D
<jhass>
>> [-4, 0, 0].inject &.-
<DeBot>
jhass: -4
<jhass>
mmh
waj has quit [Quit: Leaving.]
zamith has joined #crystal-lang
asterite has joined #crystal-lang
<asterite>
It seems Ruby's Symbol#to_proc creates a Proc that is variadic
<asterite>
Probably uses send behind the hoods
<asterite>
I just find out about that varaiadicness...
<asterite>
On the other hand, what's another use case for &:+ ? inject(&:+) is the same as sum, and we already have that covered
<jhass>
mmh, you can do join with it :D
<jhass>
%w(a b c d).inject(:+)
<epitron>
yeah, you don't even need the &
<asterite>
:-D
<epitron>
reduce is awesome
<epitron>
def factorial(n); (1..n).reduce(:*); end
<epitron>
(i never liked the name "inject"... i always use "reduce" :)
<asterite>
A friend of mine likes collect instead of map
<asterite>
He really likes Smalltalk too, so...
<jhass>
that's like the people that like detect over find
<jhass>
or find_all over select
<jhass>
it goes on
<asterite>
Yup, still talking about the same guy here :)
<epitron>
collect isn't map
<epitron>
collect is select
<jhass>
no, collect is map
<jhass>
find_all is select
<epitron>
nobody in their right mind would call "transforming data" collecting it
<epitron>
jhass: nope! I refuse to accept that :)
<asterite>
I don't know why they would prefer a longer name
<epitron>
jhass: so smalltalk's is called collect?
<epitron>
i guess collect makes sense if you're getting an attribute from a bunch of objects
<jhass>
I don't know smalltalk
<epitron>
it makes no sense if you're doing everything else though
<asterite>
I don't know smalltalk either, I might be mixing names
<jhass>
asterite: guy in #ruby earlier this day had the idea for Enumerable#includes_all? / includes_any?
asterite has quit [Ping timeout: 246 seconds]
weskinner has joined #crystal-lang
weskinner has quit [Client Quit]
weskinner has joined #crystal-lang
<weskinner>
whats the best way around:
<weskinner>
Error while requiring prelude. can't find prelude
<weskinner>
I'm using a locally built crystal
<jhass>
do you start through the bin/crystal wrapper?
<weskinner>
ahh no I wasn't
<weskinner>
forgot that step. Knew I had solved this on my other machine
<epitron>
nooooo
vifino has quit [Ping timeout: 246 seconds]
<epitron>
you guys took out list with d_type
bcardiff has quit [Quit: Leaving.]
<jhass>
it was broken!
<epitron>
you could've made a backup method
<epitron>
so that my script would still work
<epitron>
like, list_with_types
<jhass>
you could make a library that supports it
<crystal-gh>
[crystal] epitron opened pull request #404: 'string["substring"]' (like in Ruby) added (master...strings) http://git.io/bdw9
<epitron>
jhass: i'm adding an "each_with_type" that falls back to stat if d_type is 0
vifino has joined #crystal-lang
<epitron>
def self.directory?(path)
<epitron>
Dir.exists?(path)
<epitron>
end
<epitron>
o_O
<jhass>
hum
<jhass>
>> Dir.exists?("/etc/passwd")
<DeBot>
jhass: false
<jhass>
cool :D
<epitron>
i never knew about that one
<epitron>
i always used File.directory?
<jhass>
dunno if Dir in ruby has it
<jhass>
I should annoy people and port Pathname :P