From: John Prevost <prevost@maya.com>
To: Judicael Courant <Judicael.Courant@lri.fr>
Cc: caml-list@inria.fr
Subject: Re: Camlp4's (lack of) hygiene (was Re: Macros)
Date: 10 Jul 2000 09:16:39 -0400 [thread overview]
Message-ID: <87r992nn0o.fsf@isil.localdomain> (raw)
In-Reply-To: Judicael Courant's message of "Mon, 10 Jul 2000 13:42:25 +0200 (MEST)"
>>>>> "jc" == Judicael Courant <Judicael.Courant@lri.fr> writes:
jc> Notice that even O'Caml itself (I mean without camlp4) already
jc> has this problem:
jc> # let x = [| 1 ; 2 |];;
jc> val x : int array = [|1; 2|]
jc> # module Array = struct end;;
jc> module Array : sig end
jc> # x.(1);; (* guess what happens... *)
jc> Unbound value Array.get
jc> # (* x.(1) just expands to Array.get x 1 *)
Ugh... That's horrible! On the one hand, I can see how it could be
useful from the point of view of using different implementations of
arrays, but on the other hand, it's a mess.
Especially considering the description of array syntax in the manual:
------------------------------------------------------------------------
Arrays
The expression [| expr1 ; ... ; exprn |] evaluates to a n-element
array, whose elements are initialized with the values of expr1 to
exprn respectively. The order in which these expressions are evaluated
is unspecified.
The expression expr1 .( expr2 ) returns the value of element number
expr2 in the array denoted by expr1. The first element has number 0;
the last element has number n-1, where n is the size of the array. The
exception Invalid_argument is raised if the access is out of bounds.
The expression expr1 .( expr2 ) <- expr3 modifies in-place the array
denoted by expr1, replacing element number expr2 by the value of
expr3. The exception Invalid_argument is raised if the access is out
of bounds. The value of the whole expression is ().
------------------------------------------------------------------------
These are described in terms of operations on the base array type.
The fact that the operations are implemented as sugar shouldn't mean
that the behavior is different from what you would expect. Normal
function calls have better behavior than this--all the more reason
that constructions which are part of the language definition should
work in a safe manner.
Also of note, of course, is that [| ... |] *does* work, no matter what
bindings are in scope.
If no change is made to make this safer, the language definition
should be changed to note that writing "expr1 .( expr2 )" is
completely identical to "Array.get expr1 expr2" for purposes of
scoping.
Finally, I'd like to note that the same properties occur with strings:
# "foo".[1];;
- : char = 'o'
# module String = struct end;;
module String : sig end
# "foo".[1];;
---------
Unbound value String.get
While I've actually never been tempted to create an Array module by
that name (I might be tempted a little with the current discussion on
clf about fast persistent arrays), I have in fact created a String
module. At the time, I was working on some wide character stuff.
I suppose that, on one hand, this points out why things are good:
module Wide = (struct
type ochar = char
type char = int
type ostring = string
type string = char array
let o_to_char = Char.code
let o_to_string = (* I'm too lazy to write this for you *)
(* other stuff *)
module String = struct
let get = Array.get
let set = Array.set
end
end : sig
type ochar = char
type char
type ostring = string
type string
val o_to_char : ochar -> char
module String : sig
val get : string -> int -> char
val set : string -> int -> char -> unit
end
end)
By opening this, you're instantly using wide characters instead of 8
bit characters. (Except for the little "constants" problem.) But,
like with arrays, I think you might be justifiably confused if you did
this, and .[ ] stopped working "normally", and yet quotation marks
still worked the same. Especially when you mostly want .[ ] for "byte
array" "strings" more than strings.
Allowing .() and .[] to somehow be bound would be a different matter.
Then normal scoping would apply, and you'd expect it.
Gah. In any case, these rough edges are making me start to hate
syntax (not just Caml's) as a whole class of experience. (Though I
still like Caml's more than SML's. :)
John.
next prev parent reply other threads:[~2000-07-16 21:55 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <8js72h$11h$1@nnrp1.deja.com>
[not found] ` <Pine.LNX.4.21.0007041051140.20796-100000@punaluu.informatik.uni-freiburg.de>
[not found] ` <8juuep$420$1@news.planetinternet.be>
[not found] ` <u0lmzhyllz.fsf@hana.kurims.kyoto-u.ac.jp>
[not found] ` <8jv92l$qpb$1@bird.wu-wien.ac.at>
[not found] ` <u0wvj0datl.fsf@hana.kurims.kyoto-u.ac.jp>
2000-07-07 2:03 ` John Prevost
2000-07-07 23:42 ` John Prevost
2000-07-10 9:37 ` Daniel de Rauglaudre
2000-07-10 10:17 ` John Prevost
2000-07-10 11:42 ` Judicael Courant
2000-07-10 13:16 ` John Prevost [this message]
2000-07-17 10:08 ` Markus Mottl
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87r992nn0o.fsf@isil.localdomain \
--to=prevost@maya.com \
--cc=Judicael.Courant@lri.fr \
--cc=caml-list@inria.fr \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox