jhass changed the topic of #crystal-lang to: The Crystal programming language | http://crystal-lang.org | Crystal 0.5.8 | Paste > 3 lines of text to https://gist.github.com | GH: https://github.com/manastech/crystal - Docs: http://crystal-lang.org/docs/ - API: http://crystal-lang.org/api/ - Logs: http://irclog.whitequark.org/crystal-lang
<jhass> >> class Foo; end; Foo.allocate
<DeBot> jhass: #<Foo:0x80EDFF8>
<jhass> >> class Foo; end; Foo.class.allocate
<DeBot> jhass: Error in line 3: undefined method 'allocate' for Class
<jhass> >> class Foo; end; Foo.class.new
<DeBot> jhass: Error in line 3: can't instantiate abstract class Class
<jhass> >> class Foo; end; (nil || Foo).new
<DeBot> jhass: #<Foo:0x8EB6FF8>
waj has quit [Quit: Leaving.]
waj has joined #crystal-lang
r20 has quit [Quit: Leaving]
<crystal-gh> [crystal] waj pushed 1 new commit to master: http://git.io/bHkv
<crystal-gh> crystal/master 14a412a Juan Wajnerman: Fix debug info to pass LLVM assertions (fixes #257)
<travis-ci> manastech/crystal#1944 (master - 14a412a : Juan Wajnerman): The build passed.
bcardiff has joined #crystal-lang
bcardiff has quit [Ping timeout: 245 seconds]
bcardiff has joined #crystal-lang
<crystal-gh> [crystal] asterite pushed 1 new commit to master: http://git.io/bHsI
<crystal-gh> crystal/master bf9c03d Ary Borenszweig: Optimized String#rjust and String#ljust
<travis-ci> manastech/crystal#1945 (master - bf9c03d : Ary Borenszweig): The build passed.
r20 has joined #crystal-lang
r20 has quit [Quit: Leaving]
waj has quit [Quit: Leaving.]
tmoore has quit [Write error: Connection reset by peer]
tmoore has joined #crystal-lang
tmoore has joined #crystal-lang
tmoore has quit [Changing host]
bcardiff has quit [Quit: Leaving.]
tmoore has quit [Read error: Connection reset by peer]
tmoore has joined #crystal-lang
tymat has quit [Quit: PRISM - We know everything!]
asterite has joined #crystal-lang
<asterite> >> "Heeeeey Jhaßßßßßßßßßß!".squeeze
<DeBot> asterite: "Hey Jhaß!"
<asterite> jhass: whenever you have some time, can you try this in any of your linuxes, in crystal's directory? https://gist.github.com/asterite/7064f52fc371ec7299a7
<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> Could you also try this? https://gist.github.com/asterite/993519d1120186f7da9b (it prints name 0 all over the place :-()
<asterite> I don't know what's ROP
<asterite> Mmm... and why is this is important?
<jhass> so in order to do that the object files need to be relocatable
<jhass> Return oriented programming, it's when you can't inject your own code well but can control program flow to some degree
<asterite> Is the "hardening process" that thing that happened to epitron?
<asterite> (or... I can't remember the name, he had like some bin wrapper)
<jhass> so you make the program do what you want by rearranging the existing code
<jhass> (on the assembler level)
<jhass> which is a lot easier if the jump addresses are static
<jhass> yeah, that's how I noticed it
<asterite> I'm search "llvm fpic fpie" on google but can't find anything relevant except "thread sanitizer" for llvm 3.7
<jhass> llvm calls it relocatable or so
<jhass> asterite: that C programs output looks fine to me too
<asterite> I guess we can't rely on dirent d_type though: http://www.linuxquestions.org/questions/programming-9/d_type-in-struct-dirent-374/
<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
<jhass> yup
<asterite> Like, a friend of mine was trying to port this: https://github.com/steveklabnik/frappuccino
<jhass> that's why I'm leaning towards 2) ;)
<asterite> But that uses too much magic, so I told him it would not be a very motivating experience to try to do that :-P
<asterite> Ok, so 2 is not that bad :)
<asterite> The only thing is that "foo".includes?("o") makes sense
<asterite> array.includes?(1) makes sense
<asterite> But sometimes you have elements.includes?(1), which is "wrong"
<asterite> I think that's the reason it's called "include?" in Ruby
<asterite> There's also foo.is_a?(Object), which could also be foo.is_an?(Object)
<asterite> (a friend of mine adds that alias in almost every project of us :-P)
<jhass> yeah, the thing to do is to define a strict rule that actually doesn't think much about "reads nice"
<asterite> Maybe the language should understand English and let you use both
<asterite> Or we can rewrite everything to Esperanto
<jhass> like, "methods ending in ? must: 1) return true or false, 2) be a single word, 3) be the singular infinitive of that word"
<jhass> or whatever the grammatical term was
<jhass> I suck at grammar :P
<jhass> also esperanto is just spanish, if anything lojban :P
<asterite> lol
<asterite> Yes, for spanish speakers it's easy, I guess... well, any latin-based language, really
<asterite> For "?" methods we have two meanings right now: returns a Bool, or returns something nilable where the non-? would raise
<jhass> yeah
<jhass> I actually wonder if dropping thing like Hash#has_key? would make sense, in favor of Has#[]?
<jhass> mmh, actually it doesn't
<jhass> since you want false/nil as valid values
<asterite> Well, as long as you are just testing, it works
<asterite> But I think has_key? could be slightly faster, not sure
<asterite> I think Matz also regrets the many $ magic variables
<asterite> I'm trying to convince waj we should drop them, but he likes them
<asterite> He wants to think of a way to making them work by not using globals... like, they are defined somehow in the local method
<asterite> but I think that would be too much of a change to the language, and it adds more rules
<jhass> yeah, there's weird magical stuff in Ruby beyond them too
<jhass> like if you call Regexp#=~ inside an if and the regexp has named groups, those become available as local variables inside the if
<jhass> that only works with Regexp#=~ inside an if, not outside an if and not for String#=~
<jhass> please don't repeat such stuff :P
<asterite> Yes, I recently discovered that and found it too magical for my taste
<asterite> I think the parser does that transformation
waj has joined #crystal-lang
bcardiff has joined #crystal-lang
<asterite> Yay, with that Dir change I have specs passing in linux 32 bits :-)
<jhass> asterite: mmh, maybe we should link an IRC webchat from the homepage?
jhass_kiwi has joined #crystal-lang
<asterite> I think we are missing lots of links, and having them in the form of icons doesn't help a lot
<jhass> yeah
<asterite> jhass: so DeBot is running in 32 bits?
<jhass> yup
<epitron> asterite: I really like the way Dir.list returns the type of each file
<epitron> It makes high performance directory scanning easy
<epitron> Calling dir? a million times kills it
<epitron> (In ruby at least)
<asterite> epitron: I know. But do you know a portable way to do this?
<asterite> We were using dirent's d_type, but that returned 0 for me in some linuxes
<epitron> Msys2!
<asterite> and it is documented as not being available sometimes
<epitron> Orly
<epitron> That's surprising
<epitron> Well, I guess lstating every file could be the fallback
<jhass> yeah posix is great sometimes
<jhass> "So, this exists, but it won't work everywhere, so don't use it"
<asterite> Use "d_name", but don't use anything else if you want portability :-P
<epitron> jhass: haha... Yes... Such a disappointing attitude
<epitron> So lazy
<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
<epitron> Wait
<asterite> It seems we are not the only ones: http://notmuchmail.org/pipermail/notmuch/2010/001170.html
<epitron> Can't you tell whether it's a file or dir from the trailing slash?
<jhass> uhm
<jhass> no
<epitron> Ruby's Dir[] does that
<crystal-gh> [crystal] asterite pushed 1 new commit to master: http://git.io/b7Xf
<crystal-gh> crystal/master bac37a6 Ary Borenszweig: Fixed Dir::entries
<epitron> Yeah... I guess ruby just stats like crazy
<jhass> it does
<jhass> the reason why require (and thus bootup) is so slow btw
<epitron> Haha
<jhass> the recent speedups in ruby startup by 90% came from reducing the amount of stats done doing a require
<epitron> Ruby's startup is insane
<epitron> Yep
<epitron> I've been complaining about that for years
<epitron> The stat pyramid, I used to call it
<epitron> Where open would stat every directory in the path
<epitron> Glad they finally got around to fixing that
<travis-ci> manastech/crystal#1947 (master - bac37a6 : Ary Borenszweig): The build passed.
<asterite> jhass: I saw your String.class.name. For the class model we are still lacking some things... :(
<jhass> in the end I wanted the .to_s anyway
<asterite> Yes, but even with that, we need to define and finish implementing the meta-model
<jhass> a good thing to have would be a generalized not_nil! I think
<jhass> foo = String.ensure foo
<jhass> or .assert or so
<jhass> not sure about the name
<asterite> `foo = foo as String` doesn't work?
<jhass> I want a runtime assertion like not_nil!, not a cast
<asterite> >> (1 || "a") as String
<DeBot> asterite: #{e.class}: cast to String failed
<asterite> >> (("a" || 1) as String).length
<DeBot> asterite: 1
<asterite> `as` does a cast with a runtime check
<jhass> oh? mmh
<asterite> `as` also works on pointers types. If you cast from or to a pointer type, there's no runtime check
<asterite> As most other things, it's in the manual (those 30_000 lines of compiler code :-P)
<asterite> (in other words: it's not documented)
<jhass> I still have no real nice idea on how to design the gobject/gtk wrapper code
<jhass> I'd like to retain the pointer types on the library bindings, like gtk_window_set_title(this : Window*)
<jhass> but since things like Window have many child classes
<jhass> the Window#to_unsafe becomes a huge union of all the pointer types
<asterite> Oh, I changed your sample to use a real closure and it worked well :)
<jhass> yeah, I actually tried that ;)
<asterite> I also added Button#label=, but I had to do: LibGtk.button_set_label (@ptr as Pointer(LibGtk::Button)), label
<asterite> Is that what you mean? Those cast would be in every subclass, I guess
<jhass> yeah, atm I'm as far as just keeping it typed Void* in the wrapper and cast it on every call
<jhass> some oddities in gtk aren't helping with this either
<jhass> like gtk_window_new returns a Widget* not a Window*
<asterite> Yes, that's a closure because it accesses info, info_text and name from above
<jhass> thought so ;)
<asterite> I guess I'm also baffled that sending pointer and closure_data to gobject is all that's needed for that to work :)
<jhass> it simply is baffling. It's declared as fact now. Period
<jhass> :P
weskinner has joined #crystal-lang
<asterite> I'm loving the tone. "I'm surprised it's not already implemented"
<weskinner> does any documentation exist for crystal deps?
<asterite> weskinner: no
<asterite> mostly because it's not truly defined yet
jhass_kiwi has quit [Quit: http://www.kiwiirc.com/ - A hand crafted IRC client]
<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
<epitron> i made a better pathname! :D
<epitron> hmm.. stat.cr looks like it could be prettier
<epitron> the old Dir had an "enum Type : UInt8" with nice names for the modes
<epitron> Stat has a bunch of ugly unix constants
<epitron> S_IFIFO
<epitron> S_IFBLK
<epitron> S_IFLNK
<epitron> oh wait
<epitron> i see.. there's a mask
<epitron> (@stat.st_mode & LibC::S_IFMT) == LibC::S_IFDIR
<epitron> those stat methods are really wet
<epitron> >> File::Stat.new("/etc/passwd")
<DeBot> epitron: #<File::Stat:0x8C29F70 @stat=LibC::Stat(@st_dev=2049, @__pad1=0, @st_ino=1341923, @st_mode=33188, @st_nlink=1, @st_uid=0, @st_gid=0, @st_rdev=0, @__pad2=0, @st_size=775, @st_blksize=4096, @st_blocks=8, @st_atimespec=LibC::TimeSpec(@tv_sec=1423344683, @tv_nsec=810000000), @st_mtimespec=LibC::TimeSpec(@tv_sec=1422230628, @tv_nsec=200000000), @st_ctim ...
<epitron> that's not working on head for some reason
weskinner has quit [Ping timeout: 246 seconds]
<epitron> this is weird too --
<epitron> def self.stat(path)
<epitron> if LibC.stat(path, out stat) != 0
<epitron> raise Errno.new("Unable to get stat for '#{path}'")
<epitron> end
<epitron> Stat.new(path)
<epitron> end
<epitron> stat's initialize:
<epitron> def initialize(filename : String)
<epitron> if LibC.stat(filename, out @stat) != 0
<epitron> raise Errno.new("Unable to get stat for '#{filename}'")
<epitron> end
<epitron> end
<epitron> double stats!
<epitron> (that first one is File.stat)
<epitron> in /home/epi/code/crystal/src/file/stat.cr:122: no overload matches 'Time#initialize' with types LibC::TimeSpec
<epitron> :\
<epitron> oh, maybe i need to rebuild crystal
<epitron> hmm.. wasn't that
<epitron> ah, i see why you have redundant error handlers for stat -- you need to say "lstat" and "stat" :)
zamith has quit [Quit: Be back later ...]
<epitron> heh
<epitron> yeah, i like your idea of totally rewriting this API
<epitron> something that wraps file/dir/stat
<epitron> language syntactic sugar for files would be awesome too
<jhass> like?
<epitron> i dunno
<jhass> I don't like too much magic in the language
<epitron> file = ./filename.rb ?
<epitron> well, files are something you use so often
<jhass> still
<epitron> %f{filename}
<epitron> that could create a Path object
<jhass> I find file = File.read "./filename.rb" much easier to understand actually
<epitron> what if you had to change the extensions of all the files in a directory?
<epitron> :)
<jhass> see, I didn't even understand that you wouldn't read t he file contents with that or make an IO for it or whatever
<epitron> %f{*.file}.each { |f| f.rname_to(ext: "newext") }
<jhass> so, I agree with maybe dropping Dir/File in favor of something like Pathname/Path
<epitron> *rename
<jhass> but syntax? no
<epitron> dropping Dir/File would make porting irritating
<epitron> replacing thousands of "Dir/File"s :)
<epitron> maybe there should be a "require 'ruby_compat'"
<jhass> well
<jhass> >> ["foo"].include?("bar")
<DeBot> jhass: Error in line 3: undefined method 'include?' for Array(String) (did you mean 'includes?'?)
<epitron> >> "bar".in? ["foo"]
<DeBot> epitron: Error in line 3: undefined method 'in?' for String
<jhass> I don't think you really can port much Ruby and I don't think it should be the language goal
waj has joined #crystal-lang
<epitron> Object#in? is something iadded a long time ago :)
<epitron> *the* goal, no :)
<epitron> but i mean, you've already written File/Dir
<epitron> instead of nuking them, you could just throw them in a "ruby_compat" dir
<epitron> i'm sure some people will find them helpful
<jhass> I also think maintaining too much in stdlib is wrong
<jhass> sounds like a perfect library for those that want it
<jhass> like ActiveSupport in Ruby
<jhass> epitron/crystal-ruby_compat
<jhass> go for it!
<epitron> haha
<epitron> how do you add libs into crystal? do you add 'em to your path?
<epitron> oh wait, there's shards, right?
<jhass> there's this Projectfile thingy that goes together with crystal deps command and currently just pulls github repos
<epitron> i see
<epitron> go style
<jhass> I didn't look into it
<jhass> we're still debating how to call them, but currently it looks like it's going to be shards, yeah ;)
<epitron> i like shards too
<epitron> anyhow, think about %f{} :)
<epitron> it would be awesome if you could extend the language's %-strings with your own methods
<epitron> %html{ }
<epitron> %shell_escaped{ }
<epitron> %glob{*}
<epitron> anyhow, at the very least, strings should have a #to_path
<jhass> yeah and then hundreds of shards do that and we get tons of conflicts
<epitron> i doubt that would happen
<epitron> gems can monkeypatch everything in ruby
<epitron> people don't do it that often
<epitron> it's nice for DSL programming, for example
<epitron> %mydsl { ... }
<epitron> %shader{ }
<jhass> I think you can go pretty far with what's there currently
<jhass> let's try to work with it for a while
<epitron> ok :)
<epitron> i'll try to come up with more good examples
<epitron> it's a great time to think about these things
<epitron> you don't have a lot of legacy stuff and the userbase is tiny
<jhass> yeah
<jhass> so it's good to not adopt rubys mistakes
<jhass> doesn't mean we shouldn't be careful about not making new ones ;)
<epitron> i agree
<epitron> i also know that first-class syntactic things make langauges awesome
<epitron> like regexes
<epitron> compare python regexes to ruby regexes :)
<epitron> i'm thinking of something along those lines for files
zamith has joined #crystal-lang
weskinner has joined #crystal-lang
waj has quit [Quit: Leaving.]