• Should I write building blocks?

    From Luc@luc@sep.invalid to comp.lang.tcl on Fri Jan 24 20:34:41 2025
    From Newsgroup: comp.lang.tcl

    I am usually so well rewarded for asking questions here so what the hey.
    Might as well try again.

    I have personal issues. For that reason, my coding habits are spotty
    at best. I don't really abandon my projects. I just postpone them when I
    am not feeling well. But one wouldn't be able to tell the difference. I postpone them for very long periods.

    On top of my personal problems, the long periods of inactivity make
    me very unfamiliar with my own code. Picking up where I left off is
    hard. I have to read everything again and make heads and tails of the
    whole thing and know where to look when the code throws an error.
    It's so bad I sometimes decide to just start over, from scratch.
    The awareness of the wasted effort hurts, but at least I will know
    what I'm doing and where I'm going with the code.

    It's all quite tiresome and discouraging. So I postpone. Again. Again
    and again.

    I like to associate this problem with an old idea of mine: functional programming. I'm sure I've seen that term before but probably with a
    different meaning. I mean writing blocks of code, likely procs (I know you
    lot are going to tell me to write classes) that can be fitted in most of my projects so well that I just need to copy-paste them and put the whole
    machine together almost like magic.

    I already do a little bit of that. I find myself copying blocks of
    code from one old project to a new one quite often (and my IDE has a very useful "snippets" feature), but there is always the problem of adjusting all the variable names and perhaps even proc arguments and parameters. But I
    often crave something richer than that. I fancy much better building blocks that will help me produce stuff with a lot less effort, on use and reuse.

    Maybe I should pause all the projects (even more so) and spend some
    time focused on writing such blocks? Is that a good idea? Should
    that wheel be reinvented?

    Elders of the Code Church, what is your wisdom?
    --
    Luc


    --- Synchronet 3.20c-Linux NewsLink 1.2
  • From Tim Wallace@tp_wallace@yahoo.com to comp.lang.tcl on Fri Jan 24 19:51:22 2025
    From Newsgroup: comp.lang.tcl

    On 1/24/25 18:34, Luc wrote:
    I am usually so well rewarded for asking questions here so what the hey. Might as well try again.

    I have personal issues. For that reason, my coding habits are spotty
    at best. I don't really abandon my projects. I just postpone them when I
    am not feeling well. But one wouldn't be able to tell the difference. I postpone them for very long periods.

    On top of my personal problems, the long periods of inactivity make
    me very unfamiliar with my own code. Picking up where I left off is
    hard. I have to read everything again and make heads and tails of the
    whole thing and know where to look when the code throws an error.
    It's so bad I sometimes decide to just start over, from scratch.
    The awareness of the wasted effort hurts, but at least I will know
    what I'm doing and where I'm going with the code.

    It's all quite tiresome and discouraging. So I postpone. Again. Again
    and again.

    I like to associate this problem with an old idea of mine: functional programming. I'm sure I've seen that term before but probably with a different meaning. I mean writing blocks of code, likely procs (I know you lot are going to tell me to write classes) that can be fitted in most of my projects so well that I just need to copy-paste them and put the whole machine together almost like magic.

    I already do a little bit of that. I find myself copying blocks of
    code from one old project to a new one quite often (and my IDE has a very useful "snippets" feature), but there is always the problem of adjusting all the variable names and perhaps even proc arguments and parameters. But I often crave something richer than that. I fancy much better building blocks that will help me produce stuff with a lot less effort, on use and reuse.

    Maybe I should pause all the projects (even more so) and spend some
    time focused on writing such blocks? Is that a good idea? Should
    that wheel be reinvented?

    Elders of the Code Church, what is your wisdom?


    Write comments before you write the code--explaining your thinking and
    plans. In grad school I had to write in Fortran and C, and half my
    lines were comment lines (especially in Fortran). Made it easier to go
    back!

    I also wrote it top-down, the main program first and various subroutines
    and functions as needed. Kind of paralleling the thinking.

    --Tim
    --- Synchronet 3.20c-Linux NewsLink 1.2
  • From Rich@rich@example.invalid to comp.lang.tcl on Sat Jan 25 03:59:25 2025
    From Newsgroup: comp.lang.tcl

    Luc <luc@sep.invalid> wrote:
    I already do a little bit of that. I find myself copying blocks of
    code from one old project to a new one quite often (and my IDE has a very useful "snippets" feature),

    That's one form of 'reuse', but:

    but there is always the problem of adjusting all the variable names
    and perhaps even proc arguments and parameters.

    You've discovered the problem with "copy/paste reuse". Adapting the
    copied code to fit into its place in a new batch of code can often be
    more work than rewriting it all over again.

    But I often crave something richer than that. I fancy much better
    building blocks that will help me produce stuff with a lot less
    effort, on use and reuse.

    You are beginning to recognize what are termed "code libraries".
    Usually (but not always) small code chunks for one specific useful
    aspect, that can then be reused in multiple other projects without the
    effort of "rewriting" or of "adjusting variable names and proc
    arguments".

    I.e., Tcllib is a code library. It has tons of useful modules inside.
    To pick a couple out, the 'sha256' module impliments the SHA256 hash
    function [1]. Lets just say you regularly write applications that
    make use of SHA256 hashes. You /could/ copy paste in the long drawn
    out code to perform a SHA256 hash into each one, laboriously changing
    variable names that conflict. Or, you could write a "SHA256 hash
    function module" (i.e., what is now in Tcllib) and then, every time you
    are writing some application that makes use of a sha256 hash, you just
    do:

    package require sha256

    And then use the ready made hash functions that are part of the
    "sha2::*" namespace thaat the module adds to your application. And:

    1) not have to copy/past anything from anywhere;
    2) not have to laboriously edit variable names to avoid name conflicts
    3) not have to adjust proc arguments
    4) etc.

    Maybe I should pause all the projects (even more so) and spend some
    time focused on writing such blocks?

    That's your choice, it is your code and your time to do with as you
    please.

    Is that a good idea?

    In general, if you find you have "chunks" you keep reusing, then
    exerting the effort to make a package/module from the "chunk", with a
    generic enough interface to cover all your needs from the
    package/module, will turn out to return the effort/time ten or a
    hundred fold later. So yes, generally a good idea.

    At the same time, don't go "package/module" happy either (i.e. NPM).
    Exert the effort to make packages or modules for the chunks you *know*
    you are often reusing, as you will more likely reuse them later. But "building a module" from a chunk you are not sure you will reuse
    (unless you know you *really* will reuse it) can become effort wasted,
    because you may not in fact reuse it.

    Should that wheel be reinvented?

    Well, you don't need to 'reinvent'. Tcl already has packges and
    modules, you just need to start package-izing or module-izing your
    blocks you currently reuse.

    Elders of the Code Church, what is your wisdom?

    Reusable code libraries are a good thing. The effort spent to build
    (and define) a generic interface usable for multiple apps. to a block
    of 'reusable code' will pay for itself over the longer term.

    Take a look through the Tcllib source for insights on building reusable packages/modules.



    [1] Don't worry if you don't know what a 'hash function' is right now,
    that's not terribly important for this discussion here, and you can
    look it up on Wikipedia if you don't know but really want to know.

    --- Synchronet 3.20c-Linux NewsLink 1.2
  • From Luc@luc@sep.invalid to comp.lang.tcl on Sat Jan 25 02:37:06 2025
    From Newsgroup: comp.lang.tcl

    On Sat, 25 Jan 2025 03:59:25 -0000 (UTC), Rich wrote:

    [1] Don't worry if you don't know what a 'hash function' is right now, >that's not terribly important for this discussion here, and you can
    look it up on Wikipedia if you don't know but really want to know. **************************

    Hey, I know what a hash function is. I use it all the time to check the integrity of ISO images.

    In fact, I have written - and shared - a Tcl script that uses it:

    set ::hashMethod tcllib
    foreach i {sha512sum sha384sum sha256sum sha224sum sha1sum md5sum} {
    if {[catch {set ::hashMethod [exec which $i]} _catchError]} {
    continue
    } else {break}
    }

    if {$::hashMethod == "tcllib"} {
    if {[catch {package require sha256} _catchError]} {
    puts "ERROR! Impossible to proceed. Please install at least one of these packages: "
    puts "sha512sum, sha384sum, sha256sum, sha224sum, sha1sum, md5sum, or tcllib."
    puts "Note: tcllib is considerably slower than all the others."
    puts ""
    exit
    }
    }

    That was 10 years ago. I wonder if the tcllib implementation has been
    optimized since then.


    Thank you for all the advice.
    --
    Luc


    --- Synchronet 3.20c-Linux NewsLink 1.2
  • From Rich@rich@example.invalid to comp.lang.tcl on Sat Jan 25 17:10:49 2025
    From Newsgroup: comp.lang.tcl

    Luc <luc@sep.invalid> wrote:
    On Sat, 25 Jan 2025 03:59:25 -0000 (UTC), Rich wrote:

    [1] Don't worry if you don't know what a 'hash function' is right now, >>that's not terribly important for this discussion here, and you can
    look it up on Wikipedia if you don't know but really want to know.
    **************************

    Hey, I know what a hash function is. I use it all the time to check the integrity of ISO images.

    I did not know one way or the other -- and what it was was unrelated to
    the topic.


    That was 10 years ago. I wonder if the tcllib implementation has been optimized since then.

    The current Tcllib version includes a compiled C extension that will be
    built if the Tcllib build finds critcl installed and operable at build
    time. That will very much optimize hash computations vs. the other,
    pure Tcl, variant in Tcllib.

    Thank you for all the advice.

    You are welcome. Do note that my comments re. "generic interfaces" is
    a very important bit not to miss sight of. A 'reusable' module is only
    really reusable if you don't have to keep changing the various proc
    arguments for each different use. So spending effort to boil down to
    the widest common denominator for the "API" (i.e., the proc calling
    arguments) will help with the reusability.
    --- Synchronet 3.20c-Linux NewsLink 1.2
  • From Ralf Fassel@ralfixx@gmx.de to comp.lang.tcl on Mon Jan 27 09:30:19 2025
    From Newsgroup: comp.lang.tcl

    * Tim Wallace <tp_wallace@yahoo.com>
    | On 1/24/25 18:34, Luc wrote:
    | > On top of my personal problems, the long periods of inactivity make
    | > me very unfamiliar with my own code. Picking up where I left off is
    | > hard. I have to read everything again and make heads and tails of the
    | > whole thing and know where to look when the code throws an error.
    | > It's so bad I sometimes decide to just start over, from scratch. --<snip-snip>--
    | Write comments before you write the code--explaining your thinking and
    | plans.

    I'd second that advice from Tim.

    In addition:
    - document the side-effects of functions calls (eg changing global
    variables or state, in TCL: variable traces)
    - document the "clever tricks" in detail (eg bit fiddling, relying on
    hidden features, in TCL: variable traces)
    - when changing *code*, check the *comments* as well and adapt them if
    required
    - write unit tests for your building blocks

    HTH
    R'
    --- Synchronet 3.20c-Linux NewsLink 1.2
  • From Luc@luc@sep.invalid to comp.lang.tcl on Mon Jan 27 15:26:59 2025
    From Newsgroup: comp.lang.tcl

    On Mon, 27 Jan 2025 09:30:19 +0100, Ralf Fassel wrote:

    - document the "clever tricks" in detail (eg bit fiddling, relying on
    hidden features, in TCL: variable traces)
    **************************

    What is bit fiddling?
    --
    Luc


    --- Synchronet 3.20c-Linux NewsLink 1.2
  • From Rich@rich@example.invalid to comp.lang.tcl on Mon Jan 27 19:39:08 2025
    From Newsgroup: comp.lang.tcl

    Luc <luc@sep.invalid> wrote:
    On Mon, 27 Jan 2025 09:30:19 +0100, Ralf Fassel wrote:

    - document the "clever tricks" in detail (eg bit fiddling, relying on
    hidden features, in TCL: variable traces)
    **************************

    What is bit fiddling?

    Doing things like:

    set y [expr {$x << 2}]

    To multiply by four the integer in $x.

    Operations that operate on the underlying binary representation of the
    value.

    --- Synchronet 3.20c-Linux NewsLink 1.2