Forum OpenACS Q&A: Additions to the tcl language

Collapse
Posted by Tony Kirkham on

What is the current philosophy / thought on adding fundamental tcl commands to OACS?

I want to add a sub command to the tcl dict command and am wondering if it is something that we would want to add to the OACS core and where. Would it go in a loaded tcl module, in an ...init.procs in acs-tcl, or just where?

The addition is a dict getnull sub command that returns the empty string instead of throwing an error when a "get" of a non-existing key is requested. Here is the suggested addition. I found it at http://wiki.tcl.tk/19948. As can be seen, this slips the getnull into the sub commands of dict and appears and is used as any other native sub command of dict.

proc ::tcl::dict::getnull {dictionary args} {
    if {[exists $dictionary {*}$args]} {
        get $dictionary {*}$args
    }
}
namespace ensemble configure dict -map\
    [dict replace [namespace ensemble configure dict -map]\
                  getnull ::tcl::dict::getnull]

Any thoughts? Thanks,

-Tony Kirkham
Collapse
Posted by Brian Fenton on
Hi Tony

personally I would put something like that in acs-tcl, but I'm sure you'll get other opinions on the matter too!

Does it need a rename on an existing proc?

Brian

Collapse
Posted by Antonio Pisano on
Hello Tony,

my personal two cents here: although I can see why one could need such a feature, I would not modify a standard tcl command for this. Chances are that this could get overridden or conflict in future tcl versions.

If this ever should make it to the openacs codebase, I would say it should go into a separate proc e.g. util::dict_get.

What is wrong with a oneliner like this? No procs involved and should do the trick

set value [expr {[dict exists dict noexist] ? [dict get dict noexist] : ""}]

Collapse
Posted by Tony Kirkham on
That does work. It is just not as succinct.

I can understand the concern with future conflicts. To protect against that a check could wrap the creation of getnull so that, if it already exists, this code would not override it and a warning could be logged to leave tracks.

Collapse
Posted by Benjamin Brink on
Hello Tony Kirkham,

Package developers usually implement changes within a separate package.

This usually precludes modifying an existing proc. Changing behavior on an existing proc may adversely affect another that, for instance in this case, expects an error.

If the changes are applicable to the core, core developers tend to find it and incorporate it directly, or by copying the functionality of the code while improving on it.

FWIW, there are a few practical variations of the Tcl dict paradigm in Q-forms package, mainly regarding looping and converting a batch of name values from/to array, lists, and scalars. Special cases allow limiting the names, or assigning an empty string if a value is not found for named index etc.

cheers,
Ben

Collapse
Posted by Tony Kirkham on
Thanks for the comments and feedback.

This change is not changing existing behavior. It is adding behavior in the form of a new sub command which amounts to a more succinct way to express something than what currently exists.

So instead of writing things like (which is suggested above)
set a [expr {[dict exists dict_val key] ? [dict get dict_val key] : ""}]
-or-
if { [dict exists dict_val key] && [dict get dict_val key] ne "" } ...

we could write
set a [dict getnull dict_val key]
-or-
if { [dict getnull dict_val key] ne "" } ...

I am considering adding it to my systems and wondered if the community would find value in it and where it made the most sense to place something like this.

-Tony

Collapse
Posted by Benjamin Brink on
Hi Tony,

The most direct approach to add to acs-core is to post a TIP. This thread is about that:
https://openacs.org/forums/message-view?message_id=3472610

cheers,
Ben