ASPN ActiveState Programmer Network
ActiveState
/ Home / Perl / PHP / Python / Tcl / XSLT /
/ Safari / My ASPN /
Cookbooks | Documentation | Mailing Lists | Modules | News Feeds | Products | User Groups


Recent Messages
List Archives
About the List
List Leaders
Subscription Options

View Subscriptions
Help

View by Topic
ActiveState
.NET Framework
Open Source
Perl
PHP
Python
Tcl
Web Services
XML & XSLT

View by Category
Database
General
SOAP
System Administration
Tools
User Interfaces
Web Programming
XML Programming


MyASPN >> Mail Archive >> tcl-core
tcl-core
Re: [TCLCORE] Cloverfield references (was Re: Variable access)
by fbonnet other posts by this author
May 20 2008 7:53AM messages near this date
Re: [TCLCORE] Cloverfield references (was Re: Variable access) | Re: [TCLCORE] Cloverfield references (was Re: Variable access)
Andreas Leitgeb wrote:
> >    set first 1st
> >    foreach next {2nd 3rd 4th} {
> >        lappend l3 ($&first $next)
> >    }
> >    puts $l3; # ({ref <id>}1st 2nd) ({ref <id>}{} 3rd) ({ref <id>}{} 4th)
>  
>  Ah, ok, so now this is with external ref, then.
>  
>  I'm however somewhat struck by odd, as to the auto-internalizing of refs,
>  and what I'd deduce as logical consequence:
>  
>  set l3_copy $l3 ;# still with extref to "first"
>  # mod on $&l3_copy{0 0} reflects in $first and in $l3, right?

Yes. Both l3 and l3_copy hold a reference to the same value at {0 0}, so 
modifying this value reflects everywhere.

>  #   Out of curiosity, is there a way to see that "first"'s
>  #   value is currently ref-shared? 

I think references will need a whole set of dedicated commands for 
introspection and the like. This is conform to the Tcl philosophy, where 
the core language is very small and what would be keywords in other 
languages is provided by commands.

For example, the ensemble command "reference" or "ref" could provide a 
"set" subcommand to change a referenced value, versus the toplevel "set" 
command that changes the binding of a given variable (or part thereof) 
to a new value. Likewise, "reference shared" could return whether a 
referenced value is shared across contexts (and hence is externalized). 
Another command could be used to "prune" external refs so that it can be 
safely used without side effects (for example when passing strings 
around interps).

As a sidenote, I think that the whole concept of references and values, 
and their associated semantics, could be expressed more formally using 
graph theory. This would clarifies things a lot.

>  unset first; # assuming no previous further spreading of $&first
>  
>  set l3_2ndcopy $l3
>  # mod on $&l3_2ndcopy{0 0} does *not* reflect in $l3, right?

Right. Since the reference is no longer external (as only one variable 
refers to the value), then it becomes internal, so copy-on-write 
semantics fully apply.

> > <id> being some identifier. But there's a subtlety in the sense that the 
> > reference is no longer intern but extern, ie it refers to an outer 
> > variable. So copying the value preserves the external reference. 
>  
>  And what if I did it the other way round:
>  set l4 (({ref a}1st 2nd) ({ref a}{} 3rd))
>  set ext $&l4{0 0}
>  # does this make the reference "a" external, such
>  # that a copy of $l4 made afterward would then still
>  # share the ref?

Yes (as long as ext refers to it). So it's fully symmetric.

> > A structure with references can be used in an immutable way.
>  
>  A structure with external refs can be used in an immutable way,
>  but still behaves like partially mutable, as you explained in
>  your answer to my first question. But that's just a sidenote,
>  not the point of this question.

True. But a structure with external refs is partially mutable only if a 
mutable op is performed on a subpart of it. If only immutable ops are 
performed, then the whole structure remains untouched.

> > (assuming that Tcl's lreplace is kept as such, and converted to accept
> > references as arguments).
>  If lreplace was thusly converted, why not lrange?

That's a good question. Slicing (like lrange does) is an immutable 
operation, as it doesn't alter the original structure.

However Cloverfield provides a syntax for slicing:

set l (0 1 2 3 4)
set l2 $&l{1..3} ; # l2 points to l's [1-3] subrange
lreplace $&l2 1 1 foo
puts $l2 ; # =>  1 foo 3
puts $l ; =>  0 1 foo 3 4

When used on values, this syntax is equivalent to lrange. So for 
consistency, lrange, when given a reference as argument, would return a 
reference to a sublist of its argument (but wouldn't modify the 
argument, so it's still an immutable operation).

> > # Cloverfield
> > set i 1
> > set ref $&i    # ref is 1
> > setref $&ref 2 # i is 3
>  
>  2? 3? I guess, that's a typo :-)

You're right :*/  That should be "setref $&ref 3".

>  Anyway, this would mean, that: 
> > proc strip {l} {
> >   setref $&l [lrange $l 1 end-1]
> > }
>  would have answered my third question.

Indeed.

> > Unless we decide that set takes references, but this is a
> > significant departure from Tcl
>  
>  It would obviously not be the first one in cloverfields history :-)

;-)

 >  If "append $&i ..." were an acceptable departure, then
 >  "set $&l ..." wouldn't be less so in my eyes.

To be fair, I think that the current "set" syntax is part of the overall 
look & feel of Tcl. E.g.

set i 1
set j $i

I wouldn't want Cloverfield to look like:

set $@i 1
set $&j $i

Much less readable IMHO. Besides, if "set" accepts references instead of 
variable names, it means that we would need another command that does 
the reverse in order to support both semantics (i.e. alter value vs. 
point to value). This is the same dichotomy in C (*p = i vs. p = &i). So 
we would recreate "set" with a different name.

> > And now for fun, enter inline expansion {*}:
> > set v {ref root}(a {*}{ref root}{})
>  
>  That beats me.  Is this still just discussion of "what would be"
>  or is there already a demo-implementation that accepts this?

This is guaranteed 100% vaporware ;-)   Actually, my goal regarding the 
implementation is to allow such a construct.

>  I probably wouldn't allow that particular construction, since 
>  I believe that this behaviour is really impossible to implement
>  generally.
>  e.g.: 
>     proc b {} {puts "b called"}
>     set v {ref root}(a {*}{ref root}{} [b])
>  The second element (thus the whole structure) is immediately
>  inlined, before the third element has even be parsed. That 
>  can't go.

Why? The above code only builds a list with 3 nodes: first is value "a", 
second is an inline-expanded node that points to its container, and 
third is [b] (here, an empty string). The only difference between refs 
with and without {*} is the inline expansion flag. Of course foreach'ing 
such a list would cause an endless loop, but the syntax is valid and 
serializable (thanks to the serialize-first-only rule). So creating 
"infinite lists" (AKA circular lists) is trivial.

> >> Fifth question:
> >> Flattening:
> >> % set f1 [list {*}$v];# stringrep=??
> > Each of v's elements are passed as value to [list], so:
> > (1 2 3) (1 2 3) (1 2 3)
>  
>  % set f1 [list {*}$&v];# stringrep=??
>  % set f2 [list $&v{0} $&v{1} $&v{2}]; # ...
>  refs retained or lost?

Both are equivalent, ie they build a list of references to the same 
value, so the references are retained (and output in the string rep).

>  (and a new) Sixth Question:
>  Does this {...} "lindex"-syntax have a pendant for dicts?

Yes, using parentheses (like with Tcl's arrays):

set v (a (b 1 c 2) d (3 4 5))
puts $v(a) ; # =>  (b 1 c 2)
puts $v(a b) ; # =>  1
puts $v(d){1} ; # =>  4
puts $v{1}(c) ; # =>  2

>  How does treating an even sized list as a dict work with ref's
>  both for keys and values?
>  e.g. puts [dict get ({ref a}2 {ref a}{} 3 {ref a}{})]
>  I really wouldn't believe refs to work as keys.

Dicts use values as keys. The ref is just metadata. So value-wise, the 
above code is equivalent to:

puts [dict get (2 2 3 2)]

(all references point to the same value 2).


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft 
Defy all challenges. Microsoft(R) Visual Studio 2008. 
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Tcl-Core mailing list
Tcl-Core@[...].net
https://lists.sourceforge.net/lists/listinfo/tcl-core
Thread:
fbonnet
fredericbonnet
Neil Madden
fbonnet
Neil Madden
fbonnet
Lars Hellstrom
fbonnet
Neil Madden
fredericbonnet
David Welton
fbonnet
David Welton
Larry McVoy
Alexandre Ferrieux
Andreas Leitgeb
fbonnet
Neil Madden
Donal K. Fellows
Alexandre Ferrieux
Larry McVoy
Neil Madden
Gustaf Neumann
Neil Madden
Larry McVoy
Neil Madden
Alexandre Ferrieux
fbonnet
Neil Madden
Alexandre Ferrieux
Donal K. Fellows
Larry McVoy
Alexandre Ferrieux
Donal K. Fellows
Alexandre Ferrieux

Privacy Policy | Email Opt-out | Feedback | Syndication
© ActiveState Software Inc. All rights reserved