Version 4 of Islist Extension

Updated 2006-01-23 20:45:35

This is a little extension that will check wether a var is (internally) a list or not. Someone wanted something like this so I tried it. The good thing is, it works :) but since im not really into C I did not know how to dynamically (?) link it. So I guess you will need to edit the tcl.h include if you folder differs.

I just though I'd post it here, in case someone was looking for something similar, or just wanted another simple (!) extension example.


See also critcl.


 /*
 * islist.c --
 *
 *    A dirty Check for list.
 *
 *    (c) Gotisch
 */
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 #include "/usr/include/tcl8.4/tcl.h" 

 static int
 Islist_Cmd(
  ClientData cdata,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[])
  {
   if (objc < 2) {
      Tcl_SetObjResult(interp, Tcl_NewStringObj("No Argument given...", -1));
      return TCL_ERROR;
   }
   if (objv[1]->typePtr == NULL) {
      Tcl_SetObjResult(interp, Tcl_NewIntObj(0));
   } else if (strcmp(objv[1]->typePtr->name,"list")==0) {
      Tcl_SetObjResult(interp, Tcl_NewIntObj(1));
   } else {
      //Tcl_SetObjResult(interp, Tcl_NewStringObj(objv[1]->typePtr->name, -1));
      Tcl_SetObjResult(interp, Tcl_NewIntObj(0));
   }
   return TCL_OK;
  }
  /*
  * Islist_Init --
  *
  *    Called when Tcl [load]'s your extension.
  */
 int
 Islist_Init(Tcl_Interp *interp)
 {
   if (Tcl_InitStubs(interp, TCL_VERSION, 0) == 0L) {
      return TCL_ERROR;
   }
   Tcl_CreateObjCommand(interp, "Islist", Islist_Cmd, NULL, NULL);
   Tcl_PkgProvide(interp, "Islist", "1.0");
   return TCL_OK;
 }

to compile like this

  gcc -shared -DUSE_TCL_STUBS islist.c -o islist.so -ltclstub8.4

and then use like this

 % load ./islist.so
 % Islist [list 1 2 3]
 1
 % Islist "this is a string"
 0
 % Islist [split "this is a list because we split it"]
 1

This also shows how TCL is switching the internal representation of variables

 % set a [list 3] 
 3
 % Islist $a 
 1
 % incr a
 4
 % Islist $a
 0

First its a list, then it gets (internally) converted to a integer (i think).


male 2006-01-23:

In my eyes it is very important to program with tcl in a way, that prevents shimmering, if the application to be developed has to handle a lot of probably large or huge lists and has to do a lot of numerical work!

A kind of developer extension to get a kind of statistic about shimmering, to get to know the most critical parts in an algorithm ... that would be real fine!

Some people already suggested to extend the info command to obtain object types and/or to convert objects into specified types.

This would be helpful to get more knowledge about those "shimmering happenings"!

And if it's only about to show some less tcl-driven developers that sometimes problematic situation of shimmering and its consequences!

Best regards,

Martin


NEM Hmm... the above extension violates Tcl' "everything is a string" semantics, and breaks referential transparency. Consider the following:

 % set a "this is a string"
 this is a string
 % set b "this is a string"
 this is a string
 % llength $b
 4
 % expr {"$a" == "$b"}
 1
 % Islist $a
 0
 % Islist $b
 1

So, here we have two values that are "equal" in Tcl's eyes and yet are we cannot substitute one for the other, as they are not really equal. We have replaced Tcl's referentially transparent value semantics (where we can substitute equal terms) with a referentially opaque reference semantics where we have to distinguish between objects which are equal values and those which are equal references. To make matters worse, you can now cause unwanted side-effects due to shared references (carrying on session above):

 % set c $a ;# now shared
 this is a string
 % Islist $a
 0
 % llength $c
 4
 % Islist $a
 1

There may be occassional legitimate debugging reasons for finding out the internal type that a Tcl_Obj happens to have at a given time, but it should be something that is used very rarely and you shouldn't base the logic of a program around such information.