• Re: tcl hidden "cruelties"

    From aotto1968@21:1/5 to All on Sun Oct 13 14:29:46 2024
    On 10.10.24 12:20, aotto1968 wrote:
    Hi,

    I am in the process of rewriting my ALC compiler, whereby the back-end is being rewritten from "tabular" to "object-oriented".

    Both types of structures have their advantages and disadvantages. The "tabular" structure is suitable for cross-object analysis
    and the "object-oriented" structure is suitable for object-specific analysis.

    Unfortunately, you can only ever use ONE type of data structure, so I now use the "tabular" structure in the FRONT-END and the
    "object-oriented" structure in the BACK-END.

    Anyone who knows TCL knows that "refactoring" TCL code is cruel, because it always ends in a huge amount of "broken" code.


    here we are…

    146 files changed, 8351 insertions(+), 6129 deletions(-)

    ~8351 changes later, the NEW ALC compiler is in duty :-)

    https://www.facebook.com/photo/?fbid=853356390326470&set=a.805828751745901

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rich@21:1/5 to aotto1968@t-online.de on Mon Oct 14 01:44:31 2024
    aotto1968 <aotto1968@t-online.de> wrote:
    Regardless of "broken code", TCL itself has some cruelties in its
    syntax. Here, for example, the storage of an "array" with a
    namespace path, which in TCL always has !! TWO !! commands. ONE
    command to generate the namespace and ONE command to finally generate
    the array.

    namespace eval ::funcDEF::MkErrN {}
    array set ::funcDEF::MkErrN::my {
    RETURN_MAPPING {}
    ...
    }

    This is Tcl. If something is that bothersome, just morph the language
    to be the way you want it to work. I.e.:

    proc ns-array-set {fullvarname contents} {
    namespace eval [namespace qualifiers $fullvarname] {}
    array set $fullvarname $contents
    }

    Create that once, then use it, instead of plain "array set" whenever
    you want to create a namespace, and then set an array within, i.e.:

    % ns-array-set abc::pdq::xyz [list a 1 b 2 c 3]

    Which has now, in a single command, created the parent namespaces, and
    the array variable therein:

    % info exists abc::pdq::xyz
    1
    % parray abc::pdq::xyz
    abc::pdq::xyz(a) = 1
    abc::pdq::xyz(b) = 2
    abc::pdq::xyz(c) = 3
    %

    And, given that the 'array' command is itself a namespace ensemble, you
    could extend the 'array' ensemble to add a "ns-set" (or whatever name
    you like) to the ensemble that performs the above "create ns - and
    init" of a namespace variable, then you could do
    "array ns-set [list a 1 b 2]"
    in your code to replace the two commands.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From aotto1968@21:1/5 to Rich on Mon Oct 14 09:41:04 2024
    On 14.10.24 03:44, Rich wrote:
    aotto1968 <aotto1968@t-online.de> wrote:
    Regardless of "broken code", TCL itself has some cruelties in its
    syntax. Here, for example, the storage of an "array" with a
    namespace path, which in TCL always has !! TWO !! commands. ONE
    command to generate the namespace and ONE command to finally generate
    the array.

    namespace eval ::funcDEF::MkErrN {}
    array set ::funcDEF::MkErrN::my {
    RETURN_MAPPING {}
    ...
    }

    This is Tcl. If something is that bothersome, just morph the language
    to be the way you want it to work. I.e.:

    proc ns-array-set {fullvarname contents} {
    namespace eval [namespace qualifiers $fullvarname] {}
    array set $fullvarname $contents
    }

    Create that once, then use it, instead of plain "array set" whenever
    you want to create a namespace, and then set an array within, i.e.:

    % ns-array-set abc::pdq::xyz [list a 1 b 2 c 3]

    Which has now, in a single command, created the parent namespaces, and
    the array variable therein:

    % info exists abc::pdq::xyz
    1
    % parray abc::pdq::xyz
    abc::pdq::xyz(a) = 1
    abc::pdq::xyz(b) = 2
    abc::pdq::xyz(c) = 3
    %

    And, given that the 'array' command is itself a namespace ensemble, you
    could extend the 'array' ensemble to add a "ns-set" (or whatever name
    you like) to the ensemble that performs the above "create ns - and
    init" of a namespace variable, then you could do
    "array ns-set [list a 1 b 2]"
    in your code to replace the two commands.


    your hint with the "ensemble" feature was good but missing the required code. to "extend" an ensemble is quite complicate in TCL… follow the code below:

    proc ::array-ns-set {fullvarname contents} {
    namespace eval [namespace qualifiers $fullvarname] {}
    array set $fullvarname $contents
    }

    namespace ensemble configure array -map [dict replace \
    [namespace ensemble configure array -map] ns-set ::array-ns-set]

    array ns-set ::x::my [list a 1 b 2]

    parray ::x::my


    1) but the CORE problem is not solved, for every "namespace ns-set ..." command TWO commands
    are executed just to avoid FIRST namespace missing error.
    → (ALL pay runtime-speed just for FIRST benefit)

    2) the syntax to extend an existing ensemble is still very "ugly.."

    improvement:
    1. namespace ensemble add array ns-set ::array-ns-set
    2. namespace ensemble delete array ns-set

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From aotto1968@21:1/5 to All on Sun Oct 20 15:01:25 2024
    git diff --shortstat alc-new-1-lw .
    83 files changed, 5214 insertions(+), 5300 deletions(-)


    The last step in converting the ALC compiler to the "object" structure has now been completed.

    The "attribute database" is the largest and most important database in the ALC architecture because attributes from all other
    databases are stored there and thus there is a connection to all other databases. The "object"-specific attributes are now
    stored in the data structure of the "object", which means that, in contrast to the "table" structure, the "access path" to the
    attribute is now static, which is an *enormous* gain in speed while simplifying the "ALC code".

    The ALC compiler consists of three "layers". "frontend", "middleware" and "backend". The "frontend" now uses the "table"
    structure and the "backend" uses the "object structure". When converting the "backend" from the "table" to the "object"
    structure, hidden "logic problems" came to light that were also eliminated and at the same time it also helps to consolidate the
    "layers" themselves because an analysis can only be implemented most efficiently *either* in the "table" structure or only in
    the "object" structure, which then *necessarily* triggers a certain reorganization of the ALC code.

    The "frontend" layer creates the "meta-code" which:
    1. implements a "singular" definition of information
    2. is "ordered" in terms of structure, which always delivers the same "logic" "output" for "logic"-like "input".
    3. is intended to be stored in the *code repository* in order to ultimately secure the API or to centrally verify a change.
    4. is human-readable and changeable in order to quickly create "test data" to create or to add your own "meta-code" extensions.

    The "middleware" layer creates the "compiler code" which is used *internally* to control the backend very quickly and
    efficiently. In addition, the "middleware" layer has a basic analysis of the "meta-code" and creates a variety of
    "access-oriented" data structures from the "singular" "meta-code". The "middleware" layer uses a type of "hibernate" technology
    to store a "memory dump" on the hard disk after the successful "meta-code analysis". The ALC compiler can also skip the
    "middleware layer" with the command line switch "-force", which then means that the "backend layer" is controlled directly with
    the "meta code", which is of course slower but is used for "recursive compilations" (generation of "meta code" from "meta code").

    The "backend layer" now creates the desired target, which is then a programming language, a data file or any structured data
    storage with a defined format.

    https://www.facebook.com/permalink.php?story_fbid=pfbid037cZ3kX4yBNxZNv8NQ6vtpq6nomq6YCWsjhKpPoXbyQ5RXxRrc9YnMAfoa9dAAtvVl&id=100069563501101

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From et99@21:1/5 to All on Mon Oct 14 10:33:54 2024
    On 10/14/2024 12:41 AM, aotto1968 wrote:


    1) but the CORE problem is not solved, for every "namespace ns-set ..." command TWO commands
    are executed just to avoid FIRST namespace missing error.
    → (ALL pay runtime-speed just for FIRST benefit)

    2) the syntax to extend an existing ensemble is still very "ugly.."

    improvement:
    1. namespace ensemble add     array ns-set ::array-ns-set
    2. namespace ensemble delete  array ns-set


    If you have a proposal to improve the TCL language then the TIP mechanism is the approach to take.

    However, IMHO, namespace commands, especially ones that create namespaces should be done with the [namespace] command. It would be helpful to be able to grep for "namespace" to find all the relevant commands. Having an exception, where some other command
    also can create a namespace seems quite odd to me and could cause some confusion for someone other than the author trying to understand or maintain a TCL program.

    As to performance, I doubt that a command very likely done but once in a program will cause any issues in that regard.

    That said, I wouldn't mind seeing a command:

    namespace create name ?script?

    which seems to me to be an oversight. When I first looked into namespaces, I found it odd that they were created with the eval option. At minimum, this would be a useful self documenting addition.

    -e

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rich@21:1/5 to aotto1968@t-online.de on Mon Oct 14 18:13:51 2024
    aotto1968 <aotto1968@t-online.de> wrote:
    On 14.10.24 03:44, Rich wrote:
    aotto1968 <aotto1968@t-online.de> wrote:
    Regardless of "broken code", TCL itself has some cruelties in its
    syntax. Here, for example, the storage of an "array" with a
    namespace path, which in TCL always has !! TWO !! commands. ONE
    command to generate the namespace and ONE command to finally generate
    the array.

    This is Tcl. If something is that bothersome, just morph the language
    to be the way you want it to work. I.e.:

    proc ns-array-set {fullvarname contents} {
    namespace eval [namespace qualifiers $fullvarname] {}
    array set $fullvarname $contents
    }

    Create that once, then use it, instead of plain "array set" ...

    your hint with the "ensemble" feature was good but missing the required code.

    Yes, I left that exercise to the reader to work out.

    to "extend" an ensemble is quite complicate in TCL… follow the code below:

    As are most /things/ in most programming languages.

    1) but the CORE problem is not solved, for every "namespace ns-set
    ..." command TWO commands are executed just to avoid FIRST namespace
    missing error. → (ALL pay runtime-speed just for FIRST benefit)

    You'll pay that runtime no matter whether it appears as one, or two,
    commands in your source. The 'work' of checking if the namespace
    exists, and then creating it when it does not, has to be paid, no
    matteer how many 'commands' appear in the Tcl script.

    2) the syntax to extend an existing ensemble is still very "ugly.."

    improvement:
    1. namespace ensemble add array ns-set ::array-ns-set
    2. namespace ensemble delete array ns-set

    You can 'wrap' that ugliness into your own proc, and 'extend' the
    namespace ensemble itself, to remove that as well if you like.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From aotto1968@21:1/5 to All on Thu Oct 10 12:20:04 2024
    Hi,

    I am in the process of rewriting my ALC compiler, whereby the back-end is being rewritten from "tabular" to "object-oriented".

    Both types of structures have their advantages and disadvantages. The "tabular" structure is suitable for cross-object analysis
    and the "object-oriented" structure is suitable for object-specific analysis.

    Unfortunately, you can only ever use ONE type of data structure, so I now use the "tabular" structure in the FRONT-END and the
    "object-oriented" structure in the BACK-END.

    Anyone who knows TCL knows that "refactoring" TCL code is cruel, because it always ends in a huge amount of "broken" code.

    Regardless of "broken code", TCL itself has some cruelties in its syntax. Here, for example, the storage of an "array" with a
    namespace path, which in TCL always has !! TWO !! commands. ONE command to generate the namespace and ONE command to finally
    generate the array.

    namespace eval ::funcDEF::MkErrN {}
    array set ::funcDEF::MkErrN::my {
    RETURN_MAPPING {}
    argv {{ME_CXN_MK_MNGN mng}}
    class MkErrorC
    classC MkErrorC
    classM ME_CCC_MkErrorC
    func MkErrN
    prefix Class
    prefixC ClassC
    prefixM ME_CCC_MkErrorC
    retC MkErrorC
    retM ME_CCN_MkErrorC
    retOM ME_CCN_MkErrorC
    ty sm_
    type0M ME_CXN_MK_MNGN
    var0 mng
    }

    mfg

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ralf Fassel@21:1/5 to All on Fri Oct 11 09:51:49 2024
    * aotto1968 <aotto1968@t-online.de>
    | Regardless of "broken code", TCL itself has some cruelties in its
    | syntax. Here, for example, the storage of an "array" with a namespace
    | path, which in TCL always has !! TWO !! commands. ONE command to
    | generate the namespace and ONE command to finally
    | generate the array.

    | namespace eval ::funcDEF::MkErrN {}
    | array set ::funcDEF::MkErrN::my {
    | RETURN_MAPPING {}
    --<snip-snip>--
    | var0 mng
    | }

    Well, you *could* do it in one step, but you don't have to ;-)

    namespace eval ::funcDEF::MkErrN {
    variable my
    array set my {
    RETURN_MAPPING {}
    ...
    var0 mng
    }
    }

    HTH
    R'

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)