<mrvn>
Or write a compiler for makefiles in a day.
<mrvn>
ocamlp4 to parse makefiles into an ocaml AST, ocamlc to convert the ocaml AST into a C AST and gcc to make a binary.
<pattern>
mrvn, i am confused in trying to work out the types of the y combinator you gave me as an exercise yesterday... i have the terms numbered for reference here -> http://pastecode.net/index.php?tag=184
<pattern>
do i start with the x's that i've numbered 7 and 8, or those that i've numbered 15 and 16 ?
<mrvn>
First step is to draw lines between the abstraction and the instances of a variable: fun _x_ -> 2 * _x_
<mrvn>
Connect every variable to the fun that binds it.
<mrvn>
Then rename them so that they are uniqe.
<pattern>
i see
<pattern>
let me try that...
TachYon has quit [Remote closed the connection]
Zadeh has joined #ocaml
Zadeh_ has quit [Read error: 104 (Connection reset by peer)]
<pattern>
which (x x) ? the one in the first line, or the 2nd? the x7,x8 or x15,x16 ?
<mrvn>
doesn't matter
<pattern>
so what do i do with them? i've already assigned them the same type... so i can't do (x:'d->'d)
<mrvn>
x is a function that takes a 'd as input, but the output can be anything: x 'd->'j
<pattern>
ok... let me go with that
<mrvn>
But x is the argument passed to x, so 'd must be 'd->'j
<pattern>
yeah, i'm following you
<mrvn>
x: ('d->'j)->'j
<mrvn>
But thats the argument passed to x ==> x: (('d->'j)->'j)->'j
<mrvn>
or something like that and on and on and on
<mrvn>
You have a recursive type there that would keep on growing for ever.
<pattern>
wait, how did the last ->'j get there in x: ('d->'j)->'j ?
<mrvn>
The type of x is the type of its first argument. You have to substutute it again and again
<pattern>
i know we have: fun y -> (x x) y
<pattern>
but y is 'f
<pattern>
not 'j
<mrvn>
no, you are still doing (x x)
<mrvn>
and you will be forever
<pattern>
why?
<mrvn>
because x gets itself as argument
<pattern>
hmmm
<mrvn>
(x x) results in ('a->'b as 'a) -> 'b
docelic has quit ["Client Exiting"]
<pattern>
i see that x gets itself as input, but i don't see why that would result in an infinate recursion
<mrvn>
Ok, lets ignore the fact that its x and x and look at (a b)
<pattern>
ok
<mrvn>
a:'a and b:'b initially, ok?
<pattern>
yep
<mrvn>
(a b) --> a:'b->'c
<pattern>
don't you mean (a b) --> a:'a->'b ?
<mrvn>
no, b was type 'b
<pattern>
oh, 'b was already taken
<pattern>
yeah
<pattern>
ok, go on
<mrvn>
But thinking back to (x x) we would know that b has the same type as a:
<mrvn>
a:'b->'c b:'d->'e (b must be a function just like a)
<mrvn>
But from (a b) we get a:('d->'e)->'c
<mrvn>
ok?
<pattern>
don't we get a:('b->'c)->(b:'b->'c) ?
<mrvn>
we know nothing about what type a returns
<mrvn>
ah, forget that
<pattern>
we don't?
<mrvn>
a:('b->'c) (b:'b->'c) you mean
<mrvn>
a:('b->'c) b:('b->'c) even
<pattern>
yeah
<mrvn>
yeah, but then it gets confusing. a:'b->'c b:'d->'e [ignoring that 'b='d and 'c='e]
<mrvn>
Thus we get a:('d->'e)->'c, ok?
<pattern>
yes, it certainly is confusing... because i don't know where 'b='d and 'c='e came from
<mrvn>
pattern: Originally we wanted to type (x x) and called them (a b).
<pattern>
yep
<mrvn>
So a and b in (a b) must have the same type.
<mrvn>
Both would be x
<pattern>
yep
<pattern>
go on
<mrvn>
And the only way 'b->'c and 'd->'e are the same type is with 'b='d and 'c='e
<pattern>
where did we get 'd and 'e ?
<mrvn>
out of our bag of unused types.
<pattern>
and why are we looking in that bag?
<pattern>
is it because we want to give b:('d->'e) ?
<mrvn>
because b can't have type 'b and be the same type as a is
<mrvn>
b must be a function so we pull out two types and create 'e->'d
<mrvn>
'd->'e i mean
<pattern>
for b:('d-'e) ?
<mrvn>
yes
<pattern>
for b:('d->'e) ?
<pattern>
ok, so now 'b='d and 'c='e
<pattern>
i'm with you
<mrvn>
a:'b->'c gets the argument b:'d->'e, thus 'b is actually 'd->'e
<mrvn>
a:('d->'e)->'c, ok?
<pattern>
yes!
<pattern>
:)
<mrvn>
But then b must be of the form ('f->'g)->'h
<pattern>
i see now
<pattern>
:(
<pattern>
so what do we do?
<mrvn>
a:(('f->'g)->'e)->'c
<mrvn>
...
<pattern>
yeah, i see the infinate recursion now
<pattern>
so what do we do about it?
<mrvn>
a:('a->'b as 'a)->'b
<pattern>
what do you mean by "as 'a" ?
<mrvn>
b: 'a->'b
<mrvn>
Thats the way ocaml denotes that its recursive
<pattern>
i don't follow
<mrvn>
a has type 'a->'b in which the 'a is 'a->'b in which 'a is 'a->'b
<mrvn>
It says that the arguments is the same as the full type
<pattern>
hmm
<mrvn>
Its something the normal type system can't find.
<mrvn>
'a as 'b creates 'b as alias for 'a
<mrvn>
Say you have a function f:('a->'b)->('a->'b)
<mrvn>
You can write that as f:('a->'b as 'c)->'c
<mrvn>
or: let f (x:'a->'b as 'c) (y:'c) = 0;;
<mrvn>
val f : ('a -> 'b) -> ('a -> 'b) -> int = <fun>
<pattern>
does "as 'c" mean as the last type? f:('a->'b as 'c)->**this** ?
<mrvn>
it means wherever 'c stands should stand 'a->'b
<pattern>
so does it then become f:('a->'b)->'a->'b ?
<mrvn>
yes
<pattern>
ok
<mrvn>
Normaly it just saves you typing a large type again and again
<pattern>
so now (x x) takes itself for an argument still
<pattern>
but
<pattern>
um
<mrvn>
Same as function (x::xs as l) -> l | [] -> raise ...
<mrvn>
In the case of rectypes as in (x x) you get x:('a->'b as 'a)->'b
<mrvn>
x has type 'a->'b and the argument ('a) too.
<pattern>
i haven't learned the "|" operator, or what it means to say "| []"
<Smerdyakov>
It's not really an operator.
<Smerdyakov>
And if you haven't learned that yet, it's time to read the part that tells you about it. =)
<pattern>
i will, definately
<pattern>
if i don't throw up my hands in despair after thi
<pattern>
s
<mrvn>
# let f = function false -> "false" | true -> "true";;
<mrvn>
val f : bool -> string = <fun>
<mrvn>
# f false;;
<mrvn>
- : string = "false"
<Smerdyakov>
If you haven't learned how to do pattern matching that doesn't always succeed yet, then you don't really know ML at all.
<Smerdyakov>
Sooo, giving up now would be a bad idea. =)
<pattern>
i don't know ml at all, that's for sure
<pattern>
but looking at how convoluted this whole type inference thing is does not make me hopefull that i'll ever know ml
<Smerdyakov>
It's not convoluted.
<pattern>
it makes me yearn for the simplicity of assembly language
<mrvn>
function a -> b | c -> d is the same as function x -> if x = a then b else if x = c then d else raise Match_failure
<mrvn>
pattern: you don't need to know how the type inference wotrks at all. You just have to know that it does it and sometimes why it doesn't or can't work.
<mrvn>
e.g. That let f x = x x;; can't work (unless you have -rectypes)
<mrvn>
Now you know why (x x) doesn't work so you can move on to the "fun" part.
<mrvn>
and match and |
<pattern>
so if you have -rectypes it automatically makes x:('a->'b as 'c)->'c ?
<pattern>
...when it sees (x x), that is
<mrvn>
I wouldn't worry about type inference too much. Here at university people are thought ocaml (and other similar langugaes) in on course and a term later they have a course about how the type inference in those languages actually works.
<Smerdyakov>
Ha.
<mrvn>
pattern: thats what the -rectypes adds to the normal typeing system.
<Smerdyakov>
I don't think there's a course on type inference.
<pattern>
yes, you mentioned that course... but i didn't know i had enrolled it in when you told me to figure out the y combinator :)
<mrvn>
you can do your masters thesis on them
<mrvn>
pattern: The y-combinator is something you see early when you do lambda calculus.
<pattern>
so do i need to figure out the types of an expression when i see it? or do i just type it in to ocaml's toplevel and see what it says?
<mrvn>
pattern: Then, when you move on to typed languages you quickly see that they fail to type it.
<mrvn>
pattern: 99.999% I just type it in as I think and see if it compiles.
<Smerdyakov>
You can implement the Y combinator in ML.
<pattern>
i see
<Smerdyakov>
Haven't you seen the comp.lang.ml FAQ? =)
<mrvn>
If it doesn't I check what ocaml things what type it is and compare it to what I think.
<pattern>
so when i type:
<pattern>
# let y f = ((fun x -> (fun z -> (f (fun y -> (x x) y) z)))
<pattern>
(fun x -> (fun z -> (f (fun y -> (x x) y) z))));;
<pattern>
val y : (('a -> 'b) -> 'a -> 'b) -> 'a -> 'b = <fun>
<mrvn>
pattern: That usually all you need to know.
<pattern>
what do i make of the last line?
<pattern>
what does 'a and 'b refer to?
<mrvn>
y takes two arguments: (('a -> 'b) -> 'a -> 'b) and 'a
<pattern>
don't i need to go through the whole type inference thing to figure it out?
<mrvn>
'a and 'b can be anything. But all 'a and 'b must be the same.
<mrvn>
For fac 'a=int and 'b=int
<mrvn>
But you can have 'a=int list and 'b=float array
<mrvn>
'a (or 'b) is a polymorphic type.
<pattern>
yep
<pattern>
ok, so maybe that was a bad example...
<pattern>
what about when we work with that example i asked you about earlier:
<mrvn>
'a->'b only tells you its a function, 'a->'a tells you its a function which return type equals its arguments type.
<pattern>
here, in order to see what 'c was we had to go through the whole type inference heuristic, didn't we?
<mrvn>
pattern: no, just to see that g is a function that takes the type of x as argument and so on
<mrvn>
We don#t know what 'c is but if we see g:int->int we know that x must be int
<mrvn>
The type inference makes a relation between the types of f, g and x.
<mrvn>
Is there a mode for emacs that pops up a bubble help containint the type of a variable if the mouse hovers over it?
<mrvn>
(or displays the type in the status line)
<pattern>
even if there was, i can't believe that i'd have to program by typing random things in to the editor and seeing if they work
<mrvn>
pattern: you programm what you want to do. The type inference makes sure you don't shoot yourself in the foot along the way.
<pattern>
well, i feel like shooting myself in the head now
<mrvn>
pattern: In many other languages you don't have types at all while you programm. At runtime the programm then just crashes or complains that the types don#t match up.
<mrvn>
In scheme you can write (+ 1 "Hallo")
<pattern>
not to be discouraging, but i think it's becoming clearer to me why functional languages, with all of their advantages, isn't used as widely as the imperative languages
<pattern>
aren't
<mrvn>
Of cause + doesn't work with an int and a string so when (if at all) the + is ever evaluated the programm will stop.
<pattern>
i'm still going to continue trying to learn ocaml, though... maybe i just need to read more and see this from some other perspectives before it clicks
<mrvn>
pattern: imperative languages have a big headstart and imperative is somewhat more intuitive at first.
<pattern>
"somewhat" is a huge understatement, from where i'm sitting
<mrvn>
pattern: Learn ocaml. Forget about type inference details. Just keep in mind that ocaml does it and look at the results.
<whee>
if your background is nothing but imperative, it would be somewhat difficult
<whee>
but I think you're stressing this too much, like mrvn says
<pattern>
but i have more than 20yrs imperative programming experience behind me... and maybe it's that that's somehow making functional concepts harder to grasp
<whee>
just try programming some things and see how it turns otu
<mrvn>
The problem is that you have grown up with recepies: 1. add the egg, 2. add flour, 3. add the milk, 4. steer, 5. cook, 6. eat
<mrvn>
1. open the latch, 2. put in the bateries, 3. close the hatch
<pattern>
or maybe it'd be easier if i learned functional programming as a kid, or i had a stronger math background... i don't know... but learning pretty much any imperative language is a breeze compared to learning a functional language... at least that's how i feel right now
<mrvn>
pattern: Only your first one.
<pattern>
whee, i think you're right... i think some practice programming would help
<mrvn>
You could have started with ml or scheme or some other untyped language.
<whee>
I didn't worry about what was going on when I first learn ocaml
<whee>
hell, I still don't know half the time :)
<mrvn>
just think of something small you would like to do (like draw a Mandelbrot fractal) and implement it.
<mrvn>
Or calculate prime numbers.
<pattern>
the tutorials and the ocaml book haven't proceeded with practical examples, so far... maybe they'll get to them later... so far it's been all theory and syntax
<mrvn>
pattern: Are you reading the O'Riley book?
<pattern>
but i've ordered The Functional Approach to Programming, by Guy Cousineau and Michel Mauny... maybe that'll be better
<pattern>
yes, i was reading the o'riley book
<mrvn>
How many pages without examples?
<pattern>
there are no page numbers in the html version
<pattern>
about 3/4 of the way down this looong page
<pattern>
i don't think they get to practical exercises for at least a chapter or two after this page
<pattern>
apart from this there's only the guy cosineau book in english from which to learn ocaml, afaik
<whee>
I learned it before the book was out, so :P
<pattern>
yeah, but did you already know functional programming?
<whee>
no
<pattern>
did you take a course on it?
<whee>
no
<whee>
I was in HS
<whee>
I knew C++, perl, python, other things of that nature
<mrvn>
If you know some languages the ocaml docs are quite helpfull. But you probably have to know some functional language to get an idea what your doing.
<pattern>
well, maybe i'm just slow now that i'm 32
<pattern>
or maybe it's because i haven't practiced writing anything
<whee>
I would guess it's that
<whee>
find something you want to write, and then write it
<pattern>
or maybe i'm just letting type inference discourage me too much
<whee>
use the book and manual as a reference, learning as you go
<mrvn>
I learned scheme first and then haskel and ml before finding ocaml onthe funtional side.
<mrvn>
pattern: type inference can be absolutly ignored, unless you make mistakes.
<pattern>
i've also ordered sicp... that teaches using scheme... maybe i should pick that up before trying ocaml
<pattern>
yeah, but you already knew other functional languages
<pattern>
i can learn an imperative language very quickly as well, since i know a billion of them already
<mrvn>
yeah. Its realy a crash course into ocamls syntax and features. You have to roughly know what your looking for to implement something and then look it up.
<pattern>
whee, no i haven't looked at the examples bundle
<mrvn>
pattern: Think of a small thing to implement and do that and if you get stuck ask.
<mrvn>
I find that way betterto learn a language than any book. Books are eigther far to long assuming you know nothing or far to short assuming you need a refference.
<pattern>
cool, thanks, whee
<pattern>
ok.. i will do just that
<pattern>
i'll try to program something
<pattern>
i'll start with an x server
<pattern>
just kidding :)
<mrvn>
pattern: Actually that would be nice.
<mrvn>
There is a Module that speacks the full X protocol where you could steal all the datatypes and such.
<Riastradh>
How difficult would it be to write an Objective-C/OCaml bridge?
<mrvn>
And Module Graphics has some drawing primitives, keyboard and mouse for you. :)
<Riastradh>
Or has anyone done it?
<mrvn>
Riastradh: you mean a compiler from Objective-C to ocaml?
<Riastradh>
No, a bridge, so you can instantiate Cocoa classes and call Cocoa methods from OCaml.
<mrvn>
You could use Corba
<Riastradh>
Cocoa being an Objective-C API, in case you didn't know.
<mrvn>
idl
<whee>
Riastradh: one doesn't exist, but it should be easy
<Riastradh>
What FM would I have to R to figure out how?
<whee>
haskell has one which is a full binding in a 16kb bz2, using template haskell (which we could do with camlp4)
<mrvn>
I saw some bridge for C++ code which could be worth a peak.
<whee>
could generate the ocaml object that references the objc one at compile time
<Riastradh>
Peek, and no it wouldn't. First, I refuse to deal in any way with C++; and C++ is also -WAY- too different from Objective-C for that to be useful at all.
<whee>
and because of the dynamic binding of objc, you could write one object yourself that all your ocaml objects would ultimately interact with
skylan_ has joined #ocaml
<whee>
it'd be a major pain to do each cocoa object by hand, so I really would recommend going the camlp4 route
skylan has quit [Read error: 110 (Connection timed out)]
<mrvn>
whee: google for "ocamlp4 tutorial" and you get slides for a talk about how to write a compiler for makefiles in a day using ocamlp4. Shou7ld give you some examples on how to parse the cocoa object sources.
<pattern>
i just skimmed through that today
<pattern>
looked neat
<pattern>
it's even geared towards people who don't yet know ocaml
<pattern>
lots of parallels in there between ocaml and c constructs... and it's pretty practical
<whee>
I've used camlp4 before, but there'd be no parsing of source involved most likely
docelic has joined #ocaml
docelic has quit ["Client Exiting"]
lament has joined #ocaml
docelic has joined #ocaml
mattam has quit [Read error: 110 (Connection timed out)]
polin8 has quit ["Lost terminal"]
polin8 has joined #ocaml
lament has quit ["Did you know that God's name is ERIS, and that He is a girl?"]
asqui has quit [Connection timed out]
docelic is now known as docelic|away
mattam has joined #ocaml
<pattern>
in the example wc.ml program i see:
<pattern>
let ic = open_in name in
<pattern>
count_channel ic;
<pattern>
close_in ic
<pattern>
doesn't "ic" only exist before that semicolon, after the "in"?
<pattern>
how can "close_in" refer to "ic"? isn't it out of scope?
<mellum>
there's an implicit "begin" .. "end" there
<pattern>
where? after the semicolon?
<mellum>
after in, spanning all ; expressions
<mellum>
actually, I am always a bit unsure about imlicit begins, I tend to add them explicitely
<pattern>
hmm
<pattern>
and where does the implicit "end" go?
<mellum>
before the next "in", I would think
<pattern>
unfortunately, though i'd always follow your example and use explicit "begin" and "end", i have to understand where these go if i am to understand these examples :(
TachYon76 has joined #ocaml
TachYon76 has quit [Client Quit]
docelic|away is now known as docelic
lament has joined #ocaml
TachYon26 has joined #ocaml
skylan_ is now known as skylan
lament has quit ["Did you know that God's name is ERIS, and that He is a girl?"]
mrvn_ has joined #ocaml
Torquemada has quit [Ping timeout: 14400 seconds]
mrvn has quit [Read error: 110 (Connection timed out)]
esabb has joined #ocaml
mellum has quit [Read error: 60 (Operation timed out)]
gehel has joined #ocaml
mellum has joined #ocaml
TachYon26 has quit ["bez ki³y nie ma zaliczenia (z prawd studentek AM)"]
<phubuh>
how do i explicitly end a match e with expression?
<steele>
match e with ( .. ) or match e with begin .. end
<phubuh>
oh, i see, thanks
<mrvn_>
Why would you ever need that? the -> ends the expression.
<mrvn_>
Do you mean (match e with expr) or begin match e with expr end?
<mrvn_>
Or is that equivalent?
mrvn_ is now known as mrvn
gene9 has joined #ocaml
gene9 has quit [Client Quit]
gehel is now known as gl
asqui has joined #ocaml
nkoza has quit [Read error: 60 (Operation timed out)]
nkoza has joined #ocaml
docelic has quit ["Client Exiting"]
docelic has joined #ocaml
docelic has quit [Remote closed the connection]
docelic has joined #ocaml
docelic has quit [Remote closed the connection]
docelic has joined #ocaml
docelic has quit [Remote closed the connection]
docelic has joined #ocaml
esabb has left #ocaml []
nkoza has quit [Read error: 104 (Connection reset by peer)]
merriam has quit [leguin.freenode.net irc.freenode.net]
gl has quit [leguin.freenode.net irc.freenode.net]
skylan has quit [leguin.freenode.net irc.freenode.net]
Zadeh has quit [leguin.freenode.net irc.freenode.net]
smkl has quit [leguin.freenode.net irc.freenode.net]
rox has quit [leguin.freenode.net irc.freenode.net]
xtrm has quit [leguin.freenode.net irc.freenode.net]
pattern has quit [leguin.freenode.net irc.freenode.net]
async has quit [leguin.freenode.net irc.freenode.net]
xkb has quit [leguin.freenode.net irc.freenode.net]
mellum has quit [leguin.freenode.net irc.freenode.net]
phubuh has quit [leguin.freenode.net irc.freenode.net]
docelic has quit [leguin.freenode.net irc.freenode.net]
mrvn has quit [leguin.freenode.net irc.freenode.net]
mattam has quit [leguin.freenode.net irc.freenode.net]
polin8 has quit [leguin.freenode.net irc.freenode.net]
foxster has quit [leguin.freenode.net irc.freenode.net]
mellum has joined #ocaml
gl has joined #ocaml
skylan has joined #ocaml
Zadeh has joined #ocaml
phubuh has joined #ocaml
smkl has joined #ocaml
rox has joined #ocaml
xtrm has joined #ocaml
pattern has joined #ocaml
xkb has joined #ocaml
async has joined #ocaml
asqui has quit [Excess Flood]
async has quit [leguin.freenode.net irc.freenode.net]
Zadeh has quit [leguin.freenode.net irc.freenode.net]
gl has quit [leguin.freenode.net irc.freenode.net]
xtrm has quit [leguin.freenode.net irc.freenode.net]
xkb has quit [leguin.freenode.net irc.freenode.net]
rox has quit [leguin.freenode.net irc.freenode.net]
pattern has quit [leguin.freenode.net irc.freenode.net]
skylan has quit [leguin.freenode.net irc.freenode.net]
smkl has quit [leguin.freenode.net irc.freenode.net]
phubuh has quit [leguin.freenode.net irc.freenode.net]
mellum has quit [leguin.freenode.net irc.freenode.net]
merriam has joined #ocaml
docelic has joined #ocaml
mrvn has joined #ocaml
mattam has joined #ocaml
polin8 has joined #ocaml
foxster has joined #ocaml
mellum has joined #ocaml
gl has joined #ocaml
skylan has joined #ocaml
Zadeh has joined #ocaml
phubuh has joined #ocaml
smkl has joined #ocaml
rox has joined #ocaml
xtrm has joined #ocaml
pattern has joined #ocaml
xkb has joined #ocaml
async has joined #ocaml
nkoza has joined #ocaml
nkoza has left #ocaml []
* Riastradh
hrms.
docelic has left #ocaml []
docelic has joined #ocaml
* Riastradh
pokes someone awake.
* emu
determinedly sleeps
* mrvn
jawns
* mellum
yawns
<mrvn>
mellum: By the way, wir haetten am Donnerstag den Schein bekommen
docelic has quit [Read error: 113 (No route to host)]
docelic has joined #ocaml
<mrvn>
Riastradh: Why do you wake sleeping dogs if you don't have dog food?
<Riastradh>
Oops, I wasn't paying attention to the channel.
<emu>
we'll just have to eat him instead
<Riastradh>
OCaml is complaining that: The files maths.cmo and maths.cmo disagree over interface Maths
<Riastradh>
...when trying to #load 'maths.cmo' after compiling: