TclLists <-> TclStrings

1 view
Skip to first unread message

Will Coleda

unread,
May 29, 2005, 11:17:11 AM5/29/05
to perl6-i...@perl.org

Tcl has a need to be able to convert between Lists and Strings. All of the
morphing samples that are in, say, PerlUndef are for scalars.

Right now, I have a PIR method, "_Tcl::__stringToList" that takes a string,
and then uses the tcl parser to split it up into a list.

What I'd like to do is create a "set_string_native" method on TclList, so I
can have pir like:

$P1 = <some pmc>
$I1 = does "array"
if $I1 goto got_list
# convert to a list...
$S1 = $P1
$P1 = new TclList
$P1 = $S1
got_list:
# now $P1 has an actual list object.

I've already got the code that converts a string to a list... but I can't
figure out how to, from inside tcllist's set_string_native, to *replace* the
existing PMC with the new list PMC.

Anyone have any pointers on that, or, on a better way to solve the problem
of morphing between a scalar and an aggregate?

Thanks.

Leopold Toetsch

unread,
May 30, 2005, 3:44:27 AM5/30/05
to Will Coleda, perl6-i...@perl.org
Will Coleda <wi...@coleda.com> wrote:

> Tcl has a need to be able to convert between Lists and Strings. All of the
> morphing samples that are in, say, PerlUndef are for scalars.

> Right now, I have a PIR method, "_Tcl::__stringToList" that takes a string,
> and then uses the tcl parser to split it up into a list.

> What I'd like to do is create a "set_string_native" method on TclList,

While it's certainly doable to morph a list to a string and vv, it's a
bit tedious and it doesn't really match you description above.

I'd just do:

pmclass TclString ... {

METHOD PMC* stringToList() {
// create new list and return it
}
METHOD PMC* listToString() {
return SELF; // already a string
}
}

pmclass TclList ... {

METHOD PMC* listToString() {
// create new string from the list and return it
}
METHOD PMC* stringToList() {
return SELF;
}
}

$P1 = $P0."stringToList"()

leo

William Coleda

unread,
May 30, 2005, 9:56:22 AM5/30/05
to l...@toetsch.at, perl6-i...@perl.org
Yeah, the PIR I showed was a bit of a hack based on current functionality. Thinking about it more, I think we do need to have true morphing between TclLists and TclStrings, especially we get to true language interopability.

This is a problem with the current set of vtables, because while I can extract the string value from a list using vtables, I don't think there's a vtable for "extract list".

Now, I can certainly hack things up in Tcl like our combination of examples, where I call non-standard methods on any PMCs I see to force this conversion. What I really want is the ability to say:

$S0 = $P0 # get string value of PMC, whatever it is. This is currently doable.

this way I can support either

puts "this is a string"

or

puts [list this is a list]

Without having any special method. Any PMC that gets passed into Tcl."puts"() can be printed without having to know it's type.

The problem comes with automatically treating things like lists instead of strings. Because of the current lack of vtable support, creating a method is the way of doing something like:

set a [list a b c]
lappend a d e f

lappend take the variable "a", treats it like a list, and then adds 3 more elements. This version works fine, but:

set a "a b c"
lappend a d e f

needs to somehow get the list representation of the named variable. So, of your four methods listed, I don't need "listToString", because get_string works just fine for that. that leaves the two "...toList" methods. Which I *can* add, but it means that if anyone wants to use tcl from the another language, they are going to have support my PMC interface... Isn't extending the basic interface the best way to acheive this? ( I realize that from the calling standpoint, a generic METHOD looks like a vtable; but I'd like to use only standard mechanisms for this, so Tcl isn't balkanized from the rest of the languages)

Regards.

Bob Rogers

unread,
May 30, 2005, 10:52:54 AM5/30/05
to William Coleda, l...@toetsch.at, perl6-i...@perl.org
From: William Coleda <wi...@coleda.com>
Date: Mon, 30 May 2005 09:56:22 -0400

Yeah, the PIR I showed was a bit of a hack based on current
functionality. Thinking about it more, I think we do need to have
true morphing between TclLists and TclStrings, especially we get to
true language interopability.

This is a problem with the current set of vtables, because while I
can extract the string value from a list using vtables, I don't think
there's a vtable for "extract list".

I don't think there can be, since there are probably multiple
definitions of what a "list" is.

. . . but:

set a "a b c"
lappend a d e f

needs to somehow get the list representation of the named variable.
So, of your four methods listed, I don't need "listToString", because
get_string works just fine for that. that leaves the two "...toList"
methods. Which I *can* add, but it means that if anyone wants to use
tcl from the another language, they are going to have support my PMC
interface... Isn't extending the basic interface the best way to

acheive this? (I realize that from the calling standpoint, a generic


METHOD looks like a vtable; but I'd like to use only standard
mechanisms for this, so Tcl isn't balkanized from the rest of the
languages)

Regards.

Two observations:

1. Seems to me that the two operations are "coerceToList" and
"coerceToString", and (as you point out) coerceToString is already what
get_string does. But (I am guessing) you require "Tcl list" behavior
from the result, e.g. a Lisp list wouldn't do, as it would be
represented incompatibly. If that is true, then people writing Tcl
calls from other languages may indeed have to deal with your TclList
PMCs -- that seems unavoidable. In that case, though, the other
operator really ought to be called something like "coerceToTclList".

2. If you write a coerceToTclList method on String, instead of/in
addition to one on TclString, then that ought to give you pretty
complete language interoperability.

Looking at the bigger picture, it is IMHO unreasonable to expect a
single standard mechanism across all languages, since each language is
going to have its own idiosyncratic semantic requirements. Instead,
each language needs to define its own standard interface for its own
needs, and then implement that interface on the most fundamental classes
possible, so that other languages pick up most of their interoperability
with the first language for free. In an ideal world, the other
languages wouldn't even need to be aware of the first language. In
reality, there will probably be some exceptions, which is fine; they
become the problem of the implementor of the other language.

In other words, I believe that these interfaces need to be (a)
decentralized, so that language implementors have maximum freedom to do
what they need, and (b) heritable from Parrot base classes, so that
interoperability with other languages is automatic.

-- Bob Rogers
http://rgrjr.dyndns.org/

Leopold Toetsch

unread,
May 30, 2005, 11:52:24 AM5/30/05
to William Coleda, perl6-i...@perl.org
William Coleda wrote:

> set a "a b c"
> lappend a d e f
>
> needs to somehow get the list representation of the named variable.

Ok. It could be that this functionality just maps to Perl's list
context, which isn't supported by vtables either:

$I0 = $P0."__get_bool"() # int only
$S0 = $P0."__get_string"() # string only

$P1 = $P0."__get_numeric"() # missing +numeric context
"__get_list"()
...
nore PMC only context methods.

leo

Reply all
Reply to author
Forward
0 new messages