Yurik changed the topic of #ocaml to: http://icfpcontest.cse.ogi.edu/ -- OCaml wins | http://www.ocaml.org/ | http://caml.inria.fr/oreilly-book/ | http://icfp2002.cs.brown.edu/ | SWIG now supports OCaml| Early releases of OCamlBDB and OCamlGettext are available
hitachi has joined #ocaml
foxster has quit [Read error: 110 (Connection timed out)]
foxster has joined #ocaml
GnuVince has joined #ocaml
GnuVince has left #ocaml []
lament has joined #ocaml
hitachi has left #ocaml []
dskippy has joined #ocaml
Kinners has joined #ocaml
sproctor has joined #ocaml
<dskippy> I have a question about the object system in ocaml. In languages like Java and PLT Scheme, I am able to use "this" or "self" in calls to functions that retain that value. I am not allowed to in ocaml.
<dskippy> I have found this to be a really big hurdle in my current project and I was wondering how you guys solve this problem.
<dskippy> Concretely, I have a class and I want to have a list of all objects that are instantiated from this class in global scope. I can easily create a function that wraps the instantiation, but I want this class to be able to remove an object from the list when the object is no longer needed too.
<seth_> dskippy: you can do that in ocaml
<dskippy> seth_: How would I do that?
<seth_> you just, on the object line, use a statement like object(self) then self refers to the object
<dskippy> Oh, really? Wow.
<dskippy> And that fixes a "self type cannot escape its class" error message?
<Riastradh> And you can use whatever name you like -- object(self), object(this), object(sfquibble)
<seth_> dskippy: I'd have to see the specific code, but there are ways to get around the message.
<dskippy> I can give an example.
<dskippy> I can put this on the web in just a moment. I'll need to strip it down to just show the problem.
<dskippy> But I think I've miss understood your responce.
<dskippy> You must be talking about the class definition when you say object(self)
<dskippy> My problem is when I reference self in the class to say something like "globalList := self :: !globalList" in the methods... it gives me that error I mentioned.
<seth_> dskippy: but there is another way to do that. look at the syntax: {< ... >}
<dskippy> seth_: Could you give some short example of what you mean?
<seth_> dskippy: for your example, you probably just need to make globalList mutable, instead of a reference
<seth_> dskippy: in the manual in the objects chapter, there is a section about applicative style changes to class members where that syntax is explained.
<seth_> dskippy: I think their explanation is probably more clear than mine would be.
<dskippy> seth_: Fair enough. I have my example ready.
<seth_> dskippy: I'd have to see the code where you are using self in the above, and I can tell you how I would handle it.
<seth_> dskippy: ok...
<dskippy> I'll put it on the web.
<dskippy> y/player.ml
<dskippy> Oops.
<seth_> do this:
<seth_> class player =
<seth_> object(self)
<seth_> val mutable active_players = [];
<seth_> method logout () =
<seth_> wait a moment, I see what you are doing now...
<seth_> your class is the member of the list
<dskippy> Well, the list is a list of objects that are of my class.
<seth_> dskippy: don't use a list, use a set. then use the method to delete a member of the set.
<seth_> Set.remove
<seth_> to do that, you need a compare method to make it a proper OrderedType
<seth_> then you use the Set functor
<seth_> It isn't difficult although if you aren't familiar with the terminology it can be confusing.
<dskippy> seth_: Why does the set data type allow this and not the list?
<seth_> dskippy: the set has a method to remove a member. you can do it with a list, but it is more difficult as you have to code that part yourself.
<seth_> lists are easier to add to than to remove from.
<dskippy> seth_: I need to code removal you mean?
<seth_> right
<dskippy> Well I have a filter operation
mattam has quit [Read error: 110 (Connection timed out)]
<dskippy> And I'm setting the list to the filter of the list itself.
<seth_> that's fine, if that works for you. However, if you have set functionality, why not use a set?
<dskippy> seth_: It may be hard for us to order them.
<seth_> dskippy: you could also use the hash table data structure. But that is kind of orthogonal to your original question, which is how to handle the class operations.
<dskippy> seth_: I would like use set since it is probablly the most apporpriate data type... But I would like to learn how to make it work with lists so that I know why it failed my way.
<dskippy> seth_: How would I go about simple editing the existing example so that it works?
<seth_> at some point you are invoking logout on your class object. but there is really no need for that to be a class method. just create a function that modifies the list, and provide the class object as an argument.
<seth_> instead of classobject#logout, just do logout classobject
<seth_> the former is the more OO way to do it, but it really has no advantage here.
<Riastradh> Methods should generally be used only when you want lexical capture.
<Riastradh> With 'logout,' nothing lexical about the player need be captured.
<dskippy> seth_: I understand that way of doing it... But I want to learn how to make a list data type of my own that has the property of allowing this reference like the set data type does.
<seth_> dskippy: well, you are correct in the sense that you can't use the self reference in that way here. But it isn't necessary.
<seth_> you could make some convoluted code that does it, but it would be really ugly.
<dskippy> seth_: I should rephrase to make sure I'm clear.
<seth_> ok
<dskippy> I currently have given an example that uses lists and it is not working do to self reference rules.
<dskippy> You mentioned using a set in the same manner because a set would work.
<seth_> correct, and you can't use self that way. But, there is fundamentally nothing better about saying (add me to the list) as opposed to "add this object to a list"
<seth_> no, a set would have the same problem.
<seth_> as far as using the self reference
<dskippy> I want to know what is different about the set and list data structure and as a way to learn the language better I want to implement a list data structure that has the same property as the set so that it works in my case.
<dskippy> Oh I see.
<dskippy> I guess that makes me less confused the.
<dskippy> then
<seth_> what I'm saying is that the inability to do this doesn't really cost you anything.
<dskippy> seth_: It may cost me code organization.
<seth_> No, in this case it doesn't. You lose nothing that OO has, at least nothing of value. Because there is no true encapsulation (of data and methods) here.
<dskippy> So just to be clear, it is impossible to use "self" like this and I need to write a function that takes my object as a perameter instead of a method inorder to do it.
<seth_> Yes, but why is that a problem?
<seth_> why is self#logout fundamentally different than logout self?
<seth_> in both cases you have to reference the correct object.
<dskippy> seth_: In our real code there is a private field connection which must be closed.
<seth_> In both cases you have the same (potential) problem of referencing the wrong object.
<seth_> dskippy: then logout can invoke classobject#close
<seth_> and you still lose no encapsulation
<dskippy> By writing a function to do this I'm adding a level of indirection that would not be needed.
<seth_> what you don't have here, that would be nice, is the equivalent of a destructor. But that is a different issue.
<seth_> No, there is no additional level of indirection, just a difference in where the class method is invoked.
<seth_> Your problem would also go away if you make a class for the list object.
<seth_> and invoke methods on that class
<dskippy> What I loose is this. A class has a predefined interface of methods that can be called on it. logout is no longer part of this interface, since it is a seperate function. I now have a heterogenous group of functions and method that act on my object.
<seth_> But that is a false objection, because active_players in your example is a global, which is even worse.
<dskippy> seth_: What do you mean by "Your problem would also go away if you make a class for the list object"?
<dskippy> seth_: The global has nothing to do with the problem. It's just a reduced example.
<seth_> it makes more sense to have a class that manages the collection. That way you invoke logout on the collection, which is then smart enough to do whatever is required to logout.
<dskippy> seth_: How would the class tell the list class it needed to be logged out?
<seth_> well, I can't comment on that if the reduced example is inaccurate. But there is no advantage to having a self#logout method that invokes a global, compared to a logout method (which I'm saying should be a class method on the collection class that I think you should create) with an argument.
<seth_> dskippy: You could, although I doubt this is the best code:
<dskippy> The example is not inaccurate. It just has a global which is bad form and can be ignored.
<seth_> class player listThing =
<seth_> object(self)
<sproctor> I updated the example at http://www.rottenvegetable.org/~dskippy/player.ml to more accurately describe our problem.
<seth_> method logout =
<reltuk> I don't understand what fold left does...
<seth_> list#removeMe
<Riastradh> reltuk - It's an iterator.
<seth_> OK, let me look at the updated example
<Riastradh> That is...
<Riastradh> It's a very general-purpose iterator over lists.
<Riastradh> I don't know exactly which order arguments go in OCaml, but the basic idea of it is this:
<Riastradh> foldl kons knil [];; (* ==> knil *)
<Riastradh> foldl kons knil (head :: tail);; (* ==> foldl kons (kons head knil) tail *)
<seth_> sproctor: active_players is still a global, so I don't see what changed here.
<seth_> sproctor: but there is absolutely no gain in using a class method when all the class method is doing is referring to itself.
<sproctor> player implements controller.
<seth_> sproctor: you still have classobject#logout vs. logout classobject, which doesn't matter.
<seth_> sproctor: but controller does nothing. there is no need to create a class to produce a signature. ocaml has signatures for that.
<reltuk> Riastradh : It applies the function to the first element of the list and the "Seed" so to speak, applies the function with the result and hte second element, applies that result and the third element...
<seth_> sproctor: OO languages force you to use OO features whether you need them or not. In an environment with more options, you want to examine all the alternatives, not assume that the OO paradigm is the best way.
<sproctor> player needs to be defined after character, so the function to act on it needs to be defined after, right?
<seth_> sproctor: usually I'm arguing the other side of this, because I use classes more than most ocaml folks, but here I don't see it.
<Riastradh> reltuk - Yes.
<sproctor> I'm not familiar with signatures, maybe they solve this problem.
<seth_> sproctor: well, there is a syntax for mutually dependent classes, but I don't think that is what you are asking.
<Riastradh> reltuk - Are you having some difficulty understanding this or something?
<reltuk> nah, I got it now...
<Riastradh> OK, good.
<reltuk> of course, still got the rest of the language to get :-p
<reltuk> I'm on chapter two of the translated o'rielly book
<reltuk> specifically the exercises :-p
<sproctor> right, character doesn't need to know about player, just controller, and player implements a method of controller.
<seth_> sproctor: maybe this is also a reduced example, but I also see no point to the c:character argument on class player.
<sproctor> seth_, it's very much reduced. player needs to have a character passed to it.
<sproctor> I could post up all of the code if you want to look at it, but I think it would be a larger burden.
<seth_> sproctor: ok. what I was saying about signatures is this. You should use a class when there is a need to encapsulate data with methods. You don't need to use a class to specify an interface. The big problem with pure OO languages is that the design primatives are overloaded. Don't carry that over to an environment where it isn't necessary.
<seth_> sproctor: in OO, you want to specialize, you use a class. you want to define an interface, you use a class. you want to encapsulate, you use a class. It makes a very large mess.
<seth_> I'll be back in about 1/2 hour, all.
<sproctor> seth_, thanks.
<sproctor> we're thinking about it now.
<dskippy> Thank you.
<reltuk> what's @ symbol do?
<sproctor> concatenation of lists
<reltuk> will it concatenate a scalar onto a list
<sproctor> no
<reltuk> so I should do like... 3::[] @ list?
<sproctor> 3::somelist
<sproctor> or [3]@somelist
<reltuk> "This expression has type 'a list -> 'b but is here used with type 'a list"
<reltuk> I think my function is retarded...
<Smerdyakov> Or you are forgetting to pass a curried parameter....
<sproctor> or forgetting parentheses
<sproctor> if it were me, it'd be the latter.
<Smerdyakov> But that is syntactically impossible, so no worry! (Could be "if it were I," though! ;-)
<reltuk> hmm...
<reltuk> I'll post it...
<reltuk> it's probably completely wrong...my first time to try to write a function
<reltuk> it's supposed to take two sorted lists and make a big sorted list
<Smerdyakov> Your function looks like it will break if passed two empty lists.
<reltuk> yeah, probably
<Smerdyakov> And what are those zany commas doing in there for the recursive calls?
<reltuk> oh! that's so wrong
<Smerdyakov> And a::L is much faster than [a]@L
<Smerdyakov> LIKE 8 MILLION TIMES FASTER
<Smerdyakov> ;-)
<reltuk> hehe
<Smerdyakov> Well, L@[a] is the real slow one.
<Smerdyakov> But you'd might as well use a::L if possible.
<reltuk> can I break it down like l1head::l1tail, l2head::l2tail in the match?
<Smerdyakov> Yes, but, of course, that requires that both lists are nonempty.
<Smerdyakov> Hence, you have no case for two empty parameters.
<reltuk> yeah, I added...
<Smerdyakov> But the question is, why are you breaking up the head and tail in the first two cases?
<reltuk> no...
<Smerdyakov> I don't think that was a yes/no question. =)
<reltuk> hah
<reltuk> how can I do like "l1head::merge_i l1tail l2head::l2tail"?
<reltuk> see, that would be l1head::(merge_i l1tail l2)
<Riastradh> Isn't (::) right-associative?
<Smerdyakov> No, it's wrong associative, as a sort of masochism.
<Smerdyakov> reltuk, did you answer your own question?
<reltuk> masochism.
<reltuk> <Smerdyakov> reltuk, did you answer your own question?
<reltuk> hoops
<reltuk> no...that above doesn't work
<Smerdyakov> Well, you left out l2head....
<reltuk> I get: This expression has type 'a list * 'a list but is here used with type 'a list
<reltuk> on the l1head::(merge_i l1tail t2)
<Smerdyakov> reltuk, hm.... I don't see why, offhand.
<reltuk> what's 'a list * 'a list?
<reltuk> isn't that a tuple?
<Smerdyakov> Yes.
<Smerdyakov> A pair of 'a lists.
<reltuk> but there shouldn't be a tuple in there...t2 or l1tail shouldn't be a tuple, and merge_i doesn't return tuples...
baader has joined #ocaml
sproctor has left #ocaml []
dskippy has quit ["[BX] Hanson uses BitchX. Mommy, can we dress like boys again?"]
<Kinners> reltuk: don't use as t1 and as t2, just use l1 and l2
<Kinners> reltuk: but the problem is that it's treated as (a as t1, b) as t2
pattern_ has quit [leguin.freenode.net irc.freenode.net]
pattern_ has joined #ocaml
lament has quit ["heh"]
baader has quit ["I'll be back"]
Yurik has quit ["Client exiting"]
mattam has joined #ocaml
Zadeh has quit [Remote closed the connection]
dusty has joined #ocaml
dusty has quit [Client Quit]
wax has joined #ocaml
xtrm has joined #ocaml
Kinners has quit [Read error: 54 (Connection reset by peer)]
Riastrad1 has joined #ocaml
xmkl has joined #ocaml
Riastradh has quit [Read error: 110 (Connection timed out)]
smklsmkl has quit [Read error: 110 (Connection timed out)]
Riastrad1 has quit [Read error: 101 (Network is unreachable)]
xmkl has quit [Read error: 104 (Connection reset by peer)]
smklsmkl has joined #ocaml
docelic is now known as docelic\away
systems has joined #ocaml
docelic\away has quit [Excess Flood]
docelic\away has joined #ocaml
systems has quit [Read error: 110 (Connection timed out)]
foxster has quit [Read error: 104 (Connection reset by peer)]
systems has joined #ocaml
systems has quit ["Client Exiting"]
lus|wazze has joined #ocaml
docelic\away is now known as docelic
reltuk has quit []
systems has joined #ocaml
docelic is now known as docelic|away
systems has quit [Client Quit]
hitachi has joined #ocaml
hitachi is now known as XingSutachi
mattam_ has joined #ocaml
XingSutachi has quit [Remote closed the connection]
TachYon26 has joined #ocaml
gorts has joined #ocaml
mattam has quit [Read error: 110 (Connection timed out)]
docelic|away is now known as docelic
gorts has quit [Remote closed the connection]
__DL__ has joined #ocaml
Riastradh has joined #ocaml
docelic has quit [Excess Flood]
TachYon26 has quit ["bez ki³y nie ma zaliczenia (z prawd studentek AM)"]
foxster has joined #ocaml
xtrm has quit ["prout"]
docelic has joined #ocaml
GabeW has joined #ocaml
reltuk has joined #ocaml
Verbed has quit [leguin.freenode.net irc.freenode.net]
seth_ has quit [leguin.freenode.net irc.freenode.net]
iusris has quit [leguin.freenode.net irc.freenode.net]
GabeW has quit [leguin.freenode.net irc.freenode.net]
async has quit [leguin.freenode.net irc.freenode.net]
Riastradh has quit [leguin.freenode.net irc.freenode.net]
Smerdyakov has quit [leguin.freenode.net irc.freenode.net]
asqui has quit [leguin.freenode.net irc.freenode.net]
cm has quit [leguin.freenode.net irc.freenode.net]
emu has quit [leguin.freenode.net irc.freenode.net]
iusris has joined #ocaml
seth_ has joined #ocaml
Verbed has joined #ocaml
GabeW has joined #ocaml
Riastradh has joined #ocaml
Smerdyakov has joined #ocaml
asqui has joined #ocaml
async has joined #ocaml
emu has joined #ocaml
cm has joined #ocaml
asqui has quit [Excess Flood]
asqui has joined #ocaml
Verbed has quit [leguin.freenode.net irc.freenode.net]
iusris has quit [leguin.freenode.net irc.freenode.net]
seth_ has quit [leguin.freenode.net irc.freenode.net]
asqui has quit [leguin.freenode.net irc.freenode.net]
async has quit [leguin.freenode.net irc.freenode.net]
GabeW has quit [leguin.freenode.net irc.freenode.net]
cm has quit [leguin.freenode.net irc.freenode.net]
Smerdyakov has quit [leguin.freenode.net irc.freenode.net]
emu has quit [leguin.freenode.net irc.freenode.net]
Riastradh has quit [leguin.freenode.net irc.freenode.net]
asqui has joined #ocaml
iusris has joined #ocaml
seth_ has joined #ocaml
Verbed has joined #ocaml
GabeW has joined #ocaml
Riastradh has joined #ocaml
Smerdyakov has joined #ocaml
cm has joined #ocaml
emu has joined #ocaml
async has joined #ocaml
Smerdyakov has quit [leguin.freenode.net irc.freenode.net]
emu has quit [leguin.freenode.net irc.freenode.net]
cm has quit [leguin.freenode.net irc.freenode.net]
Riastradh has quit [leguin.freenode.net irc.freenode.net]
Riastradh has joined #ocaml
Smerdyakov has joined #ocaml
cm has joined #ocaml
emu has joined #ocaml
iusris has quit [leguin.freenode.net irc.freenode.net]
seth_ has quit [leguin.freenode.net irc.freenode.net]
Verbed has quit [leguin.freenode.net irc.freenode.net]
iusris has joined #ocaml
seth_ has joined #ocaml
Verbed has joined #ocaml
seth_ has quit [leguin.freenode.net irc.freenode.net]
iusris has quit [leguin.freenode.net irc.freenode.net]
Verbed has quit [leguin.freenode.net irc.freenode.net]
Verbed has joined #ocaml
seth_ has joined #ocaml
iusris has joined #ocaml
asqui has quit [Excess Flood]
asqui has joined #ocaml
<reltuk> "Make a new type containing three fields"...that's like type new_type = field1_type * field2_type * field3_type, right?
<lus|wazze> depends
<lus|wazze> you could also make a record
<lus|wazze> type new_type = {foo:foo_type;bar:bar_type;baz:baz_type}
TachYon has joined #ocaml
__DL__ has quit [Remote closed the connection]
<reltuk> 'k, thanks
<Riastradh> Or use the constructor syntax -- type myType = MyType of fieldType1 * fieldType2 * fieldType3
<lus|wazze> what for if he has only one case?
<Riastradh> He could use any of the three that were pointed out -- I was just pointing out another way to do it.
Vincenz has joined #ocaml
<Vincenz> hello
SuXoRzZ has joined #ocaml
Vincenz has quit []
TimFreeman has joined #ocaml
TimFreeman has left #ocaml []
lus|wazze has quit ["\o/ *liephab* \o/"]
SuXoRzZ has quit []
TachYon has quit ["Client Exiting"]
systems has joined #ocaml
systems has quit ["Client Exiting"]
GabeW has quit ["leaving"]
gl has quit [Read error: 60 (Operation timed out)]
gl has joined #ocaml
<reltuk> ok, so I asked earlier about creating a type with 3 fields. If I wanted to use the record syntax (so I could index the types independant of eachother), and one of the fields was a list, and one of them was "an order function"...what's the "type" of the order function?
<reltuk> this is from the o'reilly book...I think they might mean a 'a -> 'a -> bool that compares two of the members in the list...
<reltuk> not really sure though
<Riastradh> You're probably right.
<reltuk> ok...I think everything makes sense if that's the case too
<reltuk> how do you select just one member from a tuple?
<Riastradh> match t with (_,member,_) -> ...
<reltuk> hmm...
<reltuk> [e]::(head::tail) This expression has type 'a but is here used with type 'a list
<reltuk> I'm matching 'a list * ('a->'a->bool) * bool with (head::tail, _, _) -> in the function
<reltuk> function takes one of those and an e, which is supposed type 'a...
<seth_> reltuk: is that really what you mean, a list on both sides of the :: ?
<reltuk> oh! right...it takes a scalar
<reltuk> thanks
<seth_> np
<reltuk> sweet...it took it...
<reltuk> sorry I'm a moron about all this...just got here :-p
sproctor has joined #ocaml
Kinners has joined #ocaml
<seth_> it is a bit confusing at first.
mattam_ has quit [Read error: 110 (Connection timed out)]