<thelema>
some sort of optimization is going on here - you're using SML, right?
<c0m>
see, flatten2 .. which is a right fold performed better
<c0m>
sml?
<c0m>
standard ml
<c0m>
f#
<thelema>
yes
<thelema>
ok...
<thelema>
hmm, try it with (+) or something where the size of the arguments isn't important
<thelema>
for (@), the cost is proportional to the size of the first argument
<c0m>
ok
<thelema>
with foldback, the first argument always has size 1
<thelema>
but with fold, it has size n
<thelema>
thus the n^2 vs n that you're seeing
<c0m>
hmm
<c0m>
is (@) proportional to size of first argument with respect to fold
<c0m>
or for all instances
<thelema>
think about concatenating immutable linked lists.
<thelema>
even concatenating mutable ones where you only have head pointers
<thelema>
you have to run through the first list to find its last element. In the immutable case, you recurse back, prepending each element to the second list
<c0m>
mmkay
<thelema>
in the mutable case, you do a pointer assignment
<thelema>
in either case, O(n)
<c0m>
foldback
<c0m>
the first argument doesn't have size n
<c0m>
first argument is cs
<c0m>
sorry ... xs
<c0m>
err
<c0m>
i meant it doesn't have size 1
<c0m>
so, rephrasing correctly .... foldback doesn't have first argument as size 1 it is size n
<thelema>
hmmm...
<c0m>
for xs
<c0m>
right?
<c0m>
fold's first argument for (@) is size 1
<thelema>
hmm, maybe something is backwards here...
<c0m>
or 0, depending on how you look at it
<thelema>
still, do you get the same behavior doing + or * or something commutative?
caligula__ has joined #ocaml
<c0m>
haven't tried
<c0m>
let me do that now
<c0m>
its messing up on the types
<c0m>
this is one of the reasons why I'm not a huge fan
<c0m>
i understand for being more concise and all but i think there's a point where it can be viewed as being too ambiguous without it being explicitly written out
<c0m>
for types, etc
<c0m>
maybe its just me not being a 100% pro at type inference
<c0m>
ok got it
ulfdoz has joined #ocaml
<thelema>
you'll get used to it.
<c0m>
the addition ... the differences between each are negligible
<thelema>
so there's something about @ that works differently between the two cases.
tab has quit [zelazny.freenode.net irc.freenode.net]
mbac has quit [zelazny.freenode.net irc.freenode.net]
rbancroft has quit [zelazny.freenode.net irc.freenode.net]
mattiase has quit [zelazny.freenode.net irc.freenode.net]
willb has quit [zelazny.freenode.net irc.freenode.net]
gim has quit [zelazny.freenode.net irc.freenode.net]
mattiase has joined #ocaml
willb has joined #ocaml
rbancroft has joined #ocaml
gim has joined #ocaml
mbac has joined #ocaml
tab has joined #ocaml
<c0m>
don't think so because correct sum is being generated
<thelema>
you need to run them both long enough that you're not measuring noise
<c0m>
i have
<c0m>
ran them like 10 times each
<c0m>
could run them more but they've been averaging very low times
<c0m>
so probability of it varying from that seems very low
<thelema>
yes, but to compare runtimes you need more accurate figures
<thelema>
other than the very rough comparison, "they run about the same"
<c0m>
If xs has length n and ys has length m, then notice that we get a total of n+1 invocations. And each of these invocations again does O(1) work. So in total the running time is O(n). In other words, xs @ ys takes time proportional to the length of xs but independent of the length of ys. This asymmetry is very important to keep in mind when you use @.
<c0m>
professor has that in his notes
caligula_ has quit [Success]
<thelema>
yup, that's what i said
<c0m>
so i think you're onto something
<c0m>
oh wait
<c0m>
foldback does it to the right
<c0m>
and [] is the argument on the right
<c0m>
so the first argument, generally speaking, has been flipped to the other side
<c0m>
!
<c0m>
right?
<c0m>
so although foldback (@) xs [] has xs being the first argument, foldback, in a sense, reverses it
<thelema>
no, foldBack is fold_right in ocaml
<c0m>
no, i know
<thelema>
val fold_left : ('a -> 'b -> 'a) -> 'a -> 'b list -> 'a
<thelema>
List.fold_left f a [b1; ...; bn] is f (... (f (f a b1) b2) ...) bn.
<thelema>
val fold_right : ('a -> 'b -> 'b) -> 'a list -> 'b -> 'b
<thelema>
List.fold_right f [a1; ...; an] b is f a1 (f a2 (... (f an b) ...)). Not tail-recursive.
<c0m>
hmm
<c0m>
do you understand what i'm saying
<thelema>
yes, but I think it's incorrect based on what I know of ocaml.
<c0m>
what else could explain this?
<thelema>
also, (@) doesn't work for fold in ocaml, unless you're starting with a list of lists
<c0m>
well i've created a list of lists
<c0m>
code example in pastebin shows it
<thelema>
ok.
<c0m>
anyway, i'll think about it some more
* thelema
just looked at the fold bits
<c0m>
thanks for your time and your insight
<c0m>
going to head off for now!
<c0m>
nighty night
<thelema>
cheers
julm has quit [Read error: 60 (Operation timed out)]
palomer has quit [Remote closed the connection]
ulfdoz has quit [Read error: 110 (Connection timed out)]
ccasin has quit ["Leaving"]
ygrek has joined #ocaml
Yoric[DT] has joined #ocaml
ttamttam has joined #ocaml
caligula_ has joined #ocaml
caligula__ has quit [Read error: 60 (Operation timed out)]
onigiri has quit []
mishok13 has joined #ocaml
julm has joined #ocaml
_zack has joined #ocaml
fremo has quit [Remote closed the connection]
fremo has joined #ocaml
thrasibule has quit [Read error: 110 (Connection timed out)]
fremo is now known as Guest94649
ikaros has joined #ocaml
Submarine has joined #ocaml
Yoric[DT] has quit ["Ex-Chat"]
Associat0r has joined #ocaml
deavid has quit [Read error: 104 (Connection reset by peer)]
Associat0r has quit []
deavid has joined #ocaml
ikaros has quit ["Leave the magic to Houdini"]
struktured has quit [Read error: 110 (Connection timed out)]
munga_ has joined #ocaml
verte has joined #ocaml
th5 has joined #ocaml
reid97 has quit [Read error: 110 (Connection timed out)]
reid96 has joined #ocaml
_zack has quit ["Leaving."]
kaustuv has quit [Read error: 110 (Connection timed out)]
animist has quit [Read error: 60 (Operation timed out)]
gildor has quit [zelazny.freenode.net irc.freenode.net]
patronus_ has quit [zelazny.freenode.net irc.freenode.net]
gildor has joined #ocaml
patronus_ has joined #ocaml
valross has quit [Remote closed the connection]
gildor has quit [zelazny.freenode.net irc.freenode.net]
patronus_ has quit [zelazny.freenode.net irc.freenode.net]
gildor has joined #ocaml
patronus_ has joined #ocaml
gildor has quit [zelazny.freenode.net irc.freenode.net]
patronus_ has quit [zelazny.freenode.net irc.freenode.net]
gildor has joined #ocaml
patronus_ has joined #ocaml
gildor has quit [zelazny.freenode.net irc.freenode.net]
patronus_ has quit [zelazny.freenode.net irc.freenode.net]
gildor has joined #ocaml
patronus_ has joined #ocaml
valross has joined #ocaml
gildor has quit [zelazny.freenode.net irc.freenode.net]
patronus_ has quit [zelazny.freenode.net irc.freenode.net]
fremo has joined #ocaml
gildor has joined #ocaml
patronus_ has joined #ocaml
fremo is now known as Guest5618
gildor has quit [zelazny.freenode.net irc.freenode.net]
patronus_ has quit [zelazny.freenode.net irc.freenode.net]
gildor has joined #ocaml
patronus_ has joined #ocaml
Snark has joined #ocaml
_zack has joined #ocaml
gildor has quit [zelazny.freenode.net irc.freenode.net]
patronus_ has quit [zelazny.freenode.net irc.freenode.net]
gildor has joined #ocaml
patronus_ has joined #ocaml
gildor has quit [zelazny.freenode.net irc.freenode.net]
patronus_ has quit [zelazny.freenode.net irc.freenode.net]
gildor has joined #ocaml
patronus_ has joined #ocaml
gildor has quit [zelazny.freenode.net irc.freenode.net]
patronus_ has quit [zelazny.freenode.net irc.freenode.net]
gildor has joined #ocaml
patronus_ has joined #ocaml
gildor has quit [zelazny.freenode.net irc.freenode.net]
patronus_ has quit [zelazny.freenode.net irc.freenode.net]
Guest94649 has quit [Read error: 110 (Connection timed out)]
gildor has joined #ocaml
patronus_ has joined #ocaml
gildor has quit [zelazny.freenode.net irc.freenode.net]
patronus_ has quit [zelazny.freenode.net irc.freenode.net]
gildor has joined #ocaml
patronus_ has joined #ocaml
gildor has quit [zelazny.freenode.net irc.freenode.net]
patronus_ has quit [zelazny.freenode.net irc.freenode.net]
gildor has joined #ocaml
patronus_ has joined #ocaml
gildor has quit [zelazny.freenode.net irc.freenode.net]
patronus_ has quit [zelazny.freenode.net irc.freenode.net]
gildor has joined #ocaml
patronus_ has joined #ocaml
gildor has quit [zelazny.freenode.net irc.freenode.net]
patronus_ has quit [zelazny.freenode.net irc.freenode.net]
gildor has joined #ocaml
patronus_ has joined #ocaml
gildor has quit [zelazny.freenode.net irc.freenode.net]
patronus_ has quit [zelazny.freenode.net irc.freenode.net]
gildor has joined #ocaml
patronus_ has joined #ocaml
gildor has quit [zelazny.freenode.net irc.freenode.net]
patronus_ has quit [zelazny.freenode.net irc.freenode.net]
Alpounet has quit [No route to host]
gildor has joined #ocaml
patronus_ has joined #ocaml
gildor has quit [zelazny.freenode.net irc.freenode.net]
patronus_ has quit [zelazny.freenode.net irc.freenode.net]
gildor has joined #ocaml
patronus_ has joined #ocaml
gildor has quit [zelazny.freenode.net irc.freenode.net]
patronus_ has quit [zelazny.freenode.net irc.freenode.net]
gildor has joined #ocaml
patronus_ has joined #ocaml
_zack has quit ["Leaving."]
gildor has quit [zelazny.freenode.net irc.freenode.net]
patronus_ has quit [zelazny.freenode.net irc.freenode.net]
gildor has joined #ocaml
patronus_ has joined #ocaml
gildor has quit [zelazny.freenode.net irc.freenode.net]
patronus_ has quit [zelazny.freenode.net irc.freenode.net]
gildor has joined #ocaml
patronus_ has joined #ocaml
gildor has quit [zelazny.freenode.net irc.freenode.net]
patronus_ has quit [zelazny.freenode.net irc.freenode.net]
gildor has joined #ocaml
patronus_ has joined #ocaml
gildor has quit [zelazny.freenode.net irc.freenode.net]
patronus_ has quit [zelazny.freenode.net irc.freenode.net]
patronus has joined #ocaml
gildor has joined #ocaml
kaustuv has joined #ocaml
_andre has joined #ocaml
valross has quit ["Ex-Chat"]
albacker has joined #ocaml
_zack has joined #ocaml
det has quit [Read error: 60 (Operation timed out)]
det has joined #ocaml
kaustuv has quit [Read error: 60 (Operation timed out)]
seanmcl has joined #ocaml
kaustuv has joined #ocaml
seanmcl has quit []
seanmcl has joined #ocaml
ygrek has quit [Remote closed the connection]
ztfw has joined #ocaml
kaustuv has quit [Remote closed the connection]
Alpounet has joined #ocaml
Alpounet has quit [Read error: 60 (Operation timed out)]
Alpounet has joined #ocaml
_unK has joined #ocaml
<c0m>
anyone have a matrix multiplication, for n x m and m x p generating a n x p matrix, function?
kaustuv has joined #ocaml
<thelema>
c0m: very easy to write in different ways. using 3 for loops or two Array.init and a fold
<mrvn>
or divide and conquer for larger dimensions than 4.
<mrvn>
You can also init the resulting matix with dot products of the row and column vectors of the input matrixes or write out all the terms by hand.
<c0m>
yeah
<c0m>
not looking for iterative techniques
<mrvn>
fixed n,m,p?
ztfw has quit [Read error: 60 (Operation timed out)]
ztfw has joined #ocaml
<c0m>
Given an m-by-n matrix A and an n-by-p matrix B, the product of A and B is an m-by-p matrix whose entry in position (i,j) is the inner product of row i of A with column j of B
<thelema>
mrvn: homework, probably
<c0m>
yeah, homework
<mrvn>
fixed n,m,p?
<c0m>
what do you mean
<mrvn>
Is the homework to write this for 3x4 * 4x3 matrixes?
<mrvn>
or for any n, m, p?
<c0m>
Given an m-by-n matrix A and an n-by-p matrix B
<c0m>
so any m n p
<c0m>
Hint: Use inner and transpose and List.map.
<mrvn>
Then write a functions to get a row and collumn vector out of a x*y matrix, a dot product for 2 vectors and then init the resulting matrix with that.
<mrvn>
oeh, your matrixes are lists of lists of float?
<c0m>
Write an uncurried F# function to do matrix multiplication: > multiply ([[1;2;3];[4;5;6]], [[0;1];[3;2];[1;2]]);; val it : int list list = [[9; 11]; [21; 26]]
<c0m>
list of lists of ints
<thelema>
list matrices! wow
<mrvn>
Well, then yes. transpose one matrix because you can only get row vectors out of the list and not column vectors.
<c0m>
thelema: why wow?
<thelema>
not efficient
<thelema>
especially for multiplication
<c0m>
yeah but i think it is for us to understand the conceptuals of f#
<c0m>
and blah blah
<c0m>
not only f#, but functional programming and recursion in general
<thelema>
just an unusual way to do matrices
<mrvn>
unusual example for lists.
<c0m>
he gave us an interpreter problem which he wanted us to come up with a formula for the end answer
<c0m>
An interesting higher-order function is twice, which can be defined by > let twice f = (fun x -> f (f x));; If we also define > let successor n = n+1;; then we can evaluate expressions like > (twice (twice (twice (twice successor)))) 0;; It is pretty easy to see that with k occurrences of twice, these expressions will return 2k. Remarkably, F# also allows us to evaluate expressions like...
<c0m>
...twice twice twice twice successor 0 in which the function applications are associated to the left, by F#'s default parsing conventions. (Notice that this means that twice gets applied to itself!) Can you figure out a formula that gives the value when there are k occurrences of twice?
<mattiase>
Don't look down on these kinds of exercises. It's a way to get warm.
<c0m>
oh, i'm not looking down at all
<c0m>
the rest of the class is working in groups
<c0m>
but i'm on my own on this one
<c0m>
i figured that one out
<c0m>
i used the lagrange polynomial
<c0m>
but its only for a limited range
<c0m>
also, the generated sequence (2, 4, 16, 65536) is a subset of the ackermann function
<thelema>
c0m: I think it's called hyper-eponentiation
<c0m>
but since he wanted us to approach it experimentally, it would crash if there were more than 4 twices
<mattiase>
c0m: Look up Knuth's arrow notation
<thelema>
*exponentition
<c0m>
yeah i saw it
<c0m>
65536 is 2^(2^(2^2))
<c0m>
but there was a gap from 16 to 65536
<c0m>
i couldn't figure the formula to generate that
<thelema>
0 2 4 16 65536
<thelema>
each number is 2^(previous)
<mattiase>
c0m: try the Big_int module (or whatever it's called in f#)
<mattiase>
I suppose f# doesn't have transparent bignums?
<thelema>
mattiase: nope, not going to help
<mattiase>
thelema: not in the long run, of course.
<mattiase>
thelema: Or were you referring to run time?
<mrvn>
Isn't the stack overflowing anyway? And 2^65536 would take too long anyway.
<thelema>
0 1 2 4 16 65536
<mattiase>
2**65536 isn't huge as bignums go. 2**(2**65536) is, unless you switch representation...
<thelema>
you could compute it through squaring in a reasonable time, but not through incrementing
struktured has joined #ocaml
<mattiase>
Very true.
<kaustuv>
2^65536 is trivial to compute in binary
<mattiase>
kaustuv: Ah, but for this exercise, you have a Soviet computer based on trinary!
<mrvn>
kaustuv: not if all you use is "succ"
<kaustuv>
If you want to exponentiate by twos, (a) don't use base 3, and (2) don't use succ.
<mrvn>
print_int 1; for i = 1 to 65536 do print_int 0; done
<kaustuv>
don't forget print_string "0b" first
<thelema>
feh, if you're just going to print it, what makes that representation any better than [printf "2^65536"]?
<mattiase>
0x1p65536 maybe?
<kaustuv>
It's just 10 in base 2^65536
<mattiase>
or more pragmatically, +Inf
verte has quit ["~~~ Crash in JIT!"]
<infoe>
for some reason Pow (**) only works with floats
<infoe>
in F#
<c0m>
infoe: your name is funny
<c0m>
hehe
<infoe>
so is c zero m
<infoe>
are you using ** with types other than float?
<mrvn>
infoe: it is of little use for ints as their range is so small.
<infoe>
it is that way in ocaml as well?
<mrvn>
# ( ** );;
<mrvn>
- : float -> float -> float = <fun>
<infoe>
interesting
<mrvn>
infoe: 10 ** 10 already overflows an int.
<infoe>
yes
<infoe>
in other languages though i can ^ ints
<infoe>
not that im griping or anything...
<mrvn>
and ^ in other languages is xor.
<mrvn>
One problem is that ** can only be either int to float but not both. And float is far more often used.
<infoe>
i hear that, but that gives me anther question
<mrvn>
You could have ** (int) and **. (float), which would be more natural anyway, but someone decided ** for int isn't needed.
<infoe>
why does it default to int, ie: let f a b = a + b : int -> int -> int
<mrvn>
because + is a function int -> int -> int
<mrvn>
# (+);;
<mrvn>
- : int -> int -> int = <fun>
<mrvn>
The () are needed because it is also an infix operator.
<infoe>
i understand
<infoe>
i was looking for XOR in F#
<mrvn>
join a f# channel. :)
<mrvn>
"xor" doesn't work?
<infoe>
perhaps we should discuss that on #fsharp
<infoe>
i have been there for months, this channel is much more active
seanmcl has quit []
<c0m>
hey thelema
<c0m>
remember the issue we spoke of last night
<c0m>
i'm reading a wikipedia page .. and thought that it might be an issue with eager evaluation when using fold (left fold) which makes it slower than foldBack (right fold) for (@) function
<c0m>
although flatten2 is not tail recursive, it performs better
<c0m>
which means it has something to do with (@) function and the way the folds are implemented
<mrvn>
# List.foldBack;;
<mrvn>
Error: Unbound value List.foldBack
<c0m>
code works for me
<c0m>
F#
<mrvn>
but we are in #ocaml here
<c0m>
i know but fsharp is dead
<c0m>
and languages are similar anyway
<c0m>
so general discussion should, imo, be ok
<mrvn>
is foldBack a fold_right?
<c0m>
yes
<c0m>
(f (f (f (f (f z 1) 2) 3) 4) 5) that's a fold left and (f 1 (f 2 (f 3 (f 4 (f 5 z))))) that's a fold right
<c0m>
so when taking [] and appending a list to it using right
<c0m>
i think that is why it performs better
<c0m>
because doing it with left fold .... it seems to go through the list each time
<mrvn>
Then fold appends the short list at the end of the larger and larger list while foldBack appends the larger and larger list at the end of the small lists.
<c0m>
because to get to 2, you must go through 1
<mrvn>
So only the small lists in xs get copied each time which is much faster.
<mrvn>
fold is O(n^2) while foldBack is O(n) in your case. (n = Listh.length (flatten1 xs))
ikaros has joined #ocaml
<mrvn>
The tail-recursve or not doesn't play into this at all imho.
<c0m>
List.length (flatten1 xs) gives the size of the list
<c0m>
doing it with flatten2 gives same size
<infoe>
installing ocaml
<mrvn>
c0m: obviously.
<c0m>
but you implied using big O that n^2 was size of list squared
<mrvn>
c0m: the runtime is n^2
<c0m>
i know
ikaros has quit [Client Quit]
ikaros_ has joined #ocaml
_zack has quit ["Leaving."]
<mrvn>
so where does it say the size is squared?
<c0m>
if you read it differently
<mrvn>
read it right.
<c0m>
+P
<c0m>
* =P
<mrvn>
c0m: You should rev_append each list and then rev the result. Or use mutable lists to append to the end as yougo along.
<c0m>
this was the problem given
julm has quit [Remote closed the connection]
julm has joined #ocaml
<c0m>
btw, thanks for the convo
<mrvn>
c0m: the problem is that @ is O(List.length first_list) and the left/right approach changes what is the first list.
<c0m>
exactly my thoughts
<c0m>
(@) is proportional to the size of the first argument but it seems that foldback reverses what is considered "first" because [] is the second argument with respect to the (@) function...
<mrvn>
left has the result as first list meaning every element gets copied again and again: O(n^2) while right has the input as first list meaning every element gets copied once: O(n)
<c0m>
that's what i said
<mrvn>
You actualy can't get better than foldBack except for the recursion limit.
<infoe>
installed ocaml what is a list of must-haves?
<infoe>
i've seen discussion of batteries in here, so i just git cloned that
rwmjones_lptp has joined #ocaml
<thelema>
infoe: I'm the developer of aaa batteries, I'd love your feedback (especially problems) on it.
<thelema>
(it's in the "aaa" branch of batteries, and installs parallel, just make sure to autoconf && ./configure when you switch)
<infoe>
alpha3 ?
<thelema>
aaa is... lacking a version number
<infoe>
ok
<infoe>
well this will be my first forray into OCaml aside from the exposure to its syntax and concepts through the F# language
<infoe>
seems to me that I will have more fun with OCaml for certain things
<thelema>
then I'll get a beginner's perspective, no problem.
* thelema
always has more fun with ocaml
<infoe>
excellent
<infoe>
well i just pulled the main git repo
<infoe>
you're saying that I should pull from another location to get the aaa branch?
<infoe>
or does it come with the main branch?
<thelema>
no, the aaa branch is in the main repo
<thelema>
git checkout aaa
<flux>
hm, Changes: Local opening of modules in a subexpression. Syntax: "let open M in e", or "M.(e)" \o/
<flux>
although maybe I noticed this the last time already, but I don't think I the Changes-file was updated yet?
<thelema>
yes, that's being added to main branch
<thelema>
mainline ocaml
<thelema>
we like
<flux>
indeed, we do
<flux>
new fnu ways to ways to write code that doesn't work on older compilers \o/
<flux>
no, wait, that didn't come out right..
<thelema>
it doesn't quite cover pa_do, but it's a good start
<thelema>
probably a 90% solution
<flux>
hm, so what did pa_do do in addition to that?
<thelema>
magic with operators - turning * into mul
<flux>
btw, does this mean pa_do will not work properly with 3.12?
<thelema>
there'll probably be some fighting between the two on syntax - I think pa_do will convert to the old syntax, which'll still work ok.
<flux>
I suppose it can still work, but it must implement (as it currently does) the work of the that feature by itself..
<mrvn>
in camlp4 preprocessing can I get information from another module used in the source?
<mrvn>
specifically I would need to know OtherModules.type_length to calculate alignment.
<flux>
I suppose in theory you could, but I don't think there are facilities around to do that
<thelema>
mrvn: not easily. better just hard code the ones you think you'll use
<mrvn>
user defined structurs.
<thelema>
hmm... I don't see any easy way to do this.
<thelema>
but don't ask me - I'm not a camlp4 guru - I pulled it out of aaa because I don't understand it.
<mrvn>
I have 3 options: 1) use variable size/alignment and hope the compiler optimizes it away, 2) get the size from the other module, 3) have the user specify the size (which could be wrong then)
<thelema>
(and other reasons)
<thelema>
user specify
<thelema>
unless you can spare the performance, then variable size
<mrvn>
Can I add a compile time assert somehow? #ifneq (xyz,OtherModule.struct_length) #error #endif kind of.
<mrvn>
i.e. pass the error checking of to ocamlc/opt itself.
rwmjones_lptp has quit ["This computer has gone to sleep"]
<thelema>
mrvn: I don't think much can be done at compile time.
<flux>
it allows recursion between classes and regular types
<flux>
it's fun to look what changes have gone into the repository :)
Vecklock has joined #ocaml
<mrvn>
thelema: does the compiler optimize if (16 + OtherModule.struct_length + 32 + 8) mod 8 = 0 then access_aligned else access_unaligned ?
<mrvn>
OtherModule.struct_length being "let struct_length = 16"
<thelema>
probably.
<thelema>
if it's all known at compile time
<thelema>
ocaml does do constant propogation
<mrvn>
Just wondering how complex the expression can be before it stops.
<thelema>
I don't expect there's much of a limit - it's really easy to do.
<mrvn>
I would expect "let x = x asr 1 in s.{a}" to do x = x asr 2, get *(s+a). Instead it does asr x, tag x, asr x, get s+a
<mrvn>
s+x even
<thelema>
yes, ocaml is very literal - if you tell it to do x, then y, it will do exactly that.
<mrvn>
thelema: It doesn't "unbox" variables.
<thelema>
correct - you might need x later, and so it generates the boxed version of x
<mrvn>
then it can box it again.
<mrvn>
or rather it should box it there but use the unboxed value as long as its valid and then see the boxed one is unused.
<thelema>
mrvn: you're using knowledge about the boxing process which are abstract in the part of the compiler that would do this.
<mrvn>
thelema: not realy. Just knowing about untaged and taged values would result in "asr x; asr x; mov res,(s,x)"
<mrvn>
thelema: and the compiler already knows that "x asr 1" implicitly untags ints. So it does have inside knowledge.
<thelema>
and apparently the compiler doesn't know about untagged values, every time it wants to do an array access, it starts with a tagged value, shifts it and does the offset
<mrvn>
It is odd that the compiler knows some things and ignores others.
<thelema>
it's a design goal that ocamlc stay maintainable. You've heard how horrible GCC was for a long time, no?
<mrvn>
still could use some more optimizing.
<flux>
just write the LLVM backend and all is well ;)
fschwidom has joined #ocaml
fschwidom has quit [Remote closed the connection]
<mrvn>
or gcc
<flux>
I'm not sure how great backend gcc would be
<flux>
I mean, isn't the unsuitability of C compilers for compilation backends the reason C-- exists?
<thelema>
for some people ocaml is very nice.
<flux>
usually ocaml performance is just fine
<flux>
of course, every now and then there is the rare case of doing signal processing or some other heavy lifting
seanmcl has joined #ocaml
<infoe>
batteries readme: 30,55 note should be not
<thelema>
infoe: fixing...
<thelema>
fixed in aaa and master
<infoe>
my first contrib :D
<infoe>
having champaigne
<c0m>
what is <> again
<c0m>
empty set?
<thelema>
c0m: not equal
<c0m>
or doesn't equal ?
<c0m>
thanks
<thelema>
c0m: <> : = :: != : ==
<c0m>
yeah thought so
<c0m>
as in sql
<thelema>
hmm, that didn't come out as readable as I expected...
<c0m>
haha
<mrvn>
thelema: <> is to = as != is to ==?
<thelema>
mrvn: yes
_zack has joined #ocaml
ttamttam has quit ["Leaving."]
caligula__ has joined #ocaml
tmaeda is now known as tmaedaZ
tmaedaZ is now known as tmaeda
kaustuv has left #ocaml []
<infoe>
hrm, camlzip is harassing me
caligula_ has quit [Connection timed out]
ygrek has joined #ocaml
tmaeda is now known as tmaedaZ
animist has joined #ocaml
<thelema>
infoe: yes, I've started integrating it into aaa-batteries, I dunno if it works...
<hcarty>
flux: Wow ... they added both let open M in e and M.(e)? That's excellent.
<infoe>
thelema: i was referring to having trouble installing it and having it installed with ocamlfind
<infoe>
but i got it now
<infoe>
im using archlinux
<infoe>
what platform do you work in?
<thelema>
yes, camlzip is wierd for findlib
<thelema>
I run Ubuntu
<infoe>
ok
<hcarty>
infoe: If you are using Arch, using GODI may be easier than using the Arch packages
<infoe>
the tighter the star pattern the more consistent across benchmarks
<thelema>
yes, ocaml is very predictable
jonafan has joined #ocaml
<infoe>
ok git installed batteries
<infoe>
checking out GODI
onigiri has joined #ocaml
onigiri has quit [Client Quit]
th5 has quit []
Dodek has joined #ocaml
<Dodek>
hey
<thelema>
hi
<Dodek>
how can i declare a type of a function?
<Dodek>
something like haskell "foo :: Int -> Int"
<thelema>
let f : (int -> int) = fun x -> x+1
<Dodek>
it doesn't look nice, i think.
<thelema>
this is only a suggestion to the compiler - you can't force a function to be polymorphic
<thelema>
the usual way is to use module interfaces to specify the types
<thelema>
if you do it there, it looks like:
<Dodek>
val something =
<thelema>
val f : int -> int
<Dodek>
i know
<thelema>
but it's not common to put types in your .ml
<Dodek>
but i'm using emacs for editing
<mrvn>
apart from finding out why something doesn't compile you shouldn't need to specify types. Even mli files I usualy create with ocamlc -i and then edit down.
<Dodek>
and when i send a function to inferior caml
<Dodek>
its type does not really correspond to what i want it to be
<Dodek>
that is, i declared a type
<Dodek>
type foo = bar -> baz
<Dodek>
and when i pass a value of type foo
<hcarty>
Dodek: Inferior caml?
<mrvn>
I usualy just specify type for some arguments instead of the full function: # let f (x : int) = x + 1;;
<Dodek>
there is (bar -> baz) in its type, not foo, and it is not easy to read
<Dodek>
hcarty: well, when emacs runs repl processes, it calls them "inferior foo"
<Dodek>
i have a buffer *inferior caml* with caml running in it
<hcarty>
Dodek: Ah, an emacs-ism.
<mrvn>
Dodek: specify the type in the mli file
<thelema>
Dodek: it does get easier to read complex type expressions with practice.
<Dodek>
mrvn: unfortunately it does not work with emacs.
<thelema>
Dodek: specify argument types as mrvn said
<Dodek>
and point is (float * float) so it looks even funnier
<hcarty>
mrvn: You could kind of do that with "module M : sig ... end = struct ... end include M"
<mrvn>
hcarty: done that. :)
<Dodek>
anyway, thank you guys
<mrvn>
hcarty: only way to get phantom types to work even inside the module itself.
<hcarty>
mrvn: Yipes - yes, I've run up against that several times.
ulfdoz has joined #ocaml
<mrvn>
hcarty: I did a little "test.ml" to play with phantom types for read-only/read-write stings and I could happily write to a read-only string. Nothing worked till I moved the phantom type into a module with signature hiding the type.
<mrvn>
But I didn't know about private types then. Maybe private works too.
<thelema>
mrvn: you can specify signature even in .mli file -- module Foo : sig type t end = struct type t = int end
<thelema>
err, even in .ml file
<mrvn>
thelema: but then that is a submodule.
<mrvn>
thelema: you need to include Foo at the end to bring it back into the main module again.
<thelema>
true.
<hcarty>
mrvn: You can do the same thing for private types
<hcarty>
mrvn: I've used small sub-modules (followed by an "include") to isolate the functions which need to be able to create the private type.
<hcarty>
create *values of* the private type
<hcarty>
It's kind of ugly, but it seemed like the best solution at the time.
<mrvn>
yeah, I'm currently just readin the chapter in the docs and private needs to be hidden just like phantom type to be effective inside the module too.
<mrvn>
I was thinking of using "type uint = private int"
* thelema
wants "type uint = new int" and automatically have conversion functions to and from int
<mrvn>
thelema: new? An object?
<thelema>
no, a new type
<hcarty>
thelema: Does Deriving provide something like that?
<mrvn>
my type above should allow uint -> int transparently but int -> unit only through a constructor that can throw Negative
_andre has quit ["Lost terminal"]
<mrvn>
hcarty: your try_finally is broken if cleanup throws an exception
julm has quit [Remote closed the connection]
<mrvn>
type ('a,'b) choice = A of 'a | B of 'b
julm has joined #ocaml
<hcarty>
mrvn: That's true - any suggestions for a better way to handle that case?
<mrvn>
let try_finally it cleanup f = let res = try A (f it) with x -> B x in cleanup it; match res with A r -> r | B x -> raise x;;
<mrvn>
Or catch exceptions in cleanup in the exception case and throw DoubleException.
<hcarty>
mrvn: Thank you for the suggestions. I'll work with them and see which fits better.
<mrvn>
does cleanup ever throw an exception?
<hcarty>
mrvn: Never in the cases I've used
<mrvn>
hcarty: The problem I see with your current one is that IF cleanup throws an exception then it is executed twice. Imagine if it calls a C function with free(p).
<hcarty>
I don't think it would in this particular module. I'm not certain of that though.
ttamttam has joined #ocaml
<hcarty>
mrvn: Very good point
<mrvn>
hcarty: I still haven't solved my problem of how to handle 31bit ints nicely yet. I hate having to pipe them through int32 for the sake of Bigarray.
<mrvn>
Too bad one can't do type integer = if Sys.word_size = 32 then int32 else int;; as well.
tmaedaZ has quit [Read error: 60 (Operation timed out)]
ccasin has joined #ocaml
det has quit [Remote closed the connection]
drunK_ has joined #ocaml
julm has quit [Remote closed the connection]
julm has joined #ocaml
_unK has quit [Read error: 110 (Connection timed out)]
<mrvn>
So, bugs filed for UInt, UInt32 and UInt64 modules and (int, int31_elt) Bigarray.kind type.
<flux>
mrvn, well, you can do it with the build system..
<flux>
mrvn, welcome to the wonderful world of autoconf :P
<mrvn>
flux: in bytecode?
<hcarty>
mrvn: There is the Int63 module. But you would have to write the appropriate Bigarray glue to go along with it.
<mrvn>
hcarty: Bigarray already knows about int64.
<flux>
mrvn, step 1) determine system architecture step 2) produce file i.ml with type t = int32 or type t = int 3) convert all source that uses that particular type :-) to proper format 4) profit!
<hcarty>
mrvn: Int63.t is along the lines of the "type integer = int32 or int" you mentioned earlier.
<mrvn>
flux: you forget "compile source again"
<flux>
mrvn, well, I was assuming the source wasn't compiled in the first place
<mrvn>
flux: as said: What about bytecode?
<flux>
mrvn, hm, why does it matter what kind of code is produced?
<mrvn>
because the same bytecode runs on all archs.
<flux>
mrvn, oh you want interplatform-compatible bytecode?
<mrvn>
yep
<flux>
mrvn, well, compile both versions and dispatch..
<mrvn>
flux: yeah. sucks. :)
<hcarty>
Does 32bit bytecode run on 64bit ocamlrun?
<hcarty>
Similarly for 64bit -> 32bit?
<flux>
if you're giong for performance (?), isn't bytecode sort of against that?
<mrvn>
I believe so.
<mrvn>
flux: I often test as bytecode.
<flux>
mrvn, on multiple platforms?
<mrvn>
and some archs don't havebinary.
<flux>
mrvn, doesn't it just work if you always use int32?
<flux>
or something
<mrvn>
flux: a lot slower.
<flux>
again, bytecode, ..
<mrvn>
compiled too.
<flux>
for compiled you could specialice and not worry about the binary needing to run similarly on both 32 and 64-bit
<mrvn>
int32 is boxed on 64bit cpus too.
<mrvn>
That means then I have 3 versions of my source: 32bit binary, 64bit binary and bytecode.
<mrvn>
hcarty: any url for the Int63 module?
<flux>
one version of course, three generated versions :). but isn't either one of those sources for xx-bit binaries the same as bytecode source?
<mrvn>
flux: In bytecode you need to use int32 all the way. In 32bit binary you use int and in 64bit binary you use int32 in Bigarray but convert to int on access.
tmaedaZ has joined #ocaml
Yoric[DT] has joined #ocaml
<hcarty>
mrvn: pa-do also has some int63 magic in one of its examples.
<mattiase>
I'd actually like an int65 type...
<hcarty>
:q
<hcarty>
Sorry about that - wrong window.
<mrvn>
mattiase: int128 for SSE registers.
<mattiase>
mrvn: well no, I don't think sse registers can do 128-bit arithmetic.
<mrvn>
hcarty: I see how you can do that but again not good for bytecode.
<hcarty>
mrvn: I'm not sure if there is a good-for-bytecode implementation that isn't int32
<mrvn>
Something like Bigarray but for SSE registers. (char, int8_unsigned_elt) SSE.t for 16 uint8 in a register.
<hcarty>
mrvn: Otherwise it sounds like you'll have to dig in to C.
<mattiase>
mrvn: But it's true that once above 64 bits you might just as well go for 128.
seanmcl has quit []
<mrvn>
hcarty: It is anyoing in the int31 case as they always fit into an int. The Bigarray just needs a way to restrict itself to 4 byte on 64bit systems.
<mrvn>
It is stupid to allocate a boxed int32, Array1.get the int32 and Int32.to_int. Wasted invocation of the GC.
<hcarty>
mrvn: I'm pretty sure that could be done with some modification to the Bigarray C stubs
<mattiase>
Unboxed word-sized integers would be lovely to have
<mrvn>
hcarty: better the bigarray primitives in the compiler. Shouldn't call a C function at all.
ikaros_ has quit ["Leave the magic to Houdini"]
<mrvn>
mattiase: that is int. I want fixed size <= word-sized
<hcarty>
mrvn: Most of the Bigarray module functions are C
ikaros has joined #ocaml
det has joined #ocaml
<hcarty>
Perhaps not most. But the basic ones are.
<mattiase>
mrvn: No, int is not word-sized, or your definition of "word" disagrees with the world.
<mrvn>
hcarty: int8, uint8, int16, uint16 generate direct asm code. surprisingly int generates a C call as do int32 and int64.
<mrvn>
mattiase: well, word-1 sized.
<mattiase>
mrvn: Exactly. That -1 makes all the difference at times.
<mrvn>
mattiase: all values need to be taged. you can't have unboxed int32/int64 that the GC can see.
<mattiase>
mrvn: Of course I can. It works for floats.
<mrvn>
And unboxing/untagging them inbetween GC calls is a compiler optimization (that ocaml saddly lacks)
drunK_ has quit [Remote closed the connection]
seanmcl has joined #ocaml
_unK has joined #ocaml
seanmcl has quit [Remote closed the connection]
<hcarty>
mattiase: floats are boxed in OCaml
<mrvn>
floatBlocks with tag Double_tag.
<mattiase>
hcarty: Not in records or arrays - they are special-cased
<mattiase>
I don't see why we should need Bigarray hacks for that
<mrvn>
mattiase: The array is tagged.
<mrvn>
and in records I do believe they are boxed.
<mrvn>
"As an optimization, records whose fields all have static type float are represented as arrays of floating-point numbers, with tag Double_array_tag. (See the section below on arrays.)" with that exception
<mattiase>
mrvn: Yes.
<hcarty>
mattiase: Bigarray hacks for what?
<mattiase>
hcarty: arrays of word-sized integers
<hcarty>
mattiase: It could be special-cased like float arrays are
<mattiase>
hcarty: Yes, I thought so too, but sadly it isn't.
<mattiase>
The implementors probably didn't consider it important enough
<hcarty>
mattiase: What is the benefit to this though? An OCaml float is the same size on all supported platforms
<mattiase>
hcarty: So is an Int32, or an Int64.
<mrvn>
hcarty: an int32 Bigarray is 4 times smaller an int32 array on 64bit.
<mrvn>
+than
Kakwa has joined #ocaml
<hcarty>
mattiase: Right - but a native-word array would not be.
<hcarty>
mrvn: Right, due to the internal representation of the bigarray (a flat C array)
<mattiase>
hcarty: No, but it's not the native-word array that's important, but Int32 or Int64 where they coincide with native word size.
<mrvn>
hcarty: due to not being boxed.
<hcarty>
mattiase: Yes, so you would need to have special-cases in all code to know "is this Native_word_tag array int32 or in64?"
<mrvn>
hcarty: just like Double_array_tag
<mattiase>
hcarty: Would we? And if so, why not different tags for them then?
<mattiase>
It's mostly a consideration for polymorphic comparison. And maybe get/set
<hcarty>
Adding all of these special cases could potentially speed things up. But it would also make the compiler and its C FFI more difficult to maintain and work with.
<mrvn>
hcarty: no more so than Double_array_tag
<mrvn>
I'm actually surprised they added the special case for float.
<hcarty>
mrvn: No, no more than Double_array_tag. But it's still another special case.
<Camarade_Tux>
well, C already varies, on 64bit, my C ints are 4 bytes and I'm not sure they're the same size on windows
<mattiase>
But it leaves us with the situation we have - we need a fancy module with accessors not understood as primitives for something as simple as an array of reasonably large integers
thieusoai has quit [Read error: 60 (Operation timed out)]
<hcarty>
I remember reading a mailing list post from a while ago stating that the special case for double arrays/records is somewhat due to inertia from prior work.
<hcarty>
mattiase: 63bits is plenty reasonably large for me :-)
<hcarty>
Until some point in the future when it is not.
<mattiase>
Say you want to write a bitmap (vector of bools). You can use a string, but that's slow in many cases because 8 bits are often too few to process at a time.
<mrvn>
hcarty: if only I didn't have a 32bit cpu left.
<flux>
I suppsoe 31-bit will be a non-issue atleast for me in a few years
<flux>
it's too bad that the code that assumes 63-bit int may silently fail on older platforms, though
<flux>
s/too //
<hcarty>
mrvn: I have the same issue - one of the main workhorse systems I have access to has a 64bit CPU but is stuck with a 32bit kernel, due to reasons beyond my control.
<mrvn>
let _ = assert (Sys.word_size = 64);
<flux>
I wouldn't mind if they worked even slowly, but explicit int64's is not that great either
<hcarty>
flux: The Int63 module or pa-do extension are meant to handle those cases
<mattiase>
I'm in the business of simulating computer hardware. Such hardware usually have registers, memory locations and data paths that are 2**(2**n) bits wide.
drunK_ has joined #ocaml
<mattiase>
uh, 2**n, rather...
<hcarty>
It would be nice if that were included in OCaml. Probably too much standard library growth for their taste though.
<flux>
hcarty, nice, so that exists
<mrvn>
mattiase: so int32 or int64 usualy.
<mrvn>
hcarty: not bytecode friendly.
<flux>
hcarty, although there is a small problem still left: operator == will work differently when it's a real int or when it's an object in 32-bit land..
<hcarty>
flux: Yes, Richard Jones has one implementation and pa-do has another one which is strictly camlp4.
<mattiase>
mrvn: Yes, which is fine (if I'm lucky enough to have the compiler unbox them inside a function). Until I want to store them in an array, or record.
<mrvn>
hcarty: You need to copy the right int63_on_32.ml or int63_on_64.ml to int63.ml in the Makefile.
<hcarty>
mrvn: No, not bytecode friendly. But I don't think that there is a truly bytecode friendly option here.
<mrvn>
hcarty: only to kill all 32bit cpus. :)
<flux>
mrvn, but the code still _can_ be compiled for 32-bit platforms
<hcarty>
mrvn: Ah, of course :-) I forgot about that one.
<flux>
mrvn, bytecode and native
<mrvn>
hcarty: or run 64bit on 32bit cpus too, slowly.
<hcarty>
mattiase: Something like BitC would have suited your needs I imagine. Sadly, it seems to be a dead project now.
<mrvn>
Maybe that would be a case for phantom types. ['Int_least_31, 'Int63, 'Int32, ...] integer with +, -, *, / and the compiler picks the best it can decide.
<mattiase>
hcarty: BitC was perhaps a little too ambitious.
<mrvn>
too bad camlp4 works before type inference
<mattiase>
hcarty: But BitC was more intended for system-level implementation. I don't really have such needs.
tmaedaZ has quit [Read error: 110 (Connection timed out)]
<hcarty>
mattiase: Fortran's an option!
<mrvn>
*poud* I just want (int, int31_elt, c_layout) Array1.t with Array1.get_little and Array1.get_big for endian conversion.
<mattiase>
hcarty: INTEGER*8
<hcarty>
mrvn: Is that all? :-)
<mattiase>
... and I want Some x to be implemented as a pointer directly to x, and None as a null pointer
ygrek has quit [Remote closed the connection]
<mrvn>
mattiase: yeah, waste of a perfectly good NULL.
ygrek has joined #ocaml
<mrvn>
mattiase: would introduce a special case again though.
_unK has quit [Read error: 110 (Connection timed out)]
<mattiase>
mrvn: You can make it a little more general - for variant types with at most one case without attached data
<mattiase>
mrvn: s/without/with/
<mattiase>
like A | B | C | D of t
<mrvn>
I guess type foo = A | B | C | D of bla could use this too.
struktured has quit [Read error: 110 (Connection timed out)]
<mrvn>
Would be (in C) 1, 3, 5 or pointer to bla
<mattiase>
I'm happy to see that we think alike.
<mrvn>
but I hate special cases.
<mattiase>
mrvn: As long as the user doesn't see them, it's not too bad. The ocaml FFI is the main problem, but perhaps mostly because it isn't a very good ffi
<hcarty>
mrvn: How would you identify 1, 3, 5 as something other than a pointer?
drunK_ has quit [Client Quit]
<mrvn>
hcarty: they are taged with 1.
drunK_ has joined #ocaml
<mrvn>
hcarty: pointers have a 0 tag
drunK_ has quit [Remote closed the connection]
_unK has joined #ocaml
<hcarty>
mrvn: Ah, of course.
<hcarty>
mattiase: It's not too bad when you don't have to maintain the compiler :-)
<mrvn>
it is bad for C stubs when A | B | C | D of t suddenly gets an E of x
<mattiase>
hcarty: It depends on whether it can be isolated in one spot or if the rule leaks out all over the place.
<mattiase>
mrvn: We shouldn't have to maintain such things in parallel without any consistency checking anyway
tmaedaZ has joined #ocaml
tmaedaZ has quit [Remote closed the connection]
<hcarty>
mattiase: Is there a language which provides what OCaml provides, along with these extra goodies?
<hcarty>
That what I thought was so interesting about BitC. It seemed to be heading in that general direction.
<mattiase>
hcarty: If there were, I wouldn't be here... I like ocaml a lot, but there are clearly some low-hanging fruit
<hcarty>
Nothing else has caught my eye in that way though. Pure seems interesting, but you seem to lose many of the static checks.
<mrvn>
In the C interface what is the difference between Long_val and Int_val?
<hcarty>
mattiase: I know a University of Maryland student wrote an OCaml FFI validation tool, but I don't know if it is maintained or if it ever even worked.
tmaedaZ has joined #ocaml
<flux>
good disclaimer :)
<hcarty>
flux: :-) I looked at it a while ago, but it seemed to require a large amount of extra per-project effort to utilize.
<flux>
mrvn, but for example campl4 doesn't really compile ocaml code
<mrvn>
flux: oh, you mean just to pretty print it at the end (and feed to gcc)
<flux>
mrvn, yes
<hcarty>
flux, mrvn: It generates a separate C file which needs to be compiled
<mrvn>
that was what I ment above.
<flux>
mrvn, yes, I know, but a more structured system would be nice for as a tool for writing such a camlp4 generator
<mrvn>
flux: should be just a matter of writing a module for C-Asts.
<flux>
hcarty, yeah, I remember now seeing ciml earlier.. I wonder if it's been developed further..
<flux>
mrvn, "just", indeed :)
<mrvn>
matter of minutes. :)
<hcarty>
Would CIL do that? ASTs are getting outside of my realm of experience.
<flux>
oh, it happens I already had ciml checked out
<mattiase>
hcarty: I really should make a serious comparative evaluation of what other people have done, instead of tackling it on my own each time
<mrvn>
Ok, int31 type added to Bigarray.
Associat0r has joined #ocaml
<flux>
darcs pull takes aaaages for me
<hcarty>
mattiase: At times, it feels like 1/2 of my time spent with OCaml is spent evaluating what other people have done :-) Particularly for something like camlidl vs ciml vs ...
<mrvn>
Step 2: add compiler primitives
<mattiase>
hcarty: It really does - there has perhaps been too little collaboration to come to an agreed "best" solution to many problems
<mattiase>
hcarty: Instead, there are N different regexp libs, interface libs, marshalling libs...
<mrvn>
hcarty: I gave up on camlidl. The use is complicated, the code looks horrible and seems awfully inefficient.
<hcarty>
mrvn: I've been very happy with the efficiency of the generated code. But I've been able to reuse a lot of my effort between generating bindings for PLplot and HDF4.
<hcarty>
mrvn: The large volume of "simple" functions made it worth the effort.
<mrvn>
hcarty: Too me it looked like it generates 2 stubs. First it copies all ocaml types into C structs and calls the second stub. The second then glues to the actual C function.
<flux>
mrvn, I think for most of the libraries efficiency doesn't matter that much, really
<flux>
but I too had trouble with camlidl
<flux>
extending it to handle a custom type properly
<hcarty>
mrvn: It does a decent job of sharing data between C and OCaml. But when in doubt, it copies.
<flux>
it didn't pass an argument it used itself to my function
<mrvn>
I looked at it for libfuse bindings and they looked horrible.
<hcarty>
mrvn: Most data, unless you want to leave them opaque, require copies between C and OCaml
<flux>
mrvn, I think that for example for a terminal library camlidl would be a perfect hit
<mrvn>
In the fuse case I need the verbatim ocaml data too because I need to register a root for it. That when I gave up.
<flux>
no callbacks, no problem if you waste a cycle here and there, etc
<mrvn>
fuse - only callbacks. :)
<hcarty>
If you want to see truly ugly bindings, check out Swig-generated bindings for OCaml
<mrvn>
Can camlidl generate noalloc functions?
<flux>
it appears FrontC already has an AST defined
<mrvn>
My biggest problem is having type A | B | C and enum { A, B, C }; That should realy be only written once and used for ocaml and C.
<flux>
hcarty, like write it inside an .ml-file and have the c-file generated while you compile it
<mrvn>
hcarty: no, the primitives. Not the C stubs.
<flux>
mrvn, how about type foo = A of int | B of (string * char) | C of foo ?
<flux>
mrvn, that kind of things need some decisions to be made..
<mrvn>
flux: still needs enum { A, B, C };
<hcarty>
flux: That's what ciml does
<mrvn>
type foo = A | B | C of c | D of d is worse as A and B are ints and C and D tags.
<flux>
hcarty, uh, yes, I mixed ciml with cil
<hcarty>
flux: The C stubs are generated by the camlp4 extension
<hcarty>
flux: Ah, understood
<hcarty>
mrvn: As far as I know, the only bigarray material in OCaml sits in the C stubs, the Bigarray module code and the syntax definitions
<mrvn>
hcarty: wrong. The compiler knows about bigarrays and generates asm code for it directly. Makes it really fast.
<mrvn>
asmcomp/cmmgen.ml
<hcarty>
mrvn: Cool
valross has joined #ocaml
_JusSx_ has joined #ocaml
ygrek has quit [Remote closed the connection]
<mrvn>
Primitives completed. Step 3: get it to compile
<Camarade_Tux>
if I make 1M recursive calls and get no stack overflow, it means the compiler has tail calls, right?
<Camarade_Tux>
(wrt Harrop's claim that gcc lacks them)
<mrvn>
Camarade_Tux: yes. gcc isn't verry good at tail recursion
<Camarade_Tux>
it's not done at -O0 but it's done at -O1 and higher
<Camarade_Tux>
-foptimize-sibling-calls
<Camarade_Tux>
Optimize sibling and tail recursive calls.
<Camarade_Tux>
Enabled at levels -O2, -O3, -Os.
<Camarade_Tux>
O2 actually ;)
ulfdoz has quit [Read error: 110 (Connection timed out)]
<mattiase>
Camarade_Tux: gcc has sibcalls but they are not general tail calls
<mattiase>
First, there is no guarantee that a particular call is optimised that way.
<mattiase>
Second, only calls to functions using at most the same amount of argument stack space are considered for sibcalls.
<mattiase>
So the general mechanism is there, but it would need 1) an assertion that the user could write "please signal an error if you can't make this into a sibcall", and 2) generalisation to call functions that need more arguments on the stack
proteus has joined #ocaml
<mrvn>
or just use goto whenever you need tail recursion
<Camarade_Tux>
mattiase: ok, I see, thanks, I had always been wondering
<Camarade_Tux>
:)
_zack has quit ["Leaving."]
<mattiase>
mrvn: That only covers tail recursion, doesn't work across translation units, doesn't scale (need to emit huge functions that take forever to compile), and cannot pass arguments (although that's less important if you are emitting code)
<mrvn>
gcc could learn to rebuild the stack for tail calls.
jules has joined #ocaml
<mattiase>
mrvn: Yes. It's just usually makes C code slower (compared to normal sibcalls which are neutral or faster)
<mattiase>
mrvn: So it would be mainly for generated code.
<mrvn>
mattiase: shuffeling a few registers around and adjusting the stack size?
<mattiase>
mrvn: Yes... the caller already has a stack frame built on top of the argument list on the stack. It would need to rearrange its own locals to do that.
<mattiase>
mrvn: It can surely be done, but I don't think the stack slot allocation in gcc is written with that in mind.
<mrvn>
mattiase: do it at least for functions that pass all arguments in registers.
<mattiase>
mrvn: But for those there shouldn't be any problem. They don't have any stack space for arguments at all.
<mrvn>
stack use for parameter is an abomination of x86 anyway.
<mattiase>
mrvn: No, even modern architectures need them for sufficiently many registers, or big arguments (like structs)
<mattiase>
s/registers/arguments/
_unK has quit [Remote closed the connection]
<mrvn>
mattiase: uncommon case except for structs in registers.
<jules>
i'm trying to learn how to write parsers with ocamlyacc, here is my attempt: http://pastebin.ca/1657406
<jules>
ocamlyacc compiles this file to a .ml file, but this ml file has syntax errors (according to the toplevel when i #use "parser.ml")
Snark has quit ["Ex-Chat"]
<jules>
the error message is: File "parser.ml", line 187, characters 0-2 Error: Syntax error: ')' expected
<mattiase>
mrvn: Sure, but they do happen. And ABIs vary.
proteus has quit ["Leaving"]
<jules>
oh i see now, the actual line reported is a few lines off: the syntax error was in the .mly file and ocamlyacc copied this into the .ml file