<wanderer>
so it's always zero initialized? because I wouldn't need the overhead
<jhass>
Pointer.malloc is yes
<jhass>
:: Type is not
<jhass>
Struct#new is neither
<jhass>
and that the later two aren't caused me several headaches already
<jhass>
so I pay that overhead happily and would like to pay it for the later two too
<wanderer>
something like UInt16* is builtin and becomes an instance of the pointer class, correct?
<jhass>
UInt16* is just a shortcut for writing Pointer(UInt16), like String? is a shortcut to String|Nil
asterite has joined #crystal-lang
ismaelga has joined #crystal-lang
<asterite>
Pointer.malloc is a built-in, but we could write in crystal like GC.malloc(sizeof(T)) or something like that, but it's not something we need to do right now
<asterite>
By the way, Struct.new does initialize memory to zero. The only one that doesn't is ::
<wanderer>
when I use `str = GC.malloc_atomic(bufsize.to_u32) as UInt8*` to get a buffer, how can I pass that buffer to a c function that expects a char *?
<wanderer>
with str.address?
<asterite>
str there is a Pointer(UInt8) (or UInt8*, it's the same)
<asterite>
so you pass str directly
<asterite>
char* is UInt8* in crystal
<wanderer>
isn't it actually an object of the class Pointer?
<wanderer>
asterite: ah, information here is in general a little scattered
waj1 has joined #crystal-lang
<shadeslayer>
asterite: curious, is there scope for a inotify class in crystal?
<asterite>
what do you mean with "scope"?
<shadeslayer>
as in, do you reckon it could go into the official repo
* shadeslayer
was thinking of writing a module of sorts
<asterite>
Maybe… I don't know anything about inotify
<asterite>
But you can write it and once its done we can see if it can go in the std
waj has quit [Ping timeout: 245 seconds]
<asterite>
:)
<jhass>
if it goes into stdlib it should at least abstract away OS dependence IMO, inotify vs knotify or what it was called on mac?
<jhass>
eh, not fsevent
<crystal-gh>
[crystal] asterite pushed 1 new commit to master: http://git.io/hWkw
<crystal-gh>
crystal/master 315aaf2 Ary Borenszweig: Fixed #488: Compiler falsely claims type mismatch in method invocation (involves array and union type)
ponga has quit [Remote host closed the connection]
asterite has quit [Quit: Leaving.]
asterite has joined #crystal-lang
<wanderer>
asterite: hi
<asterite>
hi wanderer
<wanderer>
I've got a question: the windows api doesn't support utf8, but only utf16, so much of the string code would look like: `ifdef darwin || linux status = LibC.stat(path, out stat) elsif windows status = LibC.stat(path.to_utf16, out stat) end`
<wanderer>
overwriting `to_unsafe` for windows to always convert to utf16 isn't optimal, though, because there are still external libraries that support utf8, also for converting digits to a string the unicode api isn't needed
<asterite>
Maybe another method, but I don't know what name we can use
<asterite>
It's "utf-16 if windows otherwise self"
<asterite>
We can have String#to_windows_unsafe or something like that
<asterite>
Or maybe to_os_unsafe
<jhass>
String#for_win32 ?
<asterite>
so it would return self for linux and mac, and utf-16 for windows
<wanderer>
it's regular utf16, again not specific to windows
<wanderer>
I wouldn't label those things (stdcall, utf16, ...) with anything like "windows" as they're not specific to it
<jhass>
how about LibC.stat LibC.convert_string(str)
<asterite>
But LibC is a lib, it can't have methods
<asterite>
I think to_os_unsafe is ok… or not?
<jhass>
mh, yeah, just trying to namespace it to the lib
<asterite>
Or just to_os
<wanderer>
asterite: how would it work?
<jhass>
it's essentially library specific, not OS specific
<wanderer>
asterite: there are still ansi versions of the windows api, so they must not convert to utf16
<jhass>
you can view the system calls still as a library
<asterite>
def to_os_unsafe; ifdef windows; to_utf16.to_unsafe; else; to_unsafe; end; end
<jhass>
from the conceptual standpoint
<jhass>
yeah I don't think that's good
<jhass>
that would imply all code on windows behaves that way
<asterite>
But for to_os_unsafe you must invoke it manually, unlike to_unsafe
<jhass>
while it's only the win32 api
<jhass>
so I think scoping it to the library makes more sense than putting it into String
<asterite>
What are the places where utf16 is used?
<wanderer>
float.cr contains LibC.sprintf-calls, those could still be the ansi versions as there won't be any unicode involved
<jhass>
you know what, a perfect place for those conversions would be my wrapper idea
<jhass>
let's have an abstracted OS independent interface for that stuff
<jhass>
and different implementations of it for each platform
<wanderer>
for every winapi func that accepts string there is an ansi version and a wide one
<wanderer>
the ansi version accepts UInt8*, but doesn't understand UTF8
<wanderer>
the wide version uses UInt16* and UTF16
<asterite>
So we should always use the wide one, right?
<wanderer>
one could possibly label utf16 api funcs as @[string(utf16)] which overwrites to_unsafe to to_unsafe_utf16, if something like this is possible
<jhass>
let's stdlib have no clue about platform specifics, wouldn't that be awesome?
<wanderer>
as for the winapi, most likely always the wide-one
<wanderer>
however when using other external libs on windows they might support utf8
<wanderer>
so it's not "if windows then utf16"
ponga has joined #crystal-lang
<jhass>
exactly, and thus String should have no knowledge about it
<jhass>
String shouldn't care about the Win32 API
<jhass>
that's not its job
<wanderer>
yes, either there should be wrappers or the fun itself needs attributes, I guess
<wanderer>
or nothing of this and it gets kind of verbose with something like this: def to_i ifdef darwin || linux LibC.atoi(cstr) elsif windows LibC.atoi(cstr.to_utf16) end end
<asterite>
Or you can use the wrapper idea from jhass, and it becomes LibC.atoi(LibCWrappers.string(self))
<asterite>
Or something like that, the name doesn't matter
<jhass>
conditionally require either wrapper for the platform
<jhass>
one switch in one place
<asterite>
It had everything written twice, in my opinion
<jhass>
and none of stdlib needs platform specifics
<jhass>
and none of the wrappers need to know about other platforms
<asterite>
From what I read, wanderer needs to pass a string as utf8 in linux/mac or utf16 in windows in some places
<jhass>
you're making this too specific
<jhass>
this is a general design problem
<wanderer>
the general design problem is that you're kinda expecting POSIX everywhere
<wanderer>
an overall solution would be a complete wrapper like jhass said or ifdefs in the specific code
<jhass>
asterite: we probably could even stub out the linux and OS x wrappers with macro method_missing
<wanderer>
the thing with the wrapper is, that it would add overhead and is sometimes not even needed, like in to_s in float.cr that uses sprintf which can stay the same on windows like I said, as there is no unicode needed
<jhass>
and have some well placed macro code that generates the boilerplate on windows too
<wanderer>
so a complete wrapper would be a nice solution, but also a kind of bloated one
<jhass>
if llvm won't inline and optimize away single line functions that just pass along the args, I'll loose all my faith in it
<jhass>
the runtime performance shouldn't be affected in most cases
<wanderer>
yes, that's what I was guessing, too
<wanderer>
could come otherwise, though
<asterite>
Yes, llvm will definitely inline those
<asterite>
and in non-release mode the performance hurt will be very minor
<jhass>
so I think I made my point clear enough by now, there's not much point in further discussing, asterite and waj have to decide
<wanderer>
what about something like @[uses_utf16_string] fun atoi(str : UInt16*) that makes strings use to_unsafe_utf16 rather than to_unsafe?
<jhass>
if you want to litter stdlib with platform specific code and tons of ifdefs, go ahead
<jhass>
I just would find that very very sad approach, but that's just my opinion
<wanderer>
jhass: that was my argument yesterday, too, remember? :D
<asterite>
I don't want to add an attribute just for this specific case
<asterite>
Specially not if it can be done with what we have right now
<wanderer>
however
<wanderer>
I guess a problem with having a complete wrapper is the naming
<wanderer>
for example printf only accepts ansi while wprintf uses utf16, if the func is now called CWrapper.printf and on windows it uses wprintf to emulate utf8 support
<wanderer>
then how would the actual ansi func be called if needed?
<jhass>
wanderer: LibC.printf and then that application code would become platform dependent
<jhass>
it would be anyhow since there's no such distinction on other platforms
<jhass>
so the only cases where it's needed, is already platform dependent
<wanderer>
sorry, don't get what you mean atm
<jhass>
there's no wprintf on other platforms, is there?
<wanderer>
there is
<wanderer>
it's c standard
<jhass>
god
<wanderer>
there's a difference between c standard and posix standard
<jhass>
I hate posix
<jhass>
and C
<wanderer>
linux however uses utf8 so there no much use to wprintf
<wanderer>
also on linux wprintf uses utf32, while on windows wprintf uses utf16
<jhass>
I think my point still holds though
<jhass>
if you need to care about these differences, your code is already inherently platform dependent
Ven has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<jhass>
so you can just bypass the wrapper without loosing anything
<wanderer>
on windows there is atoi (ansi) and wtoi (utf16, windows specific)
<jhass>
that defies my point how?
<wanderer>
I still didn't get how you would solve this
<wanderer>
you could make atoi on windows use wtoi, so you just have CWrappers.atoi, but that hides the actual atoi on windows
<wanderer>
please explain your solution later again for me, gotta go
<wanderer>
bye
wanderer has quit [Quit: Page closed]
<asterite>
I think using an ifdef is simpler :)
<asterite>
Once we get to the point of having 100 ifdef, then we can have a better idea of how to refactor
<asterite>
I don't understand why is he concerned with hiding "atoi" or something like that :(
<jhass>
asterite: honestly, we will get to that point
<jhass>
you're only increasing the pain of implementing a proper design by delaying it
<jhass>
both of you think in specific
<jhass>
s
<jhass>
this is wrong
<jhass>
it's a general design problem
<asterite>
How do they solve this in ruby?
<jhass>
which function behaves how is completely irrelevant
<jhass>
tons of littered ifdefs
<jhass>
it's horrible to read
<jhass>
+ a good deal of defines and stuff
<asterite>
But 'amount of ruby users vs. amount of ruby core developers is huge
<asterite>
I also think your wrapper idea is ok, I don't know why wanderer doesn't like it
<asterite>
It adds a small overhead, but it doesn't matter because you will ship code built in release mode anyway
<asterite>
And we could even improve the compiler to inline such calls even in non-release mode
leafybasil has quit [Remote host closed the connection]
leafybasil has joined #crystal-lang
leafybasil has quit [Remote host closed the connection]
ponga has joined #crystal-lang
eli-se has quit [Quit: Leaving...]
ponga has quit [Ping timeout: 244 seconds]
havenn is now known as havenwood
weskinner_work has quit [Remote host closed the connection]
weskinner_work has joined #crystal-lang
eli-se has joined #crystal-lang
sferik has joined #crystal-lang
leafybasil has joined #crystal-lang
leafybasil has quit [Ping timeout: 252 seconds]
bcardiff has joined #crystal-lang
bcardiff has quit [Quit: Leaving.]
bcardiff has joined #crystal-lang
sferik has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
bcardiff has quit [Quit: Leaving.]
ponga has joined #crystal-lang
sferik has joined #crystal-lang
leafybasil has joined #crystal-lang
<havenwood>
I've always thought it was odd that Ruby's #each_with_index wasn't named #map_with_index. And the same with #each_with_object, #each_slice, etcetera. It seems like the #each versions should return the receiver, or an Enumerator if no block is given--like #each.
<jhass>
#map should return the block return values though, not some argument
<jhass>
and also .each_with_object(some_expensive_method_call) {|item, i_saved_an_external_local_and_a_closure| item.process i_saved... } is a valid usecase
<havenwood>
jhass: well, it makes more sense to me for map to be mapping to a provided object than for each to be mapping to anything
<jhass>
dunno, I don't think about them like mapping
<havenwood>
jhass: aren't they more mapping than each? or do you think not?
<jhass>
more like efficient versions of .slices(3).each, .with_object(x).each etc
<havenwood>
i guess that's the logic, each.with_index
<wanderer>
jhass: yes, you would actually need to create a new low level api that gets then implemented for linux, mac, windows and maybe more, with that api being not bound to any particular system like posix
<jhass>
exactly
<wanderer>
I then wouldn't call it CWrapper as it would be more of a crystal_low_level_api
<wanderer>
also if you go as far as coming up with a system/low level api to abstract away the actual OS, you would first need an intersection set
weskinner_work has quit [Ping timeout: 246 seconds]
<wanderer>
e.g. LibC.fork would reside outside of that low level api as fork() is not in such subset
<wanderer>
it'd be the nicest solution, but requires putting work into coming up with a sane api construct, ruby itself seems to use detours or have ifdefs in its functions like D and Nim
<wanderer>
simply like `def xyz; ifdef darwin || linux; stat(...); elsif windows; GetFileAttributes(...); end; end;`
<jhass>
yes, and I find this increasingly hard to read
<jhass>
I'm not sure if you really need to design the complete API upfront
<wanderer>
it is, both approaches have their pros and cons
<jhass>
you would do the ifdef stuff as you go too
<jhass>
so why not add the wrappers as needed
<wanderer>
one could also add an attribute that overwrites the to_unsafe like @[new_unsafe=to_unsafe_utf16] and if arguments passed to that fun have a method called to_unsafe_utf16, it is then called instead, this would reduce ifdefs when linux and windows share the same codebase which goes for the complete c standard routines
waj1 has quit [Quit: Leaving.]
<wanderer>
wait, no this is bad as it would introduce the problem I mentioned earlier with shadowing the windows ansi functions. for sharing the same codebase, the funs also have to have the same names, so it needs to be LibC.atoi on linux and on Windows, while on Windows it would need to be fun atoi = _wtoi, so both calls would look the same, then however, the ansi atoi on windows is shadowed
<jhass>
wanderer: you can bind them in the platform specific files instead
<wanderer>
jhass: I meant my suggested approach just now is bugged
<jhass>
oh, sorry
<wanderer>
when you have a wrapper this wouldn't be a problem
<jhass>
was following another channel and didn't read up, sorry
weskinner_work has joined #crystal-lang
<wanderer>
being able to overwrite the to_unsafe method would be handy, though, when defining utf16 functions for windows or some other platform, everytime you call them with a string you'd need to invoke .to_utf16, it'd be convenient if there was a way to automate this
<wanderer>
on per fun basis
<jhass>
macro utf16_wrapper name; def {{name.id}}(arg); LibC.{{name.id}}(arg.to_utf16); end; end; + proper argument handling but you get the idea
weskinner_work has quit [Ping timeout: 244 seconds]