ketty has quit [Read error: 110 (Connection timed out)]
ketty has joined #ocaml
kmag has left #ocaml []
Smerdyakov has quit ["Leaving"]
Snark has joined #ocaml
m3ga has joined #ocaml
Boojum has joined #ocaml
Snark has quit [Read error: 110 (Connection timed out)]
Boojum is now known as Snark
khaladan_ has joined #ocaml
khaladan has quit [Connection timed out]
revision17__ has joined #ocaml
Revision17 has quit [Read error: 110 (Connection timed out)]
_JusSx_ has joined #ocaml
smimou has joined #ocaml
m3ga has quit ["disappearing into the sunset"]
bzzbzz has quit ["leaving"]
joshcryer has quit [Read error: 110 (Connection timed out)]
joshcryer has joined #ocaml
Sysop_fb has quit ["going to georgia"]
Tachyon76 has joined #ocaml
Schmurtz has joined #ocaml
Myrizio has joined #ocaml
Thlayli has joined #ocaml
<Thlayli>
hi
<Thlayli>
is anybody here?
<zmdkrbou>
lo
<Thlayli>
could you answer me a newbie question please?
<zmdkrbou>
just ask
<Thlayli>
i found this line in my script: "let rec app x y = match x
<Thlayli>
with [] -> y
<Thlayli>
| x::xs -> x :: app xs y;;
<Thlayli>
"
<Thlayli>
now, i don't really know what x::xs stands for
<mauke>
:: is a list constructor
<zmdkrbou>
x::xs means adding the x element to the xs list
<Thlayli>
ah, very thanks
<zmdkrbou>
(at the beginning of the list of course)
<mauke>
isn't it easier to write that as let app = (@);; ?
<zmdkrbou>
yes it is :)
<zmdkrbou>
it's List.append you wrote here Thlayli
<Thlayli>
figured it out now :)
<Thlayli>
man, i just started learning ocaml, and by now i hate it
<zmdkrbou>
tss tss
<Thlayli>
it's all about recursion, is it?
<zmdkrbou>
it's the "right" way to use it yes
<Thlayli>
well, thanks for your help. i'll try somethings and if i have problems i'll come back here if you don't mind
<zmdkrbou>
if you're used to imperative style, no surprise functional programming looks strange to you
<mauke>
huhu, I don't like OCaml because it's not functional enough
<zmdkrbou>
mauke: :)
<Thlayli>
i'm the iterative guy. i use recursion whenever there's no other choice
<mauke>
I had to define id and $ myself!
<Thlayli>
you know: to iterate is human, to recurse is divine ^^
Tachyon76 has quit [Remote closed the connection]
<Thlayli>
ok, here are two more questions: In my script they seem to use a function called Dann(x,y) here and there, it is nowhere declared or defined in my script. And so I can't get the meaning of options (None, Some) which are explained by this example
<zmdkrbou>
is there an "open Bla" directive at the beginning of the file ?
<mauke>
Dann can't be a function
<mauke>
it's probably a constructor
<zmdkrbou>
oh yep it's Dann not dann
<Thlayli>
i just have some snippets in my script. this script is horrible. i can't stand it. the day after tomorrow i got a test for my diploma and i didn't quite start learning ocaml yet. I was thinking: Yet another programming language, no problem. Turns out to be a REAL BIG problem.
<zmdkrbou>
the problem is not "another programming language" its "another programmation style/paradigm/way of life"
<Thlayli>
so true
<mauke>
eh, OCaml is close enough to Perl to be immediately programmable
<Thlayli>
and i can only write Java, C, C++, PHP and query Databases via SQL :(
* zmdkrbou
: * scratching his head *
<Thlayli>
is it possible to learn the basics of ocaml until tomorrow if i work really hard?
<zmdkrbou>
is there functions in perl ? i mean with arguments ?
<zmdkrbou>
Thlayli: yep
<mauke>
zmdkrbou: sure
* zmdkrbou
doesn't know perl enough
<mauke>
it lacks static typing and autocurrying, but you get lexicals and closure
<zmdkrbou>
in perl5 ? because perl6 is supposed to have "everything one can need" :)
<mauke>
yeah, perl5
khaladan_ has quit [Read error: 104 (Connection reset by peer)]
smimram has joined #ocaml
smimram has quit ["bli"]
<ski>
(ketty : i think class types contain a hidden type-variable, or something like that)
<ketty>
hmm?
<ski>
<ketty> ok, another question: why do class types and normal types behave differently?
<ski>
iirc, a class type is "open" in the sense that it can still be extended ("subclassed"), to e.g. contain more methods
<ski>
this is modelled by a type-variable (which is invisible in the usual syntax, but is still there)
<ketty>
hmm
<ketty>
is there any benefit of normal types to not be "open"?
<ski>
when you instantiate an object, from a class, that will fix the type-variable (e.g. it will fix the "self-type" to the current type), so the type of an object is normal
<ski>
well, when you define a new type (or a type-alias) using some old type(s), then you must mention every type variable as a parameter to the new type
<ski>
if the type variable is hidden, you can't do this
<ski>
type foo = Foo of 'a list;; (* not ok *)
<ski>
type 'a foo = Foo of 'a list;; (* ok *)
<ketty>
so the hidden type variable in class types are ".."?
<ketty>
it would be neat if i could write #type_name as well as #class_name to specify sub typing...
<ski>
for 'type_name' being a class type ?
<ketty>
type type_name = < m : int; m2 : unit >
<ketty>
like this...
<ski>
but 'type_name' isn't an open type, there, i think
<ketty>
i'd like '#' to make it open :)
<ski>
i think there is no unique way to do that (ignoring the other problems with such a thing)
<ski>
really, the '#' thing on class types is slightly ugly
Skal has joined #ocaml
<ski>
it would be nicer if 'class_name' was the open type (which is now written as '#class_name') while '#class_name' would be the closed type (which is now written as 'class_name')
<ketty>
hmm...
<ski>
since the class type is really the open one, and the closed one is derived from that, so the open is the primary one, here
<ketty>
i still dont see the problem of creating open types from closed one...
<ketty>
you don't need to affect the orginal type
<ketty>
i just want a new one...
<ski>
where should you introduce the type variables ?
<ketty>
hmm?
<ketty>
hmm
<ski>
iirc, at least for class types, the type variable is used for (late) recursive things, like late binding and open recursion of methods
revision17__ has quit ["Ex-Chat"]
<ski>
if you have an closed object type with two methods, both returning things of same type as whole object type, how would you know if one or the other (or both or none) of the methods was meant to return "self-type", or otherwise still this object type ?
* ski
tries to remember syntax for naming "self-type" in object types
<ketty>
i would now that they return a sub type... (ie same or compatible type)
<ketty>
i would not know the exact type
<ketty>
kind of like private types...
<ski>
yes, but in some cases, the open type one wanted would *fix* a certain recursive occurance of the type to a *closed* variant, not to an *open* one
<ketty>
hmm?
<ketty>
i dont really understand now...
<ketty>
ehh... maybe what i really want is just private types...
<ketty>
so with normal open types... another part of the program can also make objects that satisfies the type...
<ketty>
and then things might start getting ugly.. ^^
<ketty>
im i on the right track?
<ski>
# class type t = object ('self) method m0 : t method m1 : 'self end;;
<ski>
class type t = object ('a) method m0 : t method m1 : 'a end
<Smerdyakov>
ski, anonymous CVS, and you might even be able to figure out how to run it. ;)
<ski>
in the type of an actual object, all the openeness are resolved already
<ski>
Smerdyakov : i looked around at the site and didn't find how to access the cvs (yes, i'm not very used to cvs)
<ski>
s/openeness/openness/
<Smerdyakov>
It's the standard SourceForge thing. You can access any project's CVS repo uniformly.
<ketty>
# class type t = object ('self) method m0 : t method m1 : 'self end;;
<ketty>
class type t = object ('a) method m0 : t method m1 : 'a end
* ski
goes to figure how how that is done, then ..
<ketty>
hmm..
<ketty>
same :)
* ski
is an idiot .. mental note to self : it's spelled 'Laconic', not 'Lakonic'
<ketty>
problem is that there is no way to specify "self" in type t = < m0 : t; m1 : t> ?
<ski>
ketty : there is no "'self" there
<ski>
it's not open
<ski>
(and you wanted a way to convert closed to open types)
<ketty>
well it might still be done :)
<ketty>
just make all recursive stuff closed :)
<ski>
not in a unique way
<ski>
no
<ski>
you need to *undo* recursive binding, to make it work
<ketty>
hmm?
<ski>
and that's not possible in a unique way
<ski>
in an open class type, the "'self" is just a type variable .. to close it, you instantiate it with the whole type, more or less (iirc)
<ketty>
an open type would be: < m0: t; m1: t; .. >
<ketty>
with t still being the closed type...
<ketty>
what is there that should be undone?
<ski>
"t" would be which type, did you say ?
<ski>
the undoing would be when trying to convert a closed type to a corresponding open type
<ketty>
t is still = < m0: t; m1: t >
<ski>
ok, yes then
<ski>
< m0: t; m1: t; .. >
<ski>
is a possible corresponding open type
<ski>
but
<ski>
< m0: t; m1: 't2; .. > as 't2
<ski>
also is one
<ski>
< m0: 't2; m1: t; .. > as 't2
<ski>
and
<ski>
< m0: 't2; m1: 't2; .. > as 't2
<ski>
are two more possible ones
<ski>
all of those have the original closed type as corresponding closed type
<ski>
anyone of these 4 open types could have been the intended one
<ketty>
if there is a way to specify which i want i would be happy.. but if not, im happy with just one of them :)
<ski>
if it's not unique, i'd not be happy with an arbitrary one of them :)
<ketty>
well.. not arbitrary.. there should be a default choice..
<ketty>
like allways my example or allways: < m0: 't2; m1: 't2; .. > as 't2
<ski>
also, i'm not sure, but possibly there can be cases where we can't know (because of module system hiding) if a type occuring inside the whole object type is a type that could possibly be replaced by the "'self" type-variable
<ketty>
if we treat everything inside the type definition as closed would there still be a problem?
<ski>
what if we have
<ski>
type t = < ...< ...t... >...>
<ski>
hrm
<ski>
no, say
<ski>
type t = < ...t... >
<ski>
as opposed to
<ski>
type t = < ...u... >
<ski>
and u = < ...t... >
<ketty>
id go for not touching the type of t..
<ski>
logically, i'd expect these two types to behave the same (their bodies are the same, except they refer to each other, for recursion)
<ski>
but with the proposed closed->open conversion, wouldn't it have to compare types for "identity" ?
<ketty>
maybe conversion is not the right word...
<ketty>
maybe its more like creating a new type
Revision17 has joined #ocaml
<ski>
(i think that doesn't matter much, for the issue here ..)
<ketty>
so #t = t_open = < ...u... >
<ketty>
where u is still < ...t... >
<ketty>
and t is still t :)
<ketty>
ehhh...
<ski>
but then that isn't same as doing the conversion on
<ski>
type t = < ...t... >
<ski>
right ?
<ketty>
of course i mean t_open is = < ...u...; ..>
<ketty>
hmm?
<ketty>
#< ...t... > = < ...t...; .. >
<ketty>
#(< ...t... > as t) = < ...t...; .. >
<ski>
(was that second a correction ?)
<ketty>
#(< ...<...t...>...> as t) = <...<...t...>...; ..>
<ski>
hm
<ketty>
yes that was a correction
<ski>
i think this is more or less the same issue as untangling a normal recursive type ..
<ketty>
mm?
<ski>
so, i think if there is no unique way to do this (which there generally isn't), i'd prefer to not have anything like this, at all
<ketty>
ok...
<ketty>
i still want it :)
<ketty>
hmm...
<ski>
what is a situation in which you'd like it ?
<ketty>
type t = [ `A of t | `B ]
<ketty>
# type t2 = #t;;
<ketty>
Warning D: this syntax is deprecated.
<ketty>
A type variable is unbound in this type declaration.
<ketty>
In definition [< t ] the variable 'a is unbound
<ketty>
hmm... this looks scary :)
<ketty>
maybe what i realy want is to make an open private type of a closed one...
<ski>
why not specify directly in the open type, which early and late recursions you want ?
<ketty>
hmm... the orginal problem was probably that i wanted to use the < ... > syntax instead of the object ... end one :)
<ski>
(for types ?)
<ketty>
yes
<ski>
i can't recall why both exists, atm, actually
<ketty>
i think it is a bit weird to...
<ski>
(hm, re the '#t' for polymorphic variants : "Use of #-types to abbreviate variant types is deprecated. If t is an exact variant type then #t translates to [< t], and #t[> `tag1 ...`tagk] translates to [< t > `tag1 ...`tagk]")
<ketty>
hmm.. what does the last mean?
<ski>
'[< t > ...]' ?
<ketty>
yes..
<ketty>
and [> ...] also...
<ski>
i don't recall details .. look up polymorphic variants
<ketty>
ok
<ski>
it has to do with allowing more and less variants, and which are know to possibly appear, or something like that, iirc
<ski>
hm, from what i can see in the manual the '< ... >' construction is the only one for a type expression describing an object type
<ski>
'object ... end' seems to be used in 'class type' definitions
<ketty>
yes..
<ketty>
i want the behaviour of class types and the syntax of object types :)
<Thlayli>
hi again, i'd have another question concerning lists...i still don't get them :(
<Thlayli>
in line 3: where does hd suddenly come from?
<mauke>
from Pervasives
<ketty>
it is the first element
<mauke>
er, wait
<Thlayli>
hd always the first element?
<ketty>
yes
<Thlayli>
i thought it's a new constructed list
<mauke>
no, the opposite
<mauke>
it destructs the passed list
<Thlayli>
but if hd is an element
<Thlayli>
how can i call tail on it
<Thlayli>
and what does "->" mean? didn't appear in my tutorial yet
<mauke>
where does it do that?
<mauke>
-> separates the pattern from the associated code
<ketty>
tail is the rest of the list
<Thlayli>
ah
<Thlayli>
i know that tail is the rest of the list
<Thlayli>
but i don't get it
<Thlayli>
if hd is an element
<Thlayli>
how can i call tail on it??
<ketty>
where do you call tail on it?
<Thlayli>
or is a hd a list with one element?
<mauke>
where does it do that?
<Thlayli>
in line 3: hd::tail
<ketty>
no it is just an element
<mauke>
Thlayli: that doesn't call anything
<Thlayli>
i'm somewhat thinking in c++
<mauke>
it looks at the list l and binds the first element to "hd" and the rest to "tail"
<ski>
| hd::tail ->
<ski>
that introduces two new (local) variables 'hd','tail'
<ski>
'hd' is the first element of the list 'l', (which is matched upon)
<ski>
'tail' is the rest of the list 'l'
<Thlayli>
ah
<Thlayli>
but i consider this code kinda confusing
<ski>
'match' is a bit like a 'switch' in C++, except it also introduces new variables
<Thlayli>
ok, i got that now
<ski>
instead of just matching against constants, you can also match the list against the "shape"/"pattern", 'hd::tail', and if that matching succeeds, then 'hd' is now the first element, and 'tail' is the rest
<Thlayli>
so in line 6
<Thlayli>
x is also the head and xs the tail?
<Thlayli>
of list l?
<Thlayli>
:(
<Thlayli>
*cry*
<mauke>
yeah, but that's a different l
<mauke>
this code is confusing
Skal has quit [Remote closed the connection]
<Thlayli>
i'm sorry to bother you with my stupid questions. i'll just search me another tutorial and maybe i understand this thing tonight
<Thlayli>
at least i understood the concept of currying and some more things. but these lists drive me MAD, MAD MAAAAAAD
<Thlayli>
i'll try somethings with the interpreter now
<ski>
Thlayli : 'construct a new head and a new tail called x and xs' should more properly be 'get the head x and tail xs of the list argument of the local function'
<Thlayli>
i thank you too, ski
<Thlayli>
god bless this channel
<ski>
Thlayli : 'return whatever is smaller, x or m' should be 'pass on, whatever is smaller, x or m, as "last min-value" to the tail-recursive call'
<ski>
Thlayli : yw
<ski>
Thlayli : did you look at mauke's version, with more readable indentation ?
<ski>
regarding the 'Some' around the initial call to the local function .. instead of having null-pointers, where a pointer either is a normal object or a null pointer, you in OCaml have to say explicitely when you except possible "null-pointers" (so, if you don't say this, it's impossible to get a null-pointer :)
<ski>
so, if you *could*have* returned a "null-pointer" (i.e. 'None') but actually didn't, in this case, you need to wrap the result you want returned in 'Some' to tell that it's not 'None'
<ski>
Thlayli : was that understandable ?
<mauke>
this is more or less the same in C++: instead of T and return x; you have T * and return NULL or return new T (x);
<Thlayli>
that made it clear. i owe you guys something.
<mikeX>
hm, I see ski, actually the example I pasted was taken out of context from a lexer i've build, I'm not sure type variants would be such a good idea there, but then again i'm not too experienced with ocaml
<ski>
mhm
mauke has quit [Read error: 110 (Connection timed out)]
shawn has quit ["This computer has gone to sleep"]
<Myrizio>
hi, can i have a match that matches functions or non-functions?
Snark has left #ocaml []
<Myrizio>
i would like to write something like: match x with (x : 'a->'b) -> () | with (x : 'a) -> ();;
<Myrizio>
but the above code make the inference engine PRETEND that x is a function :)
<ketty>
and the type of the match is in this case: 'a -> unit ?
<Myrizio>
i would like the type of the match to be 'a -> unit :)
<ketty>
i don't think what you want is possible :(
<Myrizio>
but in the above code the type is ('a->'b) -> unit
<Myrizio>
argh, BTW thanks :)
<pango>
match works on values, not types
<pango>
and functions are abstract values
<Myrizio>
i was trying to write a function that wraps a generic function f executing a function g' after it...
<Myrizio>
pango: i understand...
<pango>
sounds like 'compose' function ?
<Myrizio>
mh, a bit...
<ketty>
is the type of the generic function unit -> 'a or 'a -> 'a ?
<ketty>
or 'a -> 'b or whatever?
<Myrizio>
i wanted the generic function be really generic, let's say a'->b'
<ketty>
then how do you apply it to a value?
<ketty>
if you dont know what value it want?
<Myrizio>
not really a compose, befause i want to return the value returned by f
<Myrizio>
ketty i don't understand :(
<ketty>
how do you what to call / execute the generic function?
<ketty>
what argument do you want to pass to it?
<pango>
ok, so I guess g' does side effects, it must be non purely functional ?
<Myrizio>
pango: yes
<Myrizio>
i'm coming from evil imperative languages...
joshcryer has quit [Read error: 110 (Connection timed out)]
<Myrizio>
:)
<Myrizio>
i want a "wrap f g" to return a function that is like f and returns the same values as f
<Myrizio>
i try to explain...
<ketty>
and the type of g is: unit -> unit ?
<pango>
let wrapper f g = (fun x -> let result = f x in g (); result) ?
<Myrizio>
let's say g is unit -> unit, yes
<Myrizio>
pango: uh! :)
<ketty>
i think that is possible...
<pango>
# wrapper (fun x -> x + 2) (fun () -> print_endline "I was there") 4 ;;
<pango>
I was there
<pango>
- : int = 6
<pango>
# wrapper (fun x y -> x + y) (fun () -> print_endline "I was there") 2 4 ;;
<pango>
I was there
<pango>
- : int = 6
slipstream has joined #ocaml
<ketty>
so: ('a -> 'b) -> (unit -> unit) -> 'a -> 'b
<Myrizio>
pango: this has the problem that g is executed after that i just apply the first argument of f
mauke_ is now known as mauke
<Myrizio>
that is why i have to understand if "result" is still a function (with less parameters)
<pango>
got a too strong headache atm to think about it
<ketty>
let w f g = fun x -> let r = f x in g (); r;;
<ketty>
like this?
<Myrizio>
pango: sorry :)
<Myrizio>
ketty: this that it is exactly like pango's...
<ketty>
yes?
<Myrizio>
anyway thanks guys :)
<Myrizio>
i mean:
<Myrizio>
if f takes 2 parameters
<Myrizio>
i will:
<Myrizio>
1 - apply one paramters to f
<Myrizio>
2 - call g
<Myrizio>
3 - apply the other parameter to f
<Myrizio>
i was trying to push g to the last parameter application :)
<ketty>
i see...
<Myrizio>
BTW maybe this is a too silly question :)
<ketty>
you could use lazy evaluation...
<ketty>
maybe :)
<Myrizio>
ketty: ah, intersting this :)
shawn has joined #ocaml
slipstream-- has quit [Success]
<pango>
imo, you should write wrappers for functions with 2, 3,... parameters, and see how they relate to each other, and if you can express wrapper for function with n parameters using wrapper for functions with n-1 parameters
<pango>
I doubt there's a universal wrapper for any number of argument, specially in a strongly static typed language
<pango>
let wrapper2 f g = (fun x -> wrapper (f x) g)
<pango>
let wrapper3 f g = (fun x -> wrapper2 (f x) g)
<Myrizio>
pango: eh, this is what i was afraid of...
<Myrizio>
there is no way in OCaml of getting the (maximum) number of arguments of a function, isn't it?
<pango>
there's no introspection
<Myrizio>
eh, ok, thanks.
<pango>
and functions are abstract values
<Myrizio>
excuse me, but what is an "abstract value" exactly?
<pango>
that you cannot, among thing, deconstruct that value (like in lisp)
<mauke>
let num_of_args f = 1;;
<Myrizio>
pango: thanks!
vinceviper has joined #ocaml
vitriol_ has joined #ocaml
<Myrizio>
in ocaml can i have a generic function with different specializations?
<ketty>
no, but there is a variant called gcaml where you can do that...
<Myrizio>
ah, thanks ketty!
<pango>
what do you mean by "specialization" ?
<pango>
I think you should look at functors
<Myrizio>
i mean that i can have i function 'a->'a, but i cannot decide that the function could have a different implementation if called as int->int
<pango>
compiler does not do specialization
<pango>
there's is (was ?) a package called ocamldefun to "unroll" functors, but I don't know if it still works with recent versions of ocaml
<ketty>
all it does is inlining the functors, right?
<pango>
yes, which should improve compilation result
<ketty>
yes.. so the program runs faster.. but there is no change in how i write the program...
<pango>
ketty: what do you mean ?
<ketty>
hmm..
<ketty>
its like a optimization flag to the compiler...
<ketty>
which is great..
<ketty>
but it is nothing i have to think about (much) when i write the code..
<ketty>
right?
<pango>
it should improve the performance of applied functors, that's all
<ketty>
yes.. and the reason i don't currently use functors is because i haven't learned to use them yet... i am completely ignorant to performance issues :)
<pango>
they're really useful, for example in situations where you would have used templates in other languages
<pango>
however they rely on polymorphism, so there's a higher runtime cost
<Myrizio>
interesting...
* Myrizio
must absolutely try GCaml :)
vitriol_ has quit ["Leaving"]
Smerdyakov has quit ["Leaving"]
_JusSx_ has quit ["leaving"]
<Thlayli>
hmm, i just read the wikipedia Ocaml page
<Thlayli>
there seems to be an error on it
<Thlayli>
in the paragraph "Birthday Paradox"
<Thlayli>
the formula seems to be wrong
<Thlayli>
can anyone confirm this? the program output is 23 people. i calculated by hand 20 people.
<Thlayli>
and i doubt i made a mistake
smimou has quit ["bli"]
Schmurtz has quit ["Plouf !"]
<Myrizio>
Thlayli: i'm sure that the correct solution for the Birthday Paradox is 23.
<Myrizio>
of course if the result is correct, this do not prove that the program is correct :)
<Thlayli>
hmm, i forgot some special cases in my calculations
<Thlayli>
for example i did not think about all people sharing the same birthday for example
<Thlayli>
i just read it and was thinking wtf?? where does that forumla come from
<pango>
just follow "birthday paradox" link from that page
<Thlayli>
can i append an element to a list with the @ operator like "list@2" for an integer list?
<ketty>
yes: list @ [2]
<Thlayli>
thx
<pango>
complexity is O(length list) however
<pango>
if you plan to do that often, better build the list is reverse order, then use List.rev as a very last step
<Thlayli>
hmm, i tried to fill a list with an infinite number of naturals
<Thlayli>
however my code is rejected by the interpreter :(
<Thlayli>
This expression has type 'a list ref but is here used with type 'b list
<Thlayli>
this is the line: naturals := naturals@[start];
<pango>
you need ! to dereference a reference
<pango>
naturals := !naturals @ [start]
<Thlayli>
ah
<Thlayli>
thanks
<Thlayli>
it's my first day with OCaml :D
<pango>
then again, lists aren't symetric, it's much easier to add elements to the front
<pango>
(and to remove them too)
<Thlayli>
ok, i'll remember this advice
<pango>
:: reuses the existing list, whereas @ needs to build a totally new list using the elements of the first list argument