Yes! what you sent is straigth and simple (and gives 0o664 permissions) and I
don't mind that String.create comes from outside the standard library because
I can rewrite it as
let string_create pattern size =
let rec str_cr pattern str size counter =
if counter < size
then str_cr pattern (str^pattern) size (counter +1)
else str
in
str_cr pattern "" size 0;;
(BTW This shouldn't be very performant, fetching arguments around over and
over should take more memory than marking imperatively the value of a
counter... I suppose)
I think that it is very interesting to write copy() as recursive: so the "max
size" of the file can be also very low and all of the file will be
recursively read anyway. Great!
Thank you
Ernesto
Alle ore 14:41, giovedě 07 febbraio 2002, doug+ml.ocaml_beginners@...
ha scritto:
> let copy_file file_in file_out =
> let ic = open_in file_in in
> let max = 4096 in
> let buf = String.create max in
> try
> let oc = open_out file_out in
> (try
> let rec copy () =
> let len = input ic buf 0 max in
> if len > 0 then (output oc buf 0 len; copy ()) in
> copy ();
> close_in ic;
> close_out oc;
> with e -> close_out oc; raise e)
> with e -> close_in ic; raise e;;
I think you are on the right way.
On 2002.02.07 22:24 stalkern2 wrote:
> Hey Gerd, I'm a beginner so slow down a bit ;-))
>
> You should say not that "Every function takes exactly one argument
> and returns exactly one result value."
> but that "Every function takes some arguments
> and returns exactly one result value."
I expected that you find that surprising. Before I comment on your
examples, I want to point out that there is a theoretical view and
a pragmatic view on functions in Caml. From the theoretical view,
functions take exactly one argument, and I think it is important
to know that this view exists because it explains a lot. Of course,
you don't think like that when programming, and the code generated
by the compiler also passes several arguments at once to a function
body (so there is no performance penalty).
> (* §§§§§§§§§§§§§§§§§§§§§§§ DISCUSSION §§§§§§§§§§§§§§§§§§§§§§§§§§§§§§ *)
> The result value of the application of a function in Ocaml may (ONLY?) be:
>
> ___________________________________
> 1) one bare value or set of values;
>
> # let functa x = 3*x;;
> val functa : int -> int = <fun>
> # functa 3;;
> - : int = 9
> ( 9 is the value )
>
> ___________________________________
> 2) one function that need further informations to terminate into one bare
> value or set of values;
> # let functb x y = 3*x;;
> val functb : int -> 'a -> int = <fun>
> # functb 3;;
> - : '_a -> int = <fun>
>
> ( "hey! you promised a y and I still want a y!"
> In functional programming when you use a function
> with no arguments it doesn't care, it will keep it and
> try to evaluate it later on or just keep it symbolic
> (so it will be saying things like
> "Hi, if you give me an integer I give you back a boolean").
> I like to think about a football player kicking the ball forward
> and running after it for touching it again.
> This is called "partial application" and I think that the
> last valid touch is called "closing a function")
This is the interesting case. The definition "let functb x y = ..." is
only syntactic sugar for people who want still believe that functions have
several arguments. In reality, it is only an abbreviation for:
let functb = fun x -> (fun y -> 3*x)
The "let" gives the whole thing a name, nothing more. "fun y -> 3*x"
is a function taking an argument, calling the argument y for the time
of evaluation, and the function body "3*x". "fun x -> (fun y -> 3*x)"
is a function taking an argument, calling the argument y for the time
of evaluation, and returning a FUNCTION. A function returns a function
as result like other functions return numbers (if you read something
like "functions are first-order values" exactly this is meant, although
it sounds like "God is the Greatest").
You have a already a good picture for functions: they are like a promise,
if you give them some kind of value they promise to return something.
And a function returning a function is like a promise that there will
be another promise...
Fortunately, there is an exact method how to find out what a function
will return. Example: What is the result of functb 3?
functb 3 = (fun x -> (fun y -> 3*x)) 3
= fun y -> 3*3
First I have expanded the name functb, I think this is obvious. The
second step is to replace x by 3. Theorists call that "beta reduction".
So the result is another function, another beta reduction step is not
possible. Beta reduction is really only symbolical replacement, and
quite simple (well, not always so simple as in this example, because
there is a case when a so-called alpha conversion is necessary, but I
think this is the point where the theory becomes less explanatory).
(Because somebody else has mentioned it: I am currently explaining
the lambda calculus, but using Caml syntax instead of the traditional
notation.)
Unfortunately, Caml never prints the symbolic result of partial
application, so you have to imagine that (this is because Caml internally
does not compute with symbolical expressions, but uses more efficient
ways of calculation).
# let functc = functb 3;;
val functc : '_a -> int = <fun>
# functc 42;;
- : int = 9
Now I have given the resulting function a name, "functc", and I can
also call it.
Because you have mentioned the term "closing a function": the internal
representation of the expression fun y -> 3*x where x is already bound
to the value 3 is called a closure. Closures come from a different kind
of theory, and deals with the management of name bindings. Let's play
a quiz:
# let x = 3;;
val x : int = 3
# let f y = [ x+y; y; x ];;
val f : int -> int list = <fun>
# let x = 4;;
val x : int = 4
# f 5;;
What's the result?
(A) [8;5;3]
(B) [9;5;4]
I have bound x twice, x = 3, and x = 4. The point is now that at the
definition of f the current value of x is remembered, and will be used
even if I invent a new x with another value. The "memory effect" that
a function body can remember the bindings of the names at the time of
the definition is called "closing a function".
> ___________________________________
> 3) (), that is more or less "Nothing"
> # let f () = print_string " BEGINNERS UNITE! " ;;
> val f : unit -> unit = <fun>
> # f ();;
> BEGINNERS UNITE! - : unit = ()
>
> ( f wanted no argument, but if I call
> # f;;
> - : unit -> unit = <fun>
> it just shows its structure, so I need to say
> "f Nothing"! and then it works.
> It gives Nothing back because the ACTION of printing is not a BARE VALUE.)
() is a "substitute value". Imagine a relay race: The next runner will only
start when the previous runner reaches him and passes the stick. Think
() as the stick.
> Look:
> # let a = ref 3;;
> val a : int ref = {contents = 3}
> (I say that there's a place called "a" and I park "3" there;
> it's different from let a = 3;; because like that I say that "a" IS "3")
Yes. ref 3 is a store that is initialized with 3, but I can change it later.
let a = 3 cannot be changed. (Well, I can later define let a = 4, but this
"a" is different from the previous one.)
# let x = ref 3;;
val x : int = 3
# let f y = [ !x+y; y; !x ];;
val f : int -> int list = <fun>
# x := 4;;
val x : int = 4
# f 5;;
Surprise! I get the other value.
> # !a;;
> - : int = 3
> (go and look in the place of "a"; there's a "3" parked there)
> # let functc x = (x := !x + 1);;
> val functc : int ref -> unit = <fun>
> (I write a function that takes the name of a place and parks
> in it the value that is parked in it now plus 1)
> # functc a;;
> - : unit = ()
> (Apply the function: RESULT VALUE is Nothing!)
> # !a;;
> - : int = 4
> (Ah! so it worked. (3+1) is now parked in the place of "a")
>
> (What if I define the function not as a "parking" action
> but directly as a value?)
> # let functd x = !x + 1;;
> val functd : int ref -> int = <fun>
> # functd a;;
> - : int = 5
> (I don't get Nothing, I get a bare value!
> But I didn't park it, so if I go and check in the place of "a")
> # !a;;
> - : int = 4
> (Gee, I've wasted a function!)
>
>
> (* §§§§§§§§§§§§§§§§§§§§§§§ CONCLUSION §§§§§§§§§§§§§§§§§§§§§§§§§§§§§ *)
> So (beginner's opinion!):
> WHEN YOU SEE (), THINK THAT SOMETHING HAPPENED SOMEWHERE ELSE.
> WHEN YOU SEE A BARE VALUE, THANK OCAML AND DOUBLE-CHECK IT.
> WHEN YOU SEE STILL A FUNCTION, FEED OCAML (ocamlgotchi? ;-))
> WHEN YOU WANT TO WRITE SOMETHING THAT "IS A FUNCTION BUT ISN'T THE FUNCTION
> OF ANYTHING"... KNEEL DOWN AND START WORSHIPPING IT!
All right, I see it's now your own story.
Gerd
--
----------------------------------------------------------------------------
Gerd Stolpmann Telefon: +49 6151 997705 (privat)
Viktoriastr. 45
64293 Darmstadt EMail: gerd@...
Germany
----------------------------------------------------------------------------
Henrik Motakef <henrik.motakef@...> writes:
> Remi VANICAT <vanicat+egroups@...> writes:
>
> > no exactly :
> >
> > # let x = `Literal "foo";;
> > val x : [> `Literal of string] = `Literal "foo"
> >
> > this mean that x
>
> I just re-read the chapter on polymorphic variants in the manual (I
> had a feeling like "Aah - now I get what they are talking about" - but
> I guess it won't be the last time I have this feeling), and try to
> complete your statement:
>
> ... can be anything called "`Literal" and "really" of type string, or
> anything with a different label (hence the ">" in the type).
>
> However, in this particular case, this doesn't seem to be a problem,
> scince one would have to use a new "let x = ...", and in that case you
> could "shadow" both type and value of the thing called x anyways
> (scince "let x = 1 in let x = Some "thing" ..." is legal).
the interesting thing about the [> `Literal of string] is that x can
be use everywhere one is looking for a `Literal of string, even if it
is a closed type (as [`Literal of string | `Blup of int ]).
>
> In functions etc. where I would use pattern-matching, I could make the
> type explicit, like in
>
> type allowed = [`Literal of string | `Foo of int]
> let f (x: allowed) = match x with
> | `Literal _ -> true
> | `Foo _ -> false
>
> (Note that despite the grammar used, the above statements are of
> course meant as the question whether these statements are right.)
mostly, but i insist on the fact that when you do a
let x = 10 in
let x = 30. in
whatever
both x denote two different variable (even if they have the same
name). To think otherwise is a common mistake for beginner.
--
Rémi Vanicat
vanicat@...http://dept-info.labri.u-bordeaux.fr/~vanicat
Henrik Motakef <henrik.motakef@...> writes:
> Remi VANICAT <vanicat+egroups@...> writes:
>
> > no exactly :
> >
> > # let x = `Literal "foo";;
> > val x : [> `Literal of string] = `Literal "foo"
> >
> > this mean that x
>
> I just re-read the chapter on polymorphic variants in the manual (I
> had a feeling like "Aah - now I get what they are talking about" - but
> I guess it won't be the last time I have this feeling), and try to
> complete your statement:
>
> ... can be anything called "`Literal" and "really" of type string, or
> anything with a different label (hence the ">" in the type).
>
> However, in this particular case, this doesn't seem to be a problem,
> scince one would have to use a new "let x = ...", and in that case you
> could "shadow" both type and value of the thing called x anyways
> (scince "let x = 1 in let x = Some "thing" ..." is legal).
>
> In functions etc. where I would use pattern-matching, I could make the
> type explicit, like in
>
> type allowed = [`Literal of string | `Foo of int]
> let f (x: allowed) = match x with
> | `Literal _ -> true
> | `Foo _ -> false
>
> (Note that despite the grammar used, the above statements are of
> course meant as the question whether these statements are right.)
>
> > > Yes, that seems to work. However, I wonder why; in the end I don't
> > > tell the compiler anything new (or do I?).
> >
> > yes you do. A class must not have any open type, and
> > <get_uri: string; ...> is open (there can be other method). So you have
> > to explicitly tell the compiler that there will be open type (here 3
> > 'a 'b and 'c) and you explicitly say what have this type.
>
> What I meant was that saying
>
> class ['a, 'b, 'c] class statement (s: 'a) (p: 'b) (o: 'c)
>
> doesn't introduce something new scince it is quite clear that s, p and
> o have to be of *some* type - and I do not add any information about
> those types. So - is the ['a, 'b, 'c] just a technical neccesity, as a
> flag to say "Yes, here are some open types, deal with it"?
not exactly. You really add an information, the fact that statement is
a parametrized class, depending of three type (something very similar
to template in C++).
if you make
new statement (new resource "bla") (new resource "bli") (new resource "blu");;
the type is (resource, resource, resource) statement
new statement (new resource "bla") (new resource "bli") (new literal "blu");;
the type is (resource, resource, literal) statement
so you can see in that type contain the information of what is in the
object. the ['a, 'b, 'c] give the order in which those type parameter
must be given, and the (s : 'a) .... tell what have which type.
> (Like I feel about "class virtual ..." - after all, the rules are
> quite simple: when a class has virtual methods, it is virtual,
> otherwise it isn't. I don't see why a compiler couldn't infer this,
> so I guess it just made implementation easier.)
it mostly make thing clearer. You could also use some trick for typing
purpose with virtual method like :
# class foo =
object
method virtual foo : int -> int
method foo x = x
end;;
class foo : object method foo : int -> int end
also, when you inherit a virtual class, you may forget to write the
implementation of a virtual method. The compiler can see it immediately
(otherwise, you can only see it when you will use the class, and even
for library, only when someone else will use it).
--
Rémi Vanicat
vanicat@...http://dept-info.labri.u-bordeaux.fr/~vanicat
Thankyou Gerd,
Your response was exactly what I was looking for. You understood
my question perfectly.
Thanks to everyone else for
Cheers,
Matthew
On Thu, 7 Feb 2002 23:17, you wrote:
> Matthew O'Connor <matthew.oconnor@...> schrieb am 07.02.2002,
>
> 06:02:06:
> > Hi,
> >
> > I was wondering how I would go about adding functions that
> > take no arguments into a list?
> >
> > Can it be done? If not why not?
>
> I think I have understood your problem. In other languages, functions
> usually take n >= 0 arguments and return exactly one result (well,
> there is usually a variant returning no result; in old Pascal days
> we called them "procedures"). So you have to distinguish syntactically
> between "I mean the function as such", and "I mean the function after
> being applied". For example, in C you can write "f" if you mean the
> function as such, and write "f()" if you mean the result.
>
> The Caml model is different. Every function takes exactly one argument
> and returns exactly one result value. There is no exception from this
> rule in the whole language. So you cannot write an expression meaning
> "the function without arguments" because there is no such thing in
> the language.
>
> Because there is the frequent case that you do not want to pass
> information to a function, there is the "unit" type. unit has only
> one member, the thing, written (). You could define unit = { () }
> (if types were sets). () is also used to model "I don't want to
> return information from a function". So a "procedure" in other
> languages without arguments and without result is in Caml a
> function accepting () and returning (), e.g.
>
> let f() = ...; ();;
>
> and f is typed: f : unit -> unit.
>
> If you simply write
>
> let f = ... ;;
>
> you don't define a function. The expression "..." is immediately
> evaluated, and the result of the expression is bound to f. "let"
> simply binds values to names, and because functions are values in
> Caml it is not surprising that the same syntacical construct "let"
> can be used to define functional and non-functional named values.
>
> I hope this helps (and expecting more questions on this topic),
>
> Gerd
>
> To unsubscribe from this group, send an email to:
> ocaml_beginners-unsubscribe@yahoogroups.com
>
> The archives of the very official ocaml list (the seniors' one) can be
> found at http://caml.inria.fr
>
> Attachments are banned and you're asked to be polite, avoid flames etc.
> etc.
>
> Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/
Remi VANICAT <vanicat+egroups@...> writes:
> no exactly :
>
> # let x = `Literal "foo";;
> val x : [> `Literal of string] = `Literal "foo"
>
> this mean that x
I just re-read the chapter on polymorphic variants in the manual (I
had a feeling like "Aah - now I get what they are talking about" - but
I guess it won't be the last time I have this feeling), and try to
complete your statement:
... can be anything called "`Literal" and "really" of type string, or
anything with a different label (hence the ">" in the type).
However, in this particular case, this doesn't seem to be a problem,
scince one would have to use a new "let x = ...", and in that case you
could "shadow" both type and value of the thing called x anyways
(scince "let x = 1 in let x = Some "thing" ..." is legal).
In functions etc. where I would use pattern-matching, I could make the
type explicit, like in
type allowed = [`Literal of string | `Foo of int]
let f (x: allowed) = match x with
| `Literal _ -> true
| `Foo _ -> false
(Note that despite the grammar used, the above statements are of
course meant as the question whether these statements are right.)
> > Yes, that seems to work. However, I wonder why; in the end I don't
> > tell the compiler anything new (or do I?).
>
> yes you do. A class must not have any open type, and
> <get_uri: string; ...> is open (there can be other method). So you have
> to explicitly tell the compiler that there will be open type (here 3
> 'a 'b and 'c) and you explicitly say what have this type.
What I meant was that saying
class ['a, 'b, 'c] class statement (s: 'a) (p: 'b) (o: 'c)
doesn't introduce something new scince it is quite clear that s, p and
o have to be of *some* type - and I do not add any information about
those types. So - is the ['a, 'b, 'c] just a technical neccesity, as a
flag to say "Yes, here are some open types, deal with it"? (Like I
feel about "class virtual ..." - after all, the rules are quite
simple: when a class has virtual methods, it is virtual, otherwise it
isn't. I don't see why a compiler couldn't infer this, so I guess it
just made implementation easier.)
Salut
Henrik
"Matthew O'Connor" <matthew.oconnor@...> writes:
> Hi,
>
> Firstly thanks to everyone for there responses on my
> first posting. They were very helpful and I am glad that
> this mail list was created.
>
> Coming from a C++ background when I create a template
> class I can pass in a type and then a pointer to a function of
> that type.
>
> eg. myList<Apples, Apples::bite> myListApple
>
> Where Apples is a class type and bite is a method on an
> Apples. Inside myList I can instantiate an Apples and run the
> method bite on it. I don't actually have to pass an instantiated
> Apples in.
>
> eg. { T* myT = new T; T->fn(); }
>
> How would I do the same thing in OCaml?
very easily, for example :
class ['a] myList (x : 'a) (f : 'a -> unit) =
object
var an_obj = x
method apply () = f x
end
--
Rémi Vanicat
vanicat@...http://dept-info.labri.u-bordeaux.fr/~vanicat
Hi,
Firstly thanks to everyone for there responses on my
first posting. They were very helpful and I am glad that
this mail list was created.
Coming from a C++ background when I create a template
class I can pass in a type and then a pointer to a function of
that type.
eg. myList<Apples, Apples::bite> myListApple
Where Apples is a class type and bite is a method on an
Apples. Inside myList I can instantiate an Apples and run the
method bite on it. I don't actually have to pass an instantiated
Apples in.
eg. { T* myT = new T; T->fn(); }
How would I do the same thing in OCaml?
(Sorry for the poor example.)
Cheers,
Matthew O'Connor
Henrik Motakef <henrik.motakef@...> writes:
> Remi VANICAT <vanicat+egroups@...> writes:
>
>
> Thanks for your reply.
>
> > type literal = [ `Literal of string ]
> > type resource =
> > [ `Resource of string
> > | `Statements of (resource * resource * node) ]
> > type node =
> > [ `Resource of string
> > | `Statements of (resource * resource * node)
> > | `Literal of string ]
>
> Am I right thinking that "`Literal of string" would translate to
> "anything that is called Literal and actually is a string"?
> Or are there other caveats?
no exactly :
# let x = `Literal "foo";;
val x : [> `Literal of string] = `Literal "foo"
this mean that x
>
> > you should write :
> >
> > class ['a, 'b, 'c] statement (s : 'a) (p : 'b) (o : 'c) =
> > let uri_of_spo s p o =
> > (s # get_uri) ^ (p # get_uri) ^ (o # get_uri)
> > in
> > object (self)
> > inherit resource (uri_of_spo s p o)
> > val subj = s
> > val pred = p
> > val obj = o
> >
> > method get_subject = subj
> > method get_predicate = pred
> > method get_object = obj
> > end
>
> Yes, that seems to work. However, I wonder why; in the end I don't
> tell the compiler anything new (or do I?).
yes you do. A class must not have any open type, and
<get_uri: string; ...> is open (there can be other method). So you have
to explicitly tell the compiler that there will be open type (here 3
'a 'b and 'c) and you explicitly say what have this type.
by the way
class ['a, 'c] statement (s : 'a) (p : 'a) (o : 'c) =
let uri_of_spo s p o =
(s # get_uri) ^ (p # get_uri) ^ (o # get_uri)
in
object (self)
inherit resource (uri_of_spo s p o)
val subj = s
val pred = p
val obj = o
method get_subject = subj
method get_predicate = pred
method get_object = obj
end
could work (but s and b must have the same type).
--
Rémi Vanicat
vanicat@...http://dept-info.labri.u-bordeaux.fr/~vanicat
Remi VANICAT <vanicat+egroups@...> writes:
Thanks for your reply.
> type literal = [ `Literal of string ]
> type resource =
> [ `Resource of string
> | `Statements of (resource * resource * node) ]
> type node =
> [ `Resource of string
> | `Statements of (resource * resource * node)
> | `Literal of string ]
Am I right thinking that "`Literal of string" would translate to
"anything that is called Literal and actually is a string"?
Or are there other caveats?
> you should write :
>
> class ['a, 'b, 'c] statement (s : 'a) (p : 'b) (o : 'c) =
> let uri_of_spo s p o =
> (s # get_uri) ^ (p # get_uri) ^ (o # get_uri)
> in
> object (self)
> inherit resource (uri_of_spo s p o)
> val subj = s
> val pred = p
> val obj = o
>
> method get_subject = subj
> method get_predicate = pred
> method get_object = obj
> end
Yes, that seems to work. However, I wonder why; in the end I don't
tell the compiler anything new (or do I?).
> by the way i thought that the object could be a literal. It's not the
> case in your example (which have not get_uri method).
Typo, sorry. Should have read
(s # get_uri) ^ (p # get_uri) ^ (o # get_label)
Still basically a hack to tell O'Caml which types I meant to allow. Is
there a way to directly say <get_uri: string; ...>?
Thanks
Henrik
Henrik Motakef <henrik.motakef@...> writes:
> Hi.
>
> I have some problems with the type system, and whether to use "plain"
> types and functions, or the OO approach.
>
> The (toy) problem I chose to teach myself O'Caml is the RDF data
> model. In short, it is like this:
>
> There are two kinds of basic "things" (usually called nodes): Literals
> and Resources. Basically, can be identified by strings.
>
> Then there are Statements, consisting of a subject, a predicate and an
> object. The Object can be either a Resource or a Literal, the others
> only a Resource. However, a Statement itself can be viewed as a
> Resource itself.
>
> Additionally, a set of Statements is called a Model, and that's a
> Resource also.
>
> The first idea was using something like this:
>
> type node =
> | Literal of string
> | Resource of string
> | Statement of node * node * node
> | Model of (* some magic type *)
>
> Already two problems here:
> 1) Statement really should not be node * node * node, but "node except
> Literal * node except Literal * node".
> 2) It would be nice to let Model be a Set over statements. I have no
> idea if and how that could be done.
>
you could use the polymorphic variant :
type literal = [ `Literal of string ]
type resource =
[ `Resource of string
| `Statements of (resource * resource * node) ]
type node =
[ `Resource of string
| `Statements of (resource * resource * node)
| `Literal of string ]
> Version three tries to use classes: statement and model simply inherit
> from resource (or are at least subtypes). However, this won't work
> either:
> class statement s p o =
> let uri_of_spo s p o =
> (s # get_uri) ^ (p # get_uri) ^ (o # get_uri)
> in
> object (self)
> inherit resource (uri_of_spo s p o)
> val subj = s
> val pred = p
> val obj = o
>
> method get_subject = subj
> method get_predicate = pred
> method get_object = obj
> end
you should write :
class ['a, 'b, 'c] statement (s : 'a) (p : 'b) (o : 'c) =
let uri_of_spo s p o =
(s # get_uri) ^ (p # get_uri) ^ (o # get_uri)
in
object (self)
inherit resource (uri_of_spo s p o)
val subj = s
val pred = p
val obj = o
method get_subject = subj
method get_predicate = pred
method get_object = obj
end
by the way i thought that the object could be a literal. It's not the
case in your example (which have not get_uri method).
Hi.
I have some problems with the type system, and whether to use "plain"
types and functions, or the OO approach.
The (toy) problem I chose to teach myself O'Caml is the RDF data
model. In short, it is like this:
There are two kinds of basic "things" (usually called nodes): Literals
and Resources. Basically, can be identified by strings.
Then there are Statements, consisting of a subject, a predicate and an
object. The Object can be either a Resource or a Literal, the others
only a Resource. However, a Statement itself can be viewed as a
Resource itself.
Additionally, a set of Statements is called a Model, and that's a
Resource also.
The first idea was using something like this:
type node =
| Literal of string
| Resource of string
| Statement of node * node * node
| Model of (* some magic type *)
Already two problems here:
1) Statement really should not be node * node * node, but "node except
Literal * node except Literal * node".
2) It would be nice to let Model be a Set over statements. I have no
idea if and how that could be done.
Another idea would be using distinct types, but there are several
functions operating on any of them, and AFAIK one cannot write a
function that takes more than one type as an argument. I guess I could
write it like:
type literal =
| Literal of string
and resource =
| Resource of string
| Statement of statement
| Model of model
and node =
| ResourceNode of resource
| LiteralNode of literal
and statement = resource * resource * node
and model = (* still magic *)
which would result in code like
let some_node = ResourceNode (Resource "foo")
and so on, not quite elegant IMHO.
Version three tries to use classes: statement and model simply inherit
from resource (or are at least subtypes). However, this won't work
either:
class literal (content: string) =
object
val c = content
method get_label = c
end
class resource (uri: string) =
object (self)
val u = uri
method get_uri = u
method get_label = self # get_uri
end
class statement s p o =
let uri_of_spo s p o =
(s # get_uri) ^ (p # get_uri) ^ (o # get_uri)
in
object (self)
inherit resource (uri_of_spo s p o)
val subj = s
val pred = p
val obj = o
method get_subject = subj
method get_predicate = pred
method get_object = obj
end
Result:
Some type variables are unbound in this type:
class statement :
(< get_uri : string; .. > as 'a) ->
(< get_uri : string; .. > as 'b) ->
(< get_uri : string; .. > as 'c) ->
object
val obj : 'c
val pred : 'b
val subj : 'a
val u : string
method get_label : string
method get_object : 'c
method get_predicate : 'b
method get_subject : 'a
method get_uri : string
end
The method get_object has type < get_uri : string; .. > where .. is unbound
Of course, that is exacly what I wanted: that it accepty every object
that has a get_uri method. I could coerce it to a closed type, but how
would I then get back to a "real" statement (with get_subject etc.),
for example?
OK, I guess this was long enough. Would be nice if someone could
enlighten me.
Regards
Henrik
P.S At least noone can yell "It's a FAQ!" at me... :)
stalkern2 wrote:
> Why does
> #let oc = open_out_gen [Open_creat; Open_trunc; Open_text] 664
[...]
> create a file with permissions (obtained with ls -laF on a bash Linux shell)
> --w--wx--T
> although I was asking for -rw-rw-r-- (664)?
I believe that you have made a mistake in the radix of your input!
You put: 664, which is a decimal number. You want 0o664, which is an
octal number. So it looks like you actually asked for:
0o1230
> In a more general way, did any of you every copy a text file using the
> Standard library?
Well, no I haven't. I tend to use the Unix library more ... because
it does things in a way that is familiar to me.
> So far, I can copy a bunch of characters into a string that is bigger than
> them all,
> # let ic = open_in "./bof.txt" in
> let s = " " in ignore (input ic s 0 10); print_string s;;
> nkmnbewlkj - : unit = ()
>
> but I don't know what to do after. In other languages you read all from a
> pointer, then assign what you've read to a name, then write down to a
> pointer. What about ocaml?
Well, you use strings for character buffers, of course :-)
Does this do what you want?
let copy_file file_in file_out =
let ic = open_in file_in in
let max = 4096 in
let buf = String.create max in
try
let oc = open_out file_out in
(try
let rec copy () =
let len = input ic buf 0 max in
if len > 0 then (output oc buf 0 len; copy ()) in
copy ();
close_in ic;
close_out oc;
with e -> close_out oc; raise e)
with e -> close_in ic; raise e;;
cheers,
doug
Why does
#let oc = open_out_gen [Open_creat; Open_trunc; Open_text] 664
"./bofcopy.txt";;
val oc : out_channel = <abstr>
create a file with permissions (obtained with ls -laF on a bash Linux shell)
--w--wx--T
although I was asking for -rw-rw-r-- (664)?
In a more general way, did any of you every copy a text file using the
Standard library?
So far, I can copy a bunch of characters into a string that is bigger than
them all,
# let ic = open_in "./bof.txt" in
let s = " " in ignore (input ic s 0 10); print_string s;;
nkmnbewlkj - : unit = ()
but I don't know what to do after. In other languages you read all from a
pointer, then assign what you've read to a name, then write down to a
pointer. What about ocaml?
Ciao
Ernesto
stalkern2 wrote:
> Does this mean that every language where one function can be written
> with several arguments also accepts partial applications?
I'm not sure, but I think that partial application is a property of
most (all?) functional languages, but it is definately not a feature
of most imperative languages.
But OCaml has it! And I think it's a very cool feature :)
Partial application allows me to refactor my code so that I do not
duplicate functionality. I think easy refactoring is one of the most
fun aspects of programming in OCaml.
> (f x) seem to be a partial application.
I'm not exactly sure what you mean ... it is a partial application if
"f" is defined as taking more than one argument. (As in the case of
the binary (+) function).
> Ernesto
> PS Drop this if it's Off Topic, I don't know.
Well, I think it is on topic! :)
cheers,
doug
Does this mean that every language where one function can be written with
several arguments also accepts partial applications? (f x) seem to be a
partial application.
Ernesto
PS Drop this if it's Off Topic, I don't know.
Alle ore 12:24, giovedě 07 febbraio 2002, doug+ml.ocaml_beginners@...
ha scritto:
> f x y = (f' x) y
Hi. I am trying to get my feet wet with C code, but I find the docs
on confusing. So I hope someone will give me feedback...
I'm trying to write my own marshaling functions. For example,
external encode_float : string -> int -> float -> int
= "encode_float"
This function writes the float into the string at the offset
indicated by the int. Thus:
value encode_float (value buf, value pos, value x)
{
CAMLparam3 (buf, pos, x);
((float *) (String_val (buf))) [Int_val (pos)]
= (float) (Long_val (x));
CAMLreturn (Val_int (1 + Int_val (pos)));
}
Is this the absolute best I can do? This function will be called
over and over, and I am interested in efficiency. Could I cheat and
do something like:
CAMLreturn (pos + 10);
Thus taking advantage of my knowledge of the representation of ints?
Thanks for any advice and feedback!
I wrote:
> Any function that takes more than one argument can be thought of as a
> function that takes the first argument and results in a functional
> result that can be applied the result to the rest of the arguments.
I apologize for my bad grammar! I meant:
Any function that takes more than one argument can be thought of as a
function that takes the first argument and results in a function can
be applied to the rest of the arguments.
cheers,
doug
stalkern2 wrote:
> Hey Gerd, I'm a beginner so slow down a bit ;-))
>
> You should say not that "Every function takes exactly one argument
> and returns exactly one result value."
> but that "Every function takes some arguments
> and returns exactly one result value."
Well, in fact, what Gerd wrote is exactly true, and I think that
understanding his statement a little more deeply will result in a
greater appreciation of how OCaml works.
I think some of the messages in this thread have been talking around
the subject of partial application, and since it is such an important
concept, maybe to give an example would be good.
Any function that takes more than one argument can be thought of as a
function that takes the first argument and results in a functional
result that can be applied the result to the rest of the arguments.
So I think that is why Gerd said: "Every function takes exactly one
argument and returns exactly one result value."
Another way to say it is:
f x y = (f' x) y
Or, in the toplevel:
(* we show the binary infix operator + can be used with prefix style: *)
# let foo a b = (+) a b;;
val foo : int -> int -> int = <fun>
# foo 3 4;;
- : int = 7
(* we can demonstrate a partial application of + to one integer *)
# let foo' x = (+) x;;
val foo' : int -> int -> int = <fun>
(* redefine foo in terms of foo' *)
# let foo y = foo' y;;
val foo : int -> int -> int = <fun>
(* and the result is what you expect: *)
# foo 3 4;;
- : int = 7
(* or we could have written foo this way in the beginning *)
# let foo a b = ((+) a) b;;
val foo : int -> int -> int = <fun>
Which looks a lot like what we were trying to show:
f x y = (f' x) y
This, of course, brings up the topic of currying, which is the style
of writing the arguments just like above. By contrast, in "uncurried"
style, we might have:
f (x, y) = ...
and in that case there is only one "argument": a tuple (a, b). Functions
written in uncurried form can't take advantage of partial application,
they apply to the entire tuple at once.
Why is partial application so useful? Well, you can take a partially
applied function, and put it in a list, or return it from a function,
or do other nice things with it. At the moment you apply it to its
last argument, it returns a data value, instead of a functional value.
BTW, you can think of () as a real value, instead of "Nothing". It is
just a unique value that is not equal to anything else in OCaml but
itself ("unit").
Anyway, that's my understanding of how things work.
cheers,
doug
Hey Gerd, I'm a beginner so slow down a bit ;-))
You should say not that "Every function takes exactly one argument
and returns exactly one result value."
but that "Every function takes some arguments
and returns exactly one result value."
(* §§§§§§§§§§§§§§§§§§§§§§§ DISCUSSION §§§§§§§§§§§§§§§§§§§§§§§§§§§§§§ *)
The result value of the application of a function in Ocaml may (ONLY?) be:
___________________________________
1) one bare value or set of values;
# let functa x = 3*x;;
val functa : int -> int = <fun>
# functa 3;;
- : int = 9
( 9 is the value )
___________________________________
2) one function that need further informations to terminate into one bare
value or set of values;
# let functb x y = 3*x;;
val functb : int -> 'a -> int = <fun>
# functb 3;;
- : '_a -> int = <fun>
( "hey! you promised a y and I still want a y!"
In functional programming when you use a function
with no arguments it doesn't care, it will keep it and
try to evaluate it later on or just keep it symbolic
(so it will be saying things like
"Hi, if you give me an integer I give you back a boolean").
I like to think about a football player kicking the ball forward
and running after it for touching it again.
This is called "partial application" and I think that the
last valid touch is called "closing a function")
___________________________________
3) (), that is more or less "Nothing"
# let f () = print_string " BEGINNERS UNITE! " ;;
val f : unit -> unit = <fun>
# f ();;
BEGINNERS UNITE! - : unit = ()
( f wanted no argument, but if I call
# f;;
- : unit -> unit = <fun>
it just shows its structure, so I need to say
"f Nothing"! and then it works.
It gives Nothing back because the ACTION of printing is not a BARE VALUE.)
Look:
# let a = ref 3;;
val a : int ref = {contents = 3}
(I say that there's a place called "a" and I park "3" there;
it's different from let a = 3;; because like that I say that "a" IS "3")
# !a;;
- : int = 3
(go and look in the place of "a"; there's a "3" parked there)
# let functc x = (x := !x + 1);;
val functc : int ref -> unit = <fun>
(I write a function that takes the name of a place and parks
in it the value that is parked in it now plus 1)
# functc a;;
- : unit = ()
(Apply the function: RESULT VALUE is Nothing!)
# !a;;
- : int = 4
(Ah! so it worked. (3+1) is now parked in the place of "a")
(What if I define the function not as a "parking" action
but directly as a value?)
# let functd x = !x + 1;;
val functd : int ref -> int = <fun>
# functd a;;
- : int = 5
(I don't get Nothing, I get a bare value!
But I didn't park it, so if I go and check in the place of "a")
# !a;;
- : int = 4
(Gee, I've wasted a function!)
(* §§§§§§§§§§§§§§§§§§§§§§§ CONCLUSION §§§§§§§§§§§§§§§§§§§§§§§§§§§§§ *)
So (beginner's opinion!):
WHEN YOU SEE (), THINK THAT SOMETHING HAPPENED SOMEWHERE ELSE.
WHEN YOU SEE A BARE VALUE, THANK OCAML AND DOUBLE-CHECK IT.
WHEN YOU SEE STILL A FUNCTION, FEED OCAML (ocamlgotchi? ;-))
WHEN YOU WANT TO WRITE SOMETHING THAT "IS A FUNCTION BUT ISN'T THE FUNCTION
OF ANYTHING"... KNEEL DOWN AND START WORSHIPPING IT!
---------------------------
Ciao
Ernesto
Matthew O'Connor <matthew.oconnor@...> schrieb am 07.02.2002,
06:02:06:
> Hi,
>
> I was wondering how I would go about adding functions that
> take no arguments into a list?
>
> Can it be done? If not why not?
I think I have understood your problem. In other languages, functions
usually take n >= 0 arguments and return exactly one result (well,
there is usually a variant returning no result; in old Pascal days
we called them "procedures"). So you have to distinguish syntactically
between "I mean the function as such", and "I mean the function after
being applied". For example, in C you can write "f" if you mean the
function as such, and write "f()" if you mean the result.
The Caml model is different. Every function takes exactly one argument
and returns exactly one result value. There is no exception from this
rule in the whole language. So you cannot write an expression meaning
"the function without arguments" because there is no such thing in
the language.
Because there is the frequent case that you do not want to pass
information to a function, there is the "unit" type. unit has only
one member, the thing, written (). You could define unit = { () }
(if types were sets). () is also used to model "I don't want to
return information from a function". So a "procedure" in other
languages without arguments and without result is in Caml a
function accepting () and returning (), e.g.
let f() = ...; ();;
and f is typed: f : unit -> unit.
If you simply write
let f = ... ;;
you don't define a function. The expression "..." is immediately
evaluated, and the result of the expression is bound to f. "let"
simply binds values to names, and because functions are values in
Caml it is not surprising that the same syntacical construct "let"
can be used to define functional and non-functional named values.
I hope this helps (and expecting more questions on this topic),
Gerd
I'm not sure what you meant. All functions must take parameters. Do you
mean a function that takes parameters, but just wasn't given any? Then make
sure all the functions you're trying to put into the list have the same
type; that is, they take the same types of parameters and return the same
type. For example:
$ ocaml
Objective Caml version 3.03 ALPHA
# let fn1 x = 2 * x;;
val fn1 : unit -> int = <fun>
# let fn2 x = x * x;;
val fn2 : unit -> int = <fun>
# let fn3 x = true;;
val fn3 : unit -> unit = <fun>
# [fn1;fn2];;
- : (unit -> int) list = [<fun>; <fun>]
# [fn2;fn3];;
^^^
This expression has type int -> bool but is here used with type int -> int
That was an error because fn2 and fn3 return different types. fn1 and fn2
were okay because they took and returned the same types.
Ryan Tarpine, rtarpine@...
"To err is human, to compute divine. Trust your computer but not its
programmer."
- Morris Kingston
_________________________________________________________________
Send and receive Hotmail on your mobile device: http://mobile.msn.com
I'm using Ocaml 3.04.
I found this at http://caml.inria.fr/ocaml/Changes
=========================================================
- Libraries (.cma and .cmxa files) now "remember" C libraries given
at library construction time, and add them back at link time.
Allows linking with e.g. just unix.cma instead of
unix.cma -custom -cclib -lunix
=========================================================
And here is an example:
I'm studying the Graphics module.
I have built a Graphics-enabled interpreter toplevel using:
$ ocamlmktop -custom -o ocamlgraphics graphics.cma -cclib -lX11
$ ./ocamlgraphics
---------------------------------------------------------------------
And I can compile the bytecode version of a program using:
$ ocamlc -custom graphics.cma -cclib -lgraphics -cclib -lX11 -o
my_graphics.bin my_notes_graphics.ml
---------------------------------------------------------------------
With ocamlopt, I use not the .cma (that is a library in bytecode) module but
.cmxa (that is a library in native code)
$ ocamlopt graphics.cmxa -o my_graphics.opt my_notes_graphics1.ml -cclib
-lgraphics -cclib -lX11
---------------------------------------------------------------------
Well, now everything becomes so simple:
---------------------------------------------------------------------
$ ocamlmktop graphics.cma -o ocamlgraphics
$ ocamlc graphics.cma -o my_graphics.bin my_notes_graphics1.ml
$ ocamlopt graphics.cmxa -o my_graphics.opt my_notes_graphics1.ml
---------------------------------------------------------------------
Cheers
Ernesto
1) A list of functions exists (well, it's functional programming after all)
# let fof x y = x*y;;
val fof : int -> int -> int = <fun>
# let fof1 x y = x+y;;
val fof1 : int -> int -> int = <fun>
# fof1::fof::[];;
- : (int -> int -> int) list = [<fun>; <fun>]
2) But what is a function without an argument?? Do you mean a function named
but not solved such as "fof"
# fof;;
- : int -> int -> int = <fun>
( I think that computing with symbolic expressions is called "lambda
calculus")
or some mathematical concept that I'm crudely missing?
Cheers
Ernesto
Alle ore 00:02, giovedě 07 febbraio 2002, Matthew O'Connor ha scritto:
> I was wondering how I would go about adding functions that
> take no arguments into a list?
Hi,
I was wondering how I would go about adding functions that
take no arguments into a list?
Can it be done? If not why not?
Thanks in advance,
Matthew
I'm glad this group was formed. I have been one of the (many?) people who
read nearly every message of the main list but never posted once. Looking
forward to more "reachable" discussions :)
Ryan Tarpine, rtarpine@...
"To err is human, to compute divine. Trust your computer but not its
programmer."
- Morris Kingston
_________________________________________________________________
Get your FREE download of MSN Explorer at http://explorer.msn.com/intl.asp.