caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* Labels and operators
@ 2000-06-19  4:14 John Prevost
  2000-06-22  1:48 ` Ken Wakita
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: John Prevost @ 2000-06-19  4:14 UTC (permalink / raw)
  To: caml-list

A friend of mine recently said "if ML had regexp stuff that was as
convenient as Perl, I'd switch to it for everything", and mentioned =~
as something he specifically wanted.  So, as I was walking home
tonight, I thought "hey, I bet I could make some little operators for
the PCRE library and show him!"

But, it also occurred to me that you want to use the nice labelled
optional argument stuff, and I wasn't sure you could do that with
operators.  Here's what I've discovered.

The following definition is kind of non-sensical, since obviously you
need at least one and probably at least two arguments for an infix
operator:

# let (+) ?(x = 1) ?(y = 1) () = x + y;;
val ( + ) : ?x:int -> ?y:int -> unit -> int = <fun>

but, well, it accepts it.  Now, let's see if we can apply this
operator as a function.

# (+) ();;
- : int = 2
# (+) ~x:5 ();;
- : int = 6
# (+) ~x:5 ~y:5 ();;
- : int = 10

Okay, that's as expected.  What about as an operator?  Well, the first
case is obviously degenerate, since we're not giving enough arguments
for a two argument operator.  What about the second and third:

# ~x:5 + ();;
  ---
Syntax error
# ~x:5 + ~y:5 ();;
  ---
Syntax error

Well, that's a little disappointing.  I sort of half expected it,
though, since this isn't function application we're dealing with.

Here's what I was *trying* to do:

# let (=~) s ?iflags ?flags ?rex ?pos pat =
    pmatch ?iflags ?flags ?rex ~pat ?pos s;;
val ( =~ ) :
  string -> ?iflags:Pcre.irflag -> ?flags:Pcre.rflag list ->
    ?rex:Pcre.regexp -> ?pos:int -> string -> bool = <fun>
# "foo" =~ "\s+";;
- : bool false
# "foo" =~ "f";;
- : bool true
# "foo" =~ "f" ~pos:1;;
           ---
This expression is not a function, it cannot be applied
# ("foo" =~ "f") ~pos:1;;
  --------------
This expression is not a function, it cannot be applied
# (=~) "foo" ~pos:1 "f";;
- : bool false
# (=~) "foo" "f" ~pos:1;;
- : bool false

The only solution I can think of is something like:

# let re ?iflags ?flags ?rex ?pos pat = (iflags, flags, rex, Some pat, pos)
val re :
  ?iflags:'a -> ?flags:'b -> ?rex:'c -> ?pos:'d -> 'e ->
    'a option * 'b option * 'c option * 'e option * 'd option =
  <fun>
# let (=~) s (iflags,flags,rex,pat,pos) =
                   pmatch ?iflags ?flags ?rex ?pat ?pos;;
val ( =~ ) :
  string ->
  Pcre.irflag option * Pcre.rflag list option * Pcre.regexp option *
  string option * int option -> bool = <fun>
# "foo" =~ re "f";;
- : bool = true
# "foo" =~ re "f" ~pos:1;;
- : bool = false

Which, well, works, but seems kind of nasty.


Since the syntax of labeled arguments is based around function
application, and since function application (juxtaposition) has higher
precedence than any other "operator", I can see why it's not
syntactically valid to try to use labels on arguments to an operator.
I don't see any clean way of "fixing" this, so I figured I ought to
warn people that while you can define an operator with labeled
arguments, you're not going to get much use of it as an infix.

Well, okay, I think it might be reasonable to change the syntax to
allow this syntax:

<expr1> <op> <labelled args> <expr2>

since the labelled args could not in any way shape or form be thought
to go with either expr1 or expr2.  This would lead to things like:

# "foo" =~ ~pos:1 "f";;
- : bool = false

being possible.  Don't know whether it's a great idea, though.



John.



^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2000-06-26 10:29 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-06-19  4:14 Labels and operators John Prevost
2000-06-22  1:48 ` Ken Wakita
2000-06-22  5:19 ` Jacques Garrigue
2000-06-24 14:44 ` Markus Mottl
2000-06-24 18:03   ` John Prevost

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).